From 1c1d561f3ab3752597161a32c42ac846ae47ffe7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Luc=20=E2=99=A5?= Date: Thu, 12 Nov 2026 17:42:57 +0100 Subject: [PATCH 01/27] New translations en.json (Romanian) [ci skip] --- messages/ro.json | 1055 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 1055 insertions(+) create mode 100644 messages/ro.json diff --git a/messages/ro.json b/messages/ro.json new file mode 100644 index 00000000..ef4df56c --- /dev/null +++ b/messages/ro.json @@ -0,0 +1,1055 @@ +{ + "landing_tagline": "The go-to platform for safe, reliable, real low-latency remote shocking.", + "landing_section_label": "Home", + "landing_hubs_online": "Hubs online right now: ", + "landing_learn_more": "Learn More", + "landing_wiki": "Wiki", + "landing_meta_description": "Welcome to OpenShock, a free and open-source ecosystem to control various shock collars over the internet.", + "instance_meta_description": "Welcome to {{siteName}}, an independent instance of OpenShock, a free and open-source ecosystem to control various shock collars over the internet.", + "header_sidebar_toggle": "Toggle Sidebar", + "header_avatar_alt": "{{name}}'s avatar", + "header_menu_profile": "Profile", + "header_menu_settings": "Settings", + "header_menu_logout": "Logout", + "header_login": "Login", + "header_signup": "Sign Up", + "header_github_title": "OpenShock on GitHub", + "header_discord_title": "Community Discord", + "footer_made_with": "Made with by the OpenShock Team", + "footer_connection_status_label": "Server connection status", + "footer_signalr_state": "SignalR State", + "footer_frontend_version": "Frontend Version", + "footer_frontend_commit_title": "Commit {{commit}}", + "footer_backend_version": "Backend Version", + "footer_backend_commit_title": "Commit {{commit}}", + "footer_language_label": "Language", + "sidebar_home_link_label": "OpenShock home", + "sidebar_group_general": "General", + "sidebar_home": "Home", + "sidebar_shockers": "Shockers", + "sidebar_shared_shockers": "Shared Shockers", + "sidebar_hubs": "Hubs", + "sidebar_user_shares": "User Shares", + "sidebar_public_shares": "Public Shares", + "sidebar_serial_terminal": "Serial Terminal", + "sidebar_group_admin": "Admin", + "sidebar_admin_monitoring": "Monitoring", + "sidebar_admin_online_hubs": "Online Hubs", + "sidebar_admin_online_gateways": "Online Gateways", + "sidebar_admin_management": "Management", + "sidebar_admin_users": "Users", + "sidebar_admin_blacklists": "Blacklists", + "sidebar_admin_webhooks": "Webhooks", + "sidebar_admin_mail": "Mail", + "sidebar_admin_automation_tokens": "Automation Tokens", + "sidebar_admin_configuration": "Configuration", + "sidebar_group_settings": "Settings", + "sidebar_settings_api_tokens": "API Tokens", + "sidebar_settings_sessions": "Sessions", + "sidebar_settings_audit_log": "Audit Log", + "sidebar_settings_connections": "Connections", + "sidebar_settings_account": "Account Settings", + "error_meta_title": "Service Unavailable", + "error_meta_description": "OpenShock is currently unavailable", + "error_meta_logo_alt": "OpenShock Logo", + "error_fallback_message": "Something went wrong.", + "error_not_found_message": "Page not found", + "error_not_found_description": "The page you're looking for doesn't exist.", + "error_unexpected_description": "An unexpected error occurred.", + "error_go_back": "Go back", + "auth_layout_logo_alt": "OpenShock Logo", + "auth_layout_invalid_redirect_removed": "An invalid redirect URL was removed for your safety.", + "auth_activate_breadcrumb": "Activate Account", + "auth_activate_title": "Activate Account", + "auth_activate_activating": "Activating your account...", + "auth_activate_success": "Your account has been activated", + "auth_activate_failed": "This activation link is invalid or has expired", + "auth_activate_missing_token": "Missing activation token", + "auth_activate_continue": "Continue to login", + "auth_activate_toast_success": "Account activated", + "auth_forgot_breadcrumb": "Forgot Password", + "auth_forgot_title": "Forgot Password", + "auth_forgot_description": "Enter your email to reset your password", + "auth_forgot_email_label": "Email", + "auth_forgot_email_placeholder": "Email", + "auth_forgot_submit": "Reset Password", + "auth_forgot_signin_prompt": "Remember your password? Sign in", + "auth_forgot_mail_disabled": "Password resets are unavailable on this instance because it has no mail provider configured. Please contact your administrator for help recovering your account.", + "auth_forgot_toast_sent": "Reset password request has been sent to the given email", + "auth_login_breadcrumb": "Login", + "auth_login_title": "Welcome back", + "auth_login_loading_methods": "Loading available login methods", + "auth_login_choose_method": "Login with one of these methods", + "auth_login_with_account": "Login with your OpenShock Account", + "auth_login_activation_after_signup": "Your account has been created. We've sent an activation link to your email address. Check your inbox and spam folder.", + "auth_login_activation_pending": "Your account isn't activated yet. We've sent an activation link to your email address. Check your inbox and spam folder. If nothing arrives, try logging in again later to get a new link.", + "auth_login_oauth_only": "This account has no password. Sign in with the provider you signed up with.", + "auth_login_oauth_only_with_buttons": "This account has no password. Sign in with the provider you signed up with using the buttons above.", + "auth_login_or_continue_with": "Or continue with", + "auth_login_username_label": "Username or Email", + "auth_login_password_label": "Password", + "auth_login_submit": "Login", + "auth_login_signup_prompt": "Don't have an account? Sign up", + "auth_login_legal": "By clicking Login, you agree to our Terms of Service and Privacy Policy.", + "auth_oauth_create_breadcrumb": "Sign Up With {{provider}}", + "auth_oauth_create_title": "Sign Up With {{provider}}", + "auth_oauth_create_description": "Complete your account details", + "auth_oauth_create_username_label": "Username", + "auth_oauth_create_username_placeholder": "Username", + "auth_oauth_create_email_label": "Email", + "auth_oauth_create_email_placeholder": "Email", + "auth_oauth_create_submit": "Sign Up", + "auth_oauth_create_legal": "By clicking Sign Up, you agree to our Terms of Service and Privacy Policy.", + "auth_oauth_error_breadcrumb": "Authentication Error", + "auth_oauth_error_title": "Authentication Error", + "auth_oauth_error_back": "Back to login", + "auth_reset_breadcrumb": "Reset Password", + "auth_reset_title": "Reset Password", + "auth_reset_checking": "Verifying reset link...", + "auth_reset_choose_password": "Choose a new password for your account", + "auth_reset_invalid": "This reset link is invalid or has expired", + "auth_reset_password_label": "New Password", + "auth_reset_password_placeholder": "New Password", + "auth_reset_confirm_label": "Confirm New Password", + "auth_reset_confirm_placeholder": "Confirm New Password", + "auth_reset_submit": "Reset Password", + "auth_reset_request_new": "Request a new reset link", + "auth_reset_toast_success": "Password has been reset", + "auth_signup_breadcrumb": "Sign Up", + "auth_signup_toast_created_mail": "Account created successfully. Please check your email to verify your account.", + "auth_signup_toast_created_no_mail": "Account created successfully. You can log in now.", + "auth_signup_dialog_title": "Welcome! Thank you for signing up! ❤️", + "auth_signup_dialog_created_mail": "Your account has been created. 🎉 Please check your email to verify your account.", + "auth_signup_dialog_verify_then_login": "After verifying your email, you can log in to your account.", + "auth_signup_dialog_created_no_mail": "Your account has been created and is ready to use. 🎉", + "auth_signup_dialog_login_now": "You can log in to your account now.", + "auth_signup_title": "Create your account", + "auth_signup_loading_methods": "Loading available sign-up methods", + "auth_signup_using_email": "Signing up using email", + "auth_signup_choose_method": "Choose your preferred sign-up method", + "auth_signup_back": "Back", + "auth_signup_username_label": "Username", + "auth_signup_username_placeholder": "John OpenShock", + "auth_signup_email_label": "Email", + "auth_signup_email_placeholder": "john@example.com", + "auth_signup_password_label": "Password", + "auth_signup_password_placeholder": "Password", + "auth_signup_confirm_label": "Confirm Password", + "auth_signup_confirm_placeholder": "Confirm Password", + "auth_signup_submit": "Create Account", + "auth_signup_signin_prompt": "Already have an account? Sign in", + "auth_signup_or": "Or", + "auth_signup_with_email": "Signup with Email", + "auth_signup_legal": "By clicking Create Account, you agree to our Terms of Service and Privacy Policy.", + "auth_verify_breadcrumb": "Verify Email", + "auth_verify_title": "Verify Email", + "auth_verify_verifying": "Verifying your email address...", + "auth_verify_success": "Your email has been verified", + "auth_verify_failed": "This verification link is invalid or has expired", + "auth_verify_missing_token": "Missing verification token", + "auth_verify_continue": "Continue to login", + "auth_verify_toast_success": "Email verified", + "common_cancel": "Cancel", + "common_delete": "Delete", + "common_edit": "Edit", + "common_share": "Share", + "common_copy_id": "Copy ID", + "common_id_copied": "ID copied to clipboard", + "common_open_menu": "Open menu", + "common_refresh": "Refresh", + "common_settings": "Settings", + "common_clear": "Clear", + "common_online": "Online", + "common_offline": "Offline", + "common_paused": "Paused", + "common_resume": "Resume", + "common_resuming": "Resuming...", + "common_coming_soon": "(Coming soon)", + "common_save_changes": "Save Changes", + "common_danger_zone": "Danger Zone", + "common_name": "Name", + "control_intensity": "Intensity", + "control_duration": "Duration", + "control_max_intensity": "Max Intensity", + "control_max_duration": "Max Duration", + "control_vibration": "Vibration", + "control_value": "Value", + "control_live_intensity": "Live intensity", + "control_type_stop": "Stop", + "control_type_shock": "Shock", + "control_type_vibrate": "Vibrate", + "control_type_sound": "Sound", + "live_tooltip_active": "Live via {{gateway}} ({{country}}), {{latency}}ms", + "live_tooltip_connecting": "Connecting...", + "live_tooltip_connect": "Connect to Live Control", + "live_tooltip_hub_start": "Ctrl+click to start the whole hub", + "live_tooltip_hub_stop": "Ctrl+click to stop the whole hub", + "pause_resume_shocker": "Resume shocker", + "pause_pause_shocker": "Pause shocker", + "pause_resume_all": "Resume all shockers", + "pause_pause_all": "Pause all shockers", + "shocker_label": "Shocker", + "shocker_hub": "Hub", + "shocker_select_hub": "Select hub", + "shocker_rf_id": "RF ID", + "shocker_rf_id_invalid": "RF ID must be a whole number between {{min}} and {{max}}.", + "shocker_model": "Model", + "shocker_select_model": "Select model", + "shocker_name_placeholder": "Shocker name", + "shocker_menu_view_logs": "View Logs", + "shocker_delete_title": "Delete Shocker", + "shocker_delete_desc": "Are you sure you want to delete \"{{name}}\"? This action cannot be undone.", + "shocker_toast_deleted": "Shocker \"{{name}}\" deleted", + "shocker_toast_paused": "Shocker paused", + "shocker_toast_resumed": "Shocker resumed", + "shocker_add_desc": "Register a new shocker to one of your hubs.", + "shocker_add_name_placeholder": "My Shocker", + "shockers_title": "Shockers", + "shockers_subtitle": "Every shocker paired to your hubs.", + "shockers_loading": "Loading shockers...", + "shockers_toast_refreshed": "Shockers refreshed", + "shockers_toast_need_hub": "You need to create a hub before adding shockers.", + "shockers_toast_added": "Shocker added", + "shockers_unknown_module": "Unknown module type", + "shockers_add": "Add Shocker", + "shockers_view_mode": "View mode", + "shockers_mode_classic": "Classic", + "shockers_mode_rich": "Rich", + "shockers_mode_simple": "Simple", + "shockers_mode_map": "Map", + "shockers_group_by_hub": "Group by Hub", + "shockers_global_limits": "Global Limits", + "shockers_logs_label": "Logs", + "shockers_empty_title": "No shockers yet", + "shockers_empty_no_hubs": "Create a hub first, then add shockers to it.", + "shockers_empty_has_hubs": "Add a shocker to one of your hubs to get started.", + "shockers_create_hub": "Create a Hub", + "shockers_count_one": "{{count}} shocker", + "shockers_count_other": "{{count}} shockers", + "shared_shockers_title": "Shared Shockers", + "shared_shockers_subtitle": "Shockers other users have shared with you.", + "shared_shockers_empty_title": "No shockers have been shared with you yet.", + "shared_shockers_empty_desc": "When someone shares their shockers with you, they'll appear here.", + "shocker_logs_title": "Shocker Logs", + "shocker_logs_subtitle": "Every control command sent to your shockers.", + "shocker_logs_live_title": "New logs appear in real time", + "shocker_logs_paused_title": "Live updates pause when sorting or viewing a page other than the first", + "shocker_logs_live": "Live", + "shocker_logs_col_time": "Time", + "shocker_logs_col_type": "Type", + "shocker_logs_col_by": "By", + "shocker_logs_filter_label": "Filter by shocker", + "shocker_logs_filter_placeholder": "Search shockers...", + "shocker_logs_filter_all": "All shockers", + "shocker_logs_filter_none": "No matching shockers", + "shocker_edit_title": "Edit Shocker", + "shocker_edit_subtitle": "Change this shocker's details or remove it.", + "shocker_edit_back": "Back to Shockers", + "shocker_edit_load_failed": "Failed to load shocker.", + "shocker_edit_loading": "Loading shocker...", + "shocker_edit_details_title": "Shocker Details", + "shocker_edit_details_desc": "Update the name, RF ID, and model for this shocker.", + "shocker_edit_pause_state": "Pause State", + "shocker_edit_is_paused": "Shocker is paused", + "shocker_edit_is_active": "Shocker is active", + "shocker_edit_toast_updated": "Shocker updated", + "shocker_edit_delete_desc": "Permanently delete this shocker. This action cannot be undone.", + "common_close": "Close", + "common_continue": "Continue", + "common_loading": "Loading...", + "common_previous": "Previous", + "common_next": "Next", + "common_steps": "Steps", + "common_step_label": "Step {{number}}: {{title}}", + "common_copy": "Copy", + "common_copied": "Copied", + "common_never": "Never", + "common_error": "Error: {{message}}", + "terminal_title": "Serial Terminal", + "terminal_connecting": "Connecting...", + "terminal_help_button": "I'm having trouble, help?", + "terminal_back_to_modes": "Back to mode picker", + "terminal_mode_configure": "Configure Device", + "terminal_mode_configure_desc": "Configure WiFi, authentication, and more. Includes an interactive serial console.", + "terminal_mode_flash": "Flash Firmware", + "terminal_mode_flash_desc": "Install or update firmware on a connected device.", + "terminal_mode_raw": "Serial Monitor", + "terminal_mode_raw_desc": "Just the console. Read device logs and send commands.", + "terminal_step_channel": "Select Channel", + "terminal_step_board": "Select Board", + "terminal_go_to_step": "Go to step {{number}}: {{title}}", + "terminal_erase": "Erase before flashing", + "terminal_erase_desc": "Clears all data on the device including existing configs", + "terminal_unsupported": "Your browser does not support this feature.", + "terminal_update_browser": "Please update your browser to the latest version.", + "terminal_use_browsers": "Please use one of the following browsers:", + "terminal_connect_failed_bootloader": "Could not enter bootloader mode", + "terminal_connect_failed": "Device connection failed", + "terminal_connect_failed_desc": "We couldn't establish a serial connection with the device.", + "terminal_quick_tries": "Quick things to try:", + "terminal_try_replug": "Unplug and replug the device.", + "terminal_try_cable": "Try a different USB cable or port.", + "terminal_try_driver": "Make sure the serial driver is installed.", + "terminal_open_troubleshooter": "Open troubleshooter", + "terminal_log_reset_no_device": "Host-side error during reset: no device!", + "terminal_log_reset_error": "Host-side error during reset: {{error}}", + "terminal_log_send_no_device": "Couldn't send: no device!", + "terminal_log_send_error": "Couldn't send: {{error}}", + "terminal_log_firmware_disconnected": "Firmware disconnected: {{error}}", + "terminal_log_erase_failed": "Failed to erase flash: {{error}}", + "terminal_log_hard_reset_failed": "Failed to hard reset: {{error}}", + "terminal_log_flash_complete": "Flash complete", + "terminal_log_flash_failed": "Failed to flash: {{error}}", + "terminal_log_command_failed": "Failed to write application command: {{error}}", + "terminal_help_title": "Troubleshooter", + "terminal_help_desc": "Work through these steps in order. Each one rules out a common cause.", + "terminal_help_step_cable": "USB cable", + "terminal_help_step_port": "USB port", + "terminal_help_step_driver": "Install driver", + "terminal_help_step_manual": "Manual driver update", + "terminal_help_step_discord": "Ask on Discord", + "terminal_help_cable_body": "Many USB-C and micro-USB cables are charge-only and don't carry data. Swap to a known-good data cable (one you've used to transfer files or connect other devices) and reconnect the hub.", + "terminal_help_port_body": "Plug the device directly into a USB port on your computer. Avoid USB hubs, docking stations, and front-panel ports if possible; these are common sources of power and signal issues. If you're on a desktop, try a port on the back of the machine.", + "terminal_help_driver_download": "Download the CP210x driver:", + "terminal_help_driver_extract": "Extract the contents of the zip file to a folder on your computer.", + "terminal_help_driver_run": "Open the folder and run {{installer}}. Follow the prompts to install.", + "terminal_help_driver_reconnect": "Reconnect the device.", + "terminal_help_manual_intro": "If the driver installer ran but the device still doesn't show up:", + "terminal_help_manual_open": "Open Device Manager (press Win + X and select Device Manager).", + "terminal_help_manual_ports": "Under Ports (COM & LPT), look for an entry like:", + "terminal_help_manual_missing": "If it's missing, the device isn't being detected by Windows at all; revisit the cable and port steps.", + "terminal_help_manual_update": "Right-click the device and pick Update Driver.", + "terminal_help_manual_browse": "Choose Browse my computer for drivers and select the folder you extracted the driver zip into. Make sure Include subfolders is checked.", + "terminal_help_manual_success": "On success, the entry should now read {{deviceName}}.", + "terminal_help_discord_intro": "Still stuck after all of the above? Hop into our Discord server and ask in the {{channel}} channel. Please include:", + "terminal_help_discord_os": "your operating system and browser", + "terminal_help_discord_device": "the device you're using (board model, where you got it)", + "terminal_help_discord_tried": "what you've already tried from the previous steps", + "terminal_help_discord_errors": "any error messages or relevant terminal output", + "terminal_help_discord_join": "Join our Discord server", + "terminal_risk_title": "⚠️ UNSTABLE FIRMWARE", + "terminal_risk_intro": "You are about to flash experimental firmware that is known to be unstable.", + "terminal_risk_brick": "This may permanently brick your device, require manual recovery, or render it unusable.", + "terminal_risk_no_support": "We will NOT provide support for issues caused by this firmware.", + "terminal_risk_acknowledge": "I understand this is entirely my responsibility", + "terminal_risk_abort": "Abort", + "terminal_risk_accept": "I ACCEPT FULL RESPONSIBILITY", + "firmware_channel_recommended": "This is the recommended channel.", + "firmware_channel_danger": "DO NOT USE THIS UNLESS YOU KNOW WHAT YOU ARE DOING", + "firmware_channel_stable": "Stable", + "firmware_channel_beta": "Beta", + "firmware_channel_develop": "Develop", + "terminal_board_select": "Select a board...", + "terminal_board_search": "Search boards...", + "terminal_board_none": "No board found.", + "terminal_flash_button": "Flash", + "terminal_flash_progress": "Flash Progress: {{status}}", + "terminal_flash_idle": "Idle", + "terminal_flash_no_device": "No device selected.", + "terminal_flash_resetting": "Resetting...", + "terminal_flash_downloading": "Downloading firmware...", + "terminal_flash_download_failed": "Failed to download firmware.", + "terminal_flash_flashing": "Flashing firmware...", + "terminal_flash_rebooting": "Rebooting device... (Reconnect to power manually if stuck)", + "terminal_flash_done": "Rebooted device! Flashing complete.", + "terminal_port_select": "Select Device", + "terminal_port_disconnect": "Disconnect Device", + "terminal_port_connected": "Device connected: {{id}}", + "terminal_console": "Console", + "terminal_connected_device": "Connected device", + "terminal_resize": "Resize terminal panel", + "terminal_reboot": "Reboot", + "terminal_disconnect": "Disconnect", + "terminal_fullscreen_exit_esc": "Exit fullscreen (Esc)", + "terminal_fullscreen_exit": "Exit fullscreen", + "terminal_fullscreen_fill": "Fill the window", + "terminal_command_label": "Serial command", + "terminal_command_placeholder": "Type a command...", + "terminal_command_send": "Send command", + "terminal_colors": "Colors", + "terminal_colors_menu": "Colors...", + "terminal_colors_label": "Console colors", + "terminal_colors_close": "Close colors", + "terminal_color_input": "{{name}} color", + "terminal_colors_reset": "Reset to defaults", + "terminal_color_bg": "Background", + "terminal_color_fg": "Text", + "terminal_color_ts": "Timestamp", + "terminal_color_error": "Error", + "terminal_color_warning": "Warning", + "terminal_color_info": "Info", + "terminal_color_debug": "Debug", + "terminal_color_verbose": "Verbose", + "terminal_options": "Options", + "terminal_options_label": "Console options", + "terminal_hide_system": "Hide system messages", + "terminal_stick_bottom": "Stick to bottom", + "terminal_raw_output": "Raw output", + "terminal_timestamps": "Timestamps", + "terminal_timestamp_uptime": "Uptime", + "terminal_timestamp_local": "Local", + "terminal_timestamp_ms": "Ms", + "terminal_timestamp_off": "Off", + "terminal_copy_settings": "Copy settings", + "terminal_import_settings": "Import settings", + "terminal_copy_selection": "Copy selection", + "terminal_copy_all": "Copy all output", + "terminal_toast_selection_copied": "Selection copied", + "terminal_toast_output_copied": "Console output copied", + "terminal_toast_settings_copied": "Console settings copied", + "terminal_toast_clipboard_unreadable": "Could not read the clipboard", + "terminal_toast_settings_imported": "Console settings imported", + "terminal_toast_settings_invalid": "Clipboard does not contain console settings", + "common_try_again": "Try again", + "terminal_cfg_intro": "Values are sent to the device via UART. Read the device's response in the console below. Commands without an argument act as getters; use the button next to each field to read the current value.", + "terminal_cfg_rf_title": "RF Transmitter", + "terminal_cfg_rf_desc": "Controls the shocker RF output.", + "terminal_cfg_tx_pin": "TX GPIO pin", + "terminal_cfg_example": "e.g. {{value}}", + "terminal_cfg_read_value": "Read current value", + "terminal_cfg_set": "Set", + "terminal_cfg_read": "Read", + "terminal_cfg_reading": "Reading…", + "terminal_cfg_apply": "Apply", + "terminal_cfg_keepalive": "Keepalive enabled", + "terminal_cfg_keepalive_desc": "Periodically pings paired shockers to keep them awake.", + "terminal_cfg_estop_title": "Emergency Stop", + "terminal_cfg_estop_desc": "Hardware button that halts all output.", + "terminal_cfg_estop_enabled": "EStop enabled", + "terminal_cfg_estop_pin": "EStop GPIO pin", + "terminal_cfg_estop_note": "Note: {{latching}} and {{active}} have no dedicated commands; set them via the JSON config below.", + "terminal_cfg_wifi_title": "WiFi", + "terminal_cfg_wifi_desc": "Station credentials and device hostname.", + "terminal_cfg_hostname": "Hostname", + "terminal_cfg_networks": "Networks (JSON array)", + "terminal_cfg_invalid_json_array": "Must be a valid JSON array", + "terminal_cfg_ap_note": "AP settings ({{ssid}}, {{password}}, {{disabled}}, {{staDisabled}}, {{offlineMode}}) have no dedicated commands; use the JSON config.", + "terminal_cfg_backend_title": "Backend", + "terminal_cfg_backend_desc": "OpenShock server and authentication.", + "terminal_cfg_domain": "Domain", + "terminal_cfg_domain_restart": "Setting the domain will restart the device.", + "terminal_cfg_auth_token": "Auth token", + "terminal_cfg_auth_token_placeholder": "Paste device token", + "terminal_cfg_hide": "Hide", + "terminal_cfg_show": "Show", + "terminal_cfg_serial_title": "Serial Input", + "terminal_cfg_echo": "Echo enabled", + "terminal_cfg_echo_desc": "Print typed characters back to the console.", + "terminal_cfg_advanced_title": "Advanced: full config", + "terminal_cfg_advanced_desc": "For fields without dedicated commands (captive portal, OTA, LAN, etc.), replace the entire config.", + "terminal_cfg_json_config": "JSON config", + "terminal_cfg_invalid_json": "Must be valid JSON", + "terminal_cfg_read_json": "Read current config as JSON", + "terminal_cfg_json_restart": "Applying a JSON config will restart the device.", + "terminal_cfg_raw_config": "Raw FlatBuffer config (base64)", + "terminal_cfg_invalid_base64": "Must be a valid base64 string", + "terminal_cfg_read_raw": "Read current config as base64", + "terminal_cfg_factory_reset": "Factory reset", + "terminal_cfg_factory_reset_desc": "Wipes the entire device configuration.", + "terminal_cfg_factory_reset_title": "Factory reset device?", + "terminal_cfg_factory_reset_action": "Wipe config", + "terminal_cfg_factory_reset_confirm": "This will erase all configuration on the device; WiFi networks, backend credentials, pins, and all other settings. The device will be reset to defaults.", + "terminal_cfg_read_failed_json_title": "Couldn't read the JSON config", + "terminal_cfg_read_failed_raw_title": "Couldn't read the raw config", + "terminal_cfg_read_failed_desc": "The device didn't respond after {{attempts}} attempts.", + "terminal_cfg_common_causes": "Common causes:", + "terminal_cfg_cause_busy": "The device is busy handling another command.", + "terminal_cfg_cause_disconnected": "The device disconnected or rebooted.", + "terminal_cfg_cause_unsupported": "The firmware version doesn't support this command.", + "common_status": "Status", + "common_version": "Version", + "common_created": "Created", + "common_create": "Create", + "common_done": "Done", + "common_enable": "Enable", + "common_disable": "Disable", + "common_are_you_sure": "Are you sure?", + "common_generating": "Generating...", + "hubs_title": "Hubs", + "hubs_subtitle": "Every hub registered to your account.", + "hubs_add": "Add Hub", + "hubs_load_failed": "Failed to load hubs.", + "hubs_empty_title": "No hubs yet", + "hubs_empty_desc": "A hub is the device that relays commands to your shockers. Add one to get started.", + "hubs_create_title": "Create hub", + "hubs_name_label": "Hub Name", + "hubs_name_placeholder": "My Hub", + "hub_toast_not_connected": "Not connected to the server", + "hub_toast_try_later": "Try again in a moment.", + "hub_reboot_title": "Reboot {{name}}?", + "hub_reboot_desc": "The hub will disconnect and restart. Any shockers paired to it stop responding until it comes back online.", + "hub_reboot": "Reboot", + "hub_hotspot_enable_title": "Enable Wi-Fi hotspot on {{name}}?", + "hub_hotspot_disable_title": "Disable Wi-Fi hotspot on {{name}}?", + "hub_hotspot_enable_desc": "The hub broadcasts its own setup network. It stays reachable on your Wi-Fi, but the hotspot is open to anyone in range until you turn it off.", + "hub_hotspot_disable_desc": "The setup hotspot shuts down. If the hub is not already on your Wi-Fi you will need physical access to set it up again.", + "hub_delete_desc": "You are about to delete hub {{name}}.", + "hub_delete_shockers": "This will also delete the following shockers:", + "hub_edit_title": "Edit hub", + "hub_edit_apply": "Apply", + "hub_pair_title_generate": "Generate pair code?", + "hub_pair_title_generated": "Pair code generated", + "hub_pair_title_paired": "Hub paired", + "hub_pair_consumed": "{{name}} consumed this pair code and is now paired.", + "hub_pair_used": "The code has been used and is no longer valid.", + "hub_pair_generated_for": "Pair code generated for {{name}}.", + "hub_copy_now": "The code below will not be accessible later, please copy it now and update clients with it.", + "hub_pair_generate_for": "You are about to generate a pair code for {{name}}.", + "hub_pair_valid_for": "It will be valid for 15 minutes after its creation.", + "hub_pair_one_active": "There is only one active pair code per hub, newly generated ones will override the older active ones.", + "hub_pair_complete": "Pairing complete", + "hub_pair_code_label": "Pair code:", + "hub_pair_copied_close": "Code has been copied, close", + "hub_pair_get": "Get Pair Code", + "hub_token_generated": "Token generated", + "hub_token_generated_for": "New token generated for {{name}}.", + "hub_token_regenerate_for": "You are about to regenerate the token for {{name}}.", + "hub_token_invalidate": "This action will invalidate the current token and disconnect clients using it.", + "hub_token_confirm": "Are you sure you want to do this?", + "hub_token_label": "New token:", + "hub_token_copied_close": "Token has been copied, close", + "hub_token_regenerate": "Regenerate Token", + "hub_menu_update": "Update", + "hub_menu_label": "Hub", + "hub_menu_hotspot_enable": "Enable Wi-Fi hotspot", + "hub_menu_hotspot_disable": "Disable Wi-Fi hotspot", + "hub_menu_pair": "Pair", + "hub_menu_estop": "Emergency Stop", + "hub_update_breadcrumb": "Update", + "hub_update_unknown_hub": "Unknown Hub", + "hub_update_unknown_task": "Unknown Task", + "hub_update_task_metadata": "Fetching Metadata", + "hub_update_task_preparing": "Preparing for Update", + "hub_update_task_flash_fs": "Flashing Filesystem", + "hub_update_task_verify_fs": "Verifying Filesystem", + "hub_update_task_flash_app": "Flashing Application", + "hub_update_task_bootable": "Marking Application Bootable", + "hub_update_task_rebooting": "Rebooting", + "hub_update_status_started": "Started", + "hub_update_status_running": "Running", + "hub_update_status_finished": "Finished", + "hub_update_status_error": "Error", + "hub_update_status_timeout": "Timeout", + "hub_update_confirm_title": "Confirm firmware update", + "hub_update_confirm_desc": "Update {{name}} to version {{version}}?", + "hub_update_unstable_warning": "This version may not be from the stable channel and could contain bugs.", + "hub_update_title": "Update {{name}}", + "hub_update_subtitle": "Manage firmware updates for this hub.", + "hub_update_status_title": "Hub Status", + "hub_update_firmware": "Firmware: {{version}}", + "hub_update_confirm": "Update", + "hub_update_success": "Update completed successfully", + "hub_update_rolled_back": "Device rolled back to previous version", + "hub_update_back": "Back to Hubs", + "hub_update_flash_again": "Flash Again", + "hub_update_card_title": "Firmware Update", + "hub_update_card_desc": "Select a firmware channel and version to install.", + "hub_update_to": "Update to {{version}}", + "hub_update_must_be_online": "Hub must be online to start an update.", + "hub_update_updating_to": "Updating to {{version}}...", + "hub_update_total": "Total", + "hub_update_task": "Task", + "hub_update_history": "Update History", + "hub_update_no_history": "No update history found for this hub.", + "hub_update_col_id": "ID", + "hub_update_col_started": "Started", + "hub_update_col_message": "Message", + "hub_update_loading": "Loading hub information...", + "hub_update_not_found": "Hub not found.", + "home_breadcrumb": "Home", + "home_welcome": "Welcome back", + "home_welcome_name": "Welcome back, {{name}}", + "home_subtitle": "Here's an overview of your OpenShock setup.", + "home_hubs_online": "{{count}} online", + "home_hub_status": "Hub Status", + "home_no_hubs": "No hubs", + "home_all_online": "All online", + "home_all_offline": "All offline", + "home_some_online": "{{online}}/{{total}} online", + "home_quick_links": "Quick Links", + "home_my_shockers": "My Shockers", + "home_my_shockers_desc": "Control your shockers", + "home_hubs_desc": "Manage your hubs", + "home_shared_desc": "Shockers shared with you", + "home_public_desc": "Manage share links", + "home_get_started": "Get Started", + "home_get_started_desc": "You don't have any hubs yet. Create a hub to connect your first device, then add shockers to it.", + "home_set_up_hub": "Set Up a Hub", + "home_first_shocker": "Add Your First Shocker", + "home_first_shocker_desc_one": "You have {{count}} hub set up. Add a shocker to start controlling it.", + "home_first_shocker_desc_other": "You have {{count}} hubs set up. Add a shocker to start controlling it.", + "home_go_to_shockers": "Go to Shockers", + "profile_title": "Profile", + "profile_coming_soon": "Profile is coming soon", + "profile_coming_soon_desc": "Your public profile is not available yet. Account details live under Settings.", + "common_retry": "Retry", + "common_never_used": "Never used", + "common_expires": "Expires {{time}}", + "common_search_placeholder": "Search...", + "common_unknown": "Unknown", + "settings_breadcrumb_account": "Account", + "account_subtitle": "Your sign-in details and account actions.", + "account_change_username": "Change Username", + "account_change_email": "Change Email", + "account_change_password": "Change Password", + "account_username_label": "Username", + "account_email_label": "Email", + "account_password_label": "Password", + "account_new_password_label": "New Password", + "account_confirm_password_label": "Confirm New Password", + "account_oauth_only": "Not available for OAuth-only accounts", + "account_oauth_no_password": "This account signs in via OAuth and has no password.", + "account_diagnostics": "Diagnostics", + "account_diagnostics_desc": "Help us fix crashes and slow API calls. Reports include the error message, stack trace and your IP. Off by default.", + "account_diagnostics_level": "Diagnostics level", + "account_telemetry_off": "Off", + "account_telemetry_off_desc": "Send nothing.", + "account_telemetry_errors": "Errors", + "account_telemetry_errors_desc": "Send browser error reports only.", + "account_telemetry_full": "Full", + "account_telemetry_full_desc": "Error reports plus traces of API calls (no page navigations).", + "account_toast_deactivated": "Account deactivated successfully", + "account_deactivate_title": "Deactivate account", + "account_deactivate_desc": "Are you sure you want to deactivate your account?", + "account_deactivate": "Deactivate Account", + "account_email_title": "Change email", + "account_email_desc": "Enter your new email address and confirm with your current password.", + "account_email_toast_sent": "Verification email sent to {{email}}. Click the link in that email to apply the change.", + "account_new_email": "New Email", + "account_current_password": "Current Password", + "account_password_title": "Change password", + "account_password_desc": "Enter your current password and choose a new one.", + "account_password_toast": "Password has been changed", + "account_username_title": "Change username", + "account_username_desc": "Enter a new username.", + "account_new_username": "New Username", + "account_username_toast": "Username changed successfully", + "tokens_subtitle": "API Tokens are used to authenticate with the OpenShock API.", + "tokens_generate": "Generate Token", + "tokens_toast_refreshed": "Tokens refreshed successfully", + "tokens_empty_title": "No API tokens", + "tokens_empty_desc": "Generate a token to authenticate with the OpenShock API.", + "tokens_created_on": "Created {{date}}", + "tokens_last_used": "Last used {{time}}", + "tokens_never_expires": "Never expires", + "tokens_load_failed": "Failed to load API tokens.", + "token_toast_edited": "Token edited successfully", + "token_name_required": "Name is required", + "token_name_too_long": "Name is too long", + "token_edit_title": "Edit API token", + "token_name_label": "Token Name", + "token_name_placeholder": "Token name...", + "token_permissions": "Permissions", + "token_perm_category_shockers": "Shockers", + "token_perm_category_devices": "Hubs", + "token_perm_category_usershares": "User Shares", + "token_perm_category_publicshares": "Public Shares", + "token_perm_use": "Use", + "token_perm_edit": "Edit", + "token_perm_pause": "Pause", + "token_perm_auth": "Authenticate", + "token_shocker_control": "Shocker Control", + "token_toast_paused": "Token paused", + "token_toast_resumed": "Token resumed", + "token_delete_title": "Delete API token", + "token_delete_desc": "Are you sure you want to delete {{name}}?", + "token_delete_permanent": "This action cannot be undone. This will permanently delete the token.", + "token_toast_deleted": "Token deleted successfully", + "token_resume": "Resume token", + "token_pause": "Pause token", + "token_mode_clamp_desc": "Clamp: requests outside the allowed range are capped to the nearest limit (the min or the max).", + "token_mode_lerp_desc": "Lerp: the full input range is linearly rescaled so it fits within your allowed min–max range.", + "token_paused_desc": "A paused token may not send shocker control messages.", + "token_intensity_range": "Intensity range", + "token_duration_range": "Duration range", + "token_new_breadcrumb": "New", + "token_redirect_not_allowed": "The provided redirect_uri is not allowed. Only loopback addresses or custom application schemes are permitted.", + "token_params_missing": "Required get parameters are missing. Make sure name, redirect_uri, and permissions are provided.", + "token_invalid_permissions": "Invalid permissions provided: {{list}}", + "token_toast_created": "Token created successfully", + "token_request_title": "API Token Request", + "token_access_granted": "Access granted", + "token_shared_redirecting": "The token has been created and shared with the application. Redirecting you back to {{uri}}.", + "token_not_redirected": "If you are not redirected automatically, use the button below.", + "token_finish": "Finish", + "token_generated_title": "API Token Generated", + "token_copy_now": "Please copy your API Token now, you will not be able to view it again later!", + "token_new_title": "New API Token", + "token_external_desc": "An external application is requesting access to your account. Review and adjust the permissions below before allowing access.", + "token_new_desc": "Configure and generate a new API token for your account.", + "token_external_requesting": "{{name}} is requesting an API Token. Your token will be shared with the application at {{uri}}.", + "token_allow": "Allow", + "token_generate": "Generate", + "token_deny": "Deny", + "sessions_subtitle": "Every active session on your account. Revoke any you do not recognize.", + "sessions_unknown_device": "Unknown device", + "sessions_toast_refreshed": "Sessions refreshed successfully", + "sessions_load_failed": "Failed to load sessions.", + "sessions_empty_title": "No active sessions", + "sessions_empty_desc": "Sessions appear here once you sign in from a browser or app.", + "sessions_last_seen": "Last seen {{time}}", + "sessions_signed_in": "Signed in {{time}}", + "session_toast_revoked": "Session revoked successfully", + "session_revoke_title": "Revoke session", + "session_revoke": "Revoke", + "session_revoke_desc": "Are you sure you want to revoke this session?", + "session_revoke_from": "Session logged in from {{ip}} using {{agent}}", + "connections_title": "OAuth Connections", + "connections_subtitle": "Link or unlink third-party accounts to sign in faster and keep your profile in sync.", + "connections_toast_linked": "Account linked.", + "connections_toast_cancelled": "Link flow cancelled.", + "connections_toast_failed": "Linking failed.", + "connections_toast_removed": "Connection removed", + "connections_refreshing": "Refreshing…", + "connections_link_new": "Link new provider", + "connections_empty_title": "No connections yet", + "connections_empty_desc": "Choose “Link new provider” above to connect available providers.", + "connections_unlink": "Unlink", + "connections_load_failed": "Failed to load OAuth connections.", + "connections_unlink_title": "Unlink {{name}}?", + "connections_unlink_title_generic": "Unlink this account?", + "connections_unlink_desc": "You'll no longer be able to sign in with this provider unless you link it again.", + "provider_starting": "Starting {{name}}...", + "provider_link": "Link {{name}}", + "audit_subtitle": "Security-relevant activity on your account. Review anything you do not recognize.", + "audit_col_time": "Time", + "audit_col_action": "Action", + "audit_col_details": "Details", + "audit_col_reason": "Reason", + "audit_col_ip": "IP address", + "audit_col_device": "Device", + "audit_action_login": "Signed in", + "audit_action_logout": "Signed out", + "audit_action_password_changed": "Password changed", + "audit_action_email_change_requested": "Email change requested", + "audit_action_email_changed": "Email changed", + "audit_action_username_changed": "Username changed", + "audit_action_api_token_created": "API token created", + "audit_action_api_token_deleted": "API token deleted", + "audit_action_oauth_connected": "Connection added", + "audit_action_oauth_disconnected": "Connection removed", + "audit_action_account_deactivated": "Account deactivated", + "audit_action_account_reactivated": "Account reactivated", + "audit_action_account_deleted": "Account deleted", + "audit_action_automation_token_created": "Automation token created", + "audit_action_automation_token_updated": "Automation token updated", + "audit_action_automation_token_rotated": "Automation token rotated", + "audit_action_automation_token_deleted": "Automation token deleted", + "audit_action_automation_token_used": "Automation token used", + "audit_meta_session": "Session {{id}}", + "audit_meta_changed": "{{old}} to {{new}}", + "audit_meta_email_requested": "Requested change to {{email}}", + "audit_meta_accounts_removed_one": "{{name}} ({{count}} account removed)", + "audit_meta_accounts_removed_other": "{{name}} ({{count}} accounts removed)", + "audit_meta_scheduled_deletion": "Scheduled for deletion", + "audit_meta_kept": "Kept for reactivation", + "common_view": "View", + "common_save": "Save", + "common_saving": "Saving...", + "common_back": "Back", + "common_shared_by": "Shared by", + "common_user_avatar": "User Avatar", + "common_toast_saved": "Changes saved successfully", + "pause_reason_shocker": "Paused at shocker level", + "pause_reason_shocker_user_share": "Paused at shocker and user share level", + "pause_reason_shocker_public_share": "Paused at shocker and public share level", + "pause_reason_user_share": "Paused at user share level", + "pause_reason_public_share": "Paused at public share level", + "public_shares_subtitle": "A link anyone can use, no account required.", + "public_shares_new": "New Share", + "public_share_never_expires": "Never expires", + "public_shares_empty_title": "No public shares yet", + "public_shares_empty_desc": "Create a link that anyone can use to control your shockers.", + "public_share_expired": "Expired", + "public_share_no_expiry": "No expiry", + "public_share_label": "Public Share", + "public_share_toast_created": "Created new public share", + "public_share_create_title": "Create public share", + "public_share_toast_deleted": "Deleted public share", + "public_share_delete_title": "Delete public share", + "public_share_delete_desc": "Are you sure you want to delete public share {{name}}?", + "public_share_edit_title": "Public Share: {{name}}", + "public_share_edit_subtitle": "Editing: changes apply when you save.", + "public_share_add_shocker": "Add Shocker", + "public_share_toast_added_one": "Added {{count}} shocker to share", + "public_share_toast_added_other": "Added {{count}} shockers to share", + "public_share_empty_shockers_title": "No shockers in this share", + "public_share_empty_shockers_desc": "Add a shocker and anyone with the link will be able to control it.", + "public_share_load_failed": "Error fetching public share details", + "public_share_paused_here": "Paused for this share", + "public_share_resume_shocker": "Resume shocker", + "public_share_pause_shocker": "Pause shocker", + "public_share_remove": "Remove from share", + "public_share_toast_removed": "Shocker removed from share", + "public_share_add_title": "Add shockers", + "public_share_add_desc": "Add shockers to this public share. You can set their limits once they are added.", + "public_share_add_placeholder": "Select shockers to share...", + "public_share_add_no_match": "No matching shockers", + "public_share_add_submit": "Add Shockers", + "public_share_view_loading": "Loading share details...", + "public_share_view_title": "Public Share Link", + "public_share_view_desc": "Enter as a guest or login with your OpenShock account", + "public_share_view_guest_name": "Guest Name", + "public_share_view_enter": "Enter", + "public_share_view_enter_guest": "Enter as Guest", + "public_share_login": "Login", + "perm_shock_on": "Shock enabled", + "perm_shock_off": "Shock disabled", + "perm_vibrate_on": "Vibrate enabled", + "perm_vibrate_off": "Vibrate disabled", + "perm_sound_on": "Sound enabled", + "perm_sound_off": "Sound disabled", + "perm_live_on": "Live enabled", + "perm_live_off": "Live disabled", + "perm_live_control": "Live Control", + "user_selector_avatar_of": "{{name}}'s avatar", + "user_selector_placeholder": "Enter user name", + "user_selector_aria": "Username to search", + "user_selector_search": "Search user", + "user_selector_found": "User found", + "common_remove": "Remove", + "user_shares_subtitle": "Direct permanent shares with other users.", + "user_shares_toast_invited": "Sent a shocker invite to {{name}}", + "user_shares_redeem": "Redeem Code", + "user_shares_new": "New Share", + "user_shares_tab_shares": "Shares", + "user_shares_tab_incoming": "Shared with Me", + "user_shares_tab_invites": "Invites", + "share_code_create_title": "New share code", + "share_code_create_desc": "Create a Share Code or Invite", + "share_code_shocker_placeholder": "Select shockers to share...", + "share_code_no_match": "No matching shockers", + "share_code_send_invite": "Send Share Invite", + "share_code_create": "Create Share Code", + "share_code_created_title": "Share code generated", + "share_code_created_desc": "Please copy share code or code link!", + "share_code_redeem_title": "Redeem share code", + "share_code_redeem_desc": "Enter the share code to redeem", + "share_code_redeem_placeholder": "Enter share code", + "share_code_redeemed": "Redeemed successfully!", + "share_code_shared_shockers": "Shared shockers", + "share_code_redeeming": "Redeeming...", + "share_code_redeem": "Redeem", + "incoming_shares_empty_title": "Nothing shared with you", + "incoming_shares_empty_desc": "No one has shared a shocker with you yet.", + "incoming_share_toast_removed": "Removed share for {{name}}", + "incoming_share_remove_title": "Remove Share", + "incoming_share_remove_desc": "Are you sure you want to remove the share for {{name}}?", + "incoming_share_toast_removed_shocker": "Removed {{shocker}} shared by {{name}}", + "incoming_share_remove_shocker_title": "Remove this shared shocker?", + "incoming_share_remove_shocker_desc": "Are you sure you want to remove the shocker share {{shocker}} by {{name}}?", + "incoming_share_manage_from": "Manage shares from", + "share_remove": "Remove share", + "invites_empty_title": "No invites yet", + "invites_empty_desc": "You have no incoming or outgoing share invites.", + "invites_outgoing": "Outgoing", + "invites_outgoing_empty_title": "No outgoing invites", + "invites_outgoing_empty_desc": "You have no outgoing share invites.", + "invites_incoming": "Incoming", + "invites_incoming_empty_title": "No incoming invites", + "invites_incoming_empty_desc": "You have no incoming share invites.", + "invite_toast_accepted": "Accepted share invite from {{name}}", + "invite_toast_declined": "Declined share invite from {{name}}", + "invite_deny_title": "Deny Invite", + "invite_deny_label": "Deny Invite", + "invite_deny": "Deny", + "invite_deny_desc": "Are you sure you want to deny the invite from {{name}}?", + "invite_accept": "Accept Invite", + "invite_toast_cancelled_for": "Cancelled invite for {{name}} ({{id}})", + "invite_toast_cancelled": "Cancelled invite {{id}}", + "invite_cancel_title": "Cancel Invite", + "invite_cancel": "Cancel", + "invite_cancel_for_desc": "Are you sure you want to cancel the invite for {{name}}?", + "invite_cancel_code_desc": "Are you sure you want to cancel the invite with code {{code}}?", + "invite_cancel_outstanding": "Cancel Outstanding Invite", + "outgoing_shares_empty_title": "No shared shockers", + "outgoing_shares_empty_desc": "You haven't shared any shockers with other users yet.", + "outgoing_share_toast_removed": "Removed shocker share {{name}}", + "outgoing_share_remove_title": "Stop sharing this shocker?", + "outgoing_share_editing_for": "Editing shares for", + "outgoing_share_limits": "Limits & Permissions", + "outgoing_share_same": "Same restrictions on every shocker", + "outgoing_share_per_desc": "Tune restrictions per shocker", + "outgoing_share_all": "All", + "outgoing_share_per": "Per shocker", + "outgoing_share_remove_desc": "Are you sure you want to stop sharing {{shocker}} with {{name}}?", + "report_breadcrumb": "Report API Tokens", + "report_toast_clipboard_failed": "Failed to read clipboard: {{error}}", + "report_title": "Report Leaked API Tokens", + "report_paste": "Paste from clipboard", + "report_warning": "This form is only for reporting accidentally leaked API tokens.", + "report_abuse_warning": "Intentional abuse will result in bans or severe endpoint restrictions.", + "report_detected": "Detected Tokens", + "report_invalid": "One or more tokens appear to be invalid. Please check for formatting issues.", + "report_acknowledge": "I confirm I understand what this feature is for and accept responsibility.", + "report_submit": "Submit Report", + "turnstile_disabled": "Turnstile disabled", + "common_internal_error": "Internal error", + "resend_toast_sent": "Activation email sent. Check your inbox and spam folder.", + "resend_toast_throttled": "Too many activation emails have been requested. Please try again later.", + "resend_toast_unavailable": "No activation email can be resent from this browser. If your account isn't activated yet, logging in sends a new link.", + "resend_button": "Didn't get the email? Resend", + "expiration_label": "Expiration", + "expiration_never": "Never", + "expiration_custom": "Custom", + "expiration_days_one": "{{count}} Day", + "expiration_days_other": "{{count}} Days", + "expiration_required": "Expire date is required", + "expiration_never_desc": "This will never expire", + "expiration_expires_at": "Expires {{time}} ({{date}})", + "date_picker_placeholder": "Pick a date", + "telemetry_toast_title": "Help improve OpenShock?", + "telemetry_toast_desc": "Send diagnostics to help us fix crashes and slow API calls. Reports include the error message, stack trace and your IP. You can change this any time in Account settings.", + "telemetry_toast_no": "No thanks", + "telemetry_toast_errors": "Errors only", + "telemetry_toast_full": "Full", + "table_show_details": "Show details", + "table_hide_details": "Hide details", + "table_no_results": "No results.", + "table_sort_asc": "Sort by {{name}}, ascending", + "table_sort_desc": "Sort by {{name}}, descending", + "table_sort_none": "Sort by {{name}}, unsorted", + "cell_na": "N/A", + "cell_not_applicable": "Not applicable", + "cell_invalid": "Invalid", + "cell_unavailable": "Unavailable", + "cell_none": "None", + "oauth_login_with": "Login with {{provider}}", + "oauth_signup_with": "Signup with {{provider}}", + "signalr_connect_failed": "Failed to connect to server!", + "signalr_disconnect_failed": "Encountered error while disconnecting from server!", + "signalr_invalid_update": "Received invalid update from server!", + "signalr_invalid_log": "Received invalid log data from server!", + "signalr_invalid_ota": "Received invalid firmware update data from server!", + "ota_toast_failed": "Hub firmware update failed: {{message}}", + "ota_toast_succeeded": "Hub firmware update completed successfully!", + "ota_toast_rolled_back": "Hub firmware rolled back to previous version", + "lcg_connect_failed": "Failed to connect to live control gateway", + "terminal_toast_bootloader_failed": "Failed to enter bootloader: {{error}}", + "terminal_toast_app_mode_failed": "Failed to enter application mode: {{error}}", + "problem_account_account_not_activated_title": "Account not activated", + "problem_account_account_not_activated_desc": "Check your inbox for the activation email.", + "problem_account_activation_not_found_title": "Activation link is invalid", + "problem_account_activation_not_found_desc": "The link may have expired or already been used.", + "problem_account_activation_resend_too_many_title": "Too many activation emails requested", + "problem_account_activation_resend_too_many_desc": "Please wait a while before trying again.", + "problem_account_activation_resend_unavailable_title": "Cannot resend activation email", + "problem_account_activation_resend_unavailable_desc": "Log in again to request a new activation link.", + "problem_account_deactivate_already_deactivated_title": "Account is already deactivated", + "problem_account_deactivate_denied_privileged_title": "Privileged accounts cannot be deactivated", + "problem_account_deactivate_unauthorized_title": "You are not allowed to do this", + "problem_account_deactivated_title": "This account has been deactivated", + "problem_account_email_already_in_use_title": "That email address is already in use", + "problem_account_email_invalid_title": "That email address is not valid", + "problem_account_email_taken_title": "That email address is already in use", + "problem_account_email_too_many_requests_title": "Too many email change requests", + "problem_account_email_too_many_requests_desc": "Please wait a while before trying again.", + "problem_account_email_unchanged_title": "That is already your email address", + "problem_account_email_verify_not_found_title": "Verification link is invalid", + "problem_account_email_verify_not_found_desc": "The link may have expired or already been used.", + "problem_account_o_auth_only_title": "This account has no password", + "problem_account_o_auth_only_desc": "Sign in with the provider you signed up with.", + "problem_account_password_not_set_title": "No password set", + "problem_account_password_not_set_desc": "This account signs in through an external provider.", + "problem_account_password_old_password_invalid_title": "Current password is incorrect", + "problem_account_username_invalid_title": "That username is not allowed", + "problem_account_username_recently_changed_title": "Username changed too recently", + "problem_account_username_recently_changed_desc": "You can change your username once every 7 days.", + "problem_account_username_taken_title": "That username is already taken", + "problem_admin_user_deactivated_title": "This user is deactivated", + "problem_admin_user_not_activated_title": "This user has not been activated yet", + "problem_api_token_can_only_delete_self_title": "An API token can only delete itself", + "problem_api_token_not_found_title": "API token not found", + "problem_api_token_paused_title": "This API token is paused", + "problem_assign_lcg_bad_schema_version_title": "Unsupported hub protocol version", + "problem_assign_lcg_bad_schema_version_desc": "Update the hub firmware to connect.", + "problem_assign_lcg_no_lcg_available_title": "No gateway available", + "problem_assign_lcg_no_lcg_available_desc": "No live control gateway is available right now. Please try again later.", + "problem_authentication_account_deactivated_title": "This account has been deactivated", + "problem_authentication_account_not_activated_title": "This account has not been activated", + "problem_authentication_cookie_missing_or_invalid_title": "You are not logged in", + "problem_authentication_cookie_missing_or_invalid_desc": "Your session may have expired. Please log in again.", + "problem_authentication_header_missing_or_invalid_title": "Invalid API token", + "problem_authentication_session_invalid_title": "Session expired", + "problem_authentication_session_invalid_desc": "Please log in again.", + "problem_authentication_token_invalid_title": "Invalid API token", + "problem_authentication_unknown_error_title": "Authentication failed", + "problem_authorization_policy_not_met_title": "You do not have permission to do this", + "problem_authorization_token_only_title": "This action requires an API token", + "problem_authorization_token_permission_missing_title": "This API token is missing a required permission", + "problem_authorization_unknown_error_title": "Authorization failed", + "problem_authorization_user_session_only_title": "This action requires a logged-in session", + "problem_automation_token_not_allowed_for_account_title": "Automation tokens cannot be used with privileged accounts", + "problem_configuration_already_exists_title": "A configuration entry with that name already exists", + "problem_configuration_invalid_name_format_title": "Invalid configuration name", + "problem_configuration_invalid_name_format_desc": "Only A to Z and underscores are allowed.", + "problem_configuration_invalid_value_format_title": "Value does not match the configuration type", + "problem_configuration_not_found_title": "Configuration entry not found", + "problem_control_stats_invalid_range_title": "The from date must not be after the to date", + "problem_control_stats_invalid_time_zone_title": "Unknown time zone", + "problem_control_stats_missing_capability_title": "Control statistics are not available on this server", + "problem_device_not_found_title": "Hub not found", + "problem_device_not_online_title": "Hub is offline", + "problem_device_too_many_hubs_title": "You have reached the maximum number of hubs", + "problem_device_too_many_shockers_title": "This hub has reached its maximum number of shockers", + "problem_endpoint_retired_title": "This feature is no longer available", + "problem_expression_error_title": "Invalid filter expression", + "problem_internal_server_error_title": "Something went wrong on our end", + "problem_login_invalid_credentials_title": "Invalid username or password", + "problem_login_invalid_domain_title": "Logging in from this address is not allowed", + "problem_o_auth_connection_already_exists_title": "Your account is already connected to this provider", + "problem_o_auth_connection_already_linked_title": "This external account is already linked to another user", + "problem_o_auth_flow_anonymous_only_title": "You are already signed in", + "problem_o_auth_flow_mismatch_title": "Sign-in attempt does not match", + "problem_o_auth_flow_mismatch_desc": "Please start over.", + "problem_o_auth_flow_missing_data_title": "The provider did not return your account details", + "problem_o_auth_flow_missing_data_desc": "Please try again.", + "problem_o_auth_flow_not_found_title": "Sign-in attempt expired", + "problem_o_auth_flow_not_found_desc": "Please start over.", + "problem_o_auth_flow_unsupported_title": "Unsupported sign-in flow", + "problem_o_auth_internal_error_title": "Something went wrong during sign-in", + "problem_o_auth_internal_error_desc": "Please try again in a moment.", + "problem_o_auth_link_authenticated_user_only_title": "You must be signed in to link an external account", + "problem_o_auth_provider_mismatch_title": "Sign-in attempt does not match the provider", + "problem_o_auth_provider_mismatch_desc": "Please start over.", + "problem_o_auth_provider_unsupported_title": "This sign-in provider is not supported", + "problem_pair_code_not_found_title": "Pair code not found", + "problem_password_reset_not_found_title": "Password reset link is invalid", + "problem_password_reset_not_found_desc": "The link may have expired or already been used.", + "problem_session_not_found_title": "Session not found", + "problem_share_get_no_shares_title": "You have no shares with this user", + "problem_share_request_create_cannot_share_with_self_title": "You cannot share with yourself", + "problem_share_request_create_shocker_not_found_title": "One or more shockers were not found", + "problem_share_request_create_shocker_not_found_desc": "They may have been removed or do not belong to you.", + "problem_share_request_not_found_title": "Share invite not found", + "problem_share_user_not_found_title": "Share not found", + "problem_share_code_already_linked_title": "Shocker is already linked to your account", + "problem_share_code_cant_link_own_share_code_title": "You cannot redeem your own share code", + "problem_share_code_not_found_title": "Share code not found", + "problem_share_link_expiry_date_in_past_title": "Expiry date cannot be in the past", + "problem_share_link_not_found_title": "Public share not found", + "problem_share_link_shocker_already_in_share_link_title": "Shocker is already in this public share", + "problem_share_link_shocker_not_in_share_link_title": "Shocker is not in this public share", + "problem_shocker_control_no_permission_title": "You do not have permission to control this shocker", + "problem_shocker_control_not_found_title": "Shocker not found", + "problem_shocker_control_paused_title": "Shocker is paused", + "problem_shocker_not_found_title": "Shocker not found", + "problem_signup_registration_disabled_title": "Registration is currently disabled", + "problem_signup_username_or_email_exists_title": "That username or email is already in use", + "problem_turnstile_invalid_title": "Verification failed", + "problem_turnstile_invalid_desc": "Please complete the challenge again and retry.", + "problem_user_not_found_title": "User not found", + "problem_user_privileged_delete_denied_title": "Privileged users cannot be deleted", + "problem_validation_error_title": "Some fields are invalid", + "problem_webhook_not_found_title": "Webhook not found", + "problem_webhook_unsupported_title": "Only Discord webhooks are supported", + "problem_webhook_unsupported_desc": "Use a discord.com URL, not canary or ptb.", + "error_too_many_requests": "Too many requests", + "error_retry_after_one": "Try again in {{count}} second.", + "error_retry_after_other": "Try again in {{count}} seconds.", + "error_unexpected_response": "Unexpected server response", + "error_internal": "Internal error occurred", + "error_network": "Network error occurred", + "dev_banner": "This is the OpenShock DEVELOPMENT environment. No data is saved, and it is regularly overwritten by production data.", + "firmware_channel_bugs_warning": "This channel might contain bugs." +} From cbf4d2dbfd8ccccfd1fc8a2eab8da2906f5eae64 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Luc=20=E2=99=A5?= Date: Thu, 12 Nov 2026 17:42:59 +0100 Subject: [PATCH 02/27] New translations en.json (French) [ci skip] --- messages/fr.json | 302 ++++++++++++++++++----------------------------- 1 file changed, 117 insertions(+), 185 deletions(-) diff --git a/messages/fr.json b/messages/fr.json index 6f7a6067..1a2b5fb6 100644 --- a/messages/fr.json +++ b/messages/fr.json @@ -1,15 +1,13 @@ { - "$schema": "https://inlang.com/schema/inlang-message-format", - "landing_tagline": "La plateforme de référence pour piloter des shockers à distance, en toute sécurité et avec une latence vraiment faible.", "landing_section_label": "Accueil", "landing_hubs_online": "Hubs en ligne actuellement : ", "landing_learn_more": "En savoir plus", "landing_wiki": "Wiki", "landing_meta_description": "Bienvenue sur OpenShock, un écosystème libre et open source pour piloter différents shockers via Internet.", - "instance_meta_description": "Bienvenue sur {siteName}, une instance indépendante d’OpenShock, un écosystème libre et open source pour piloter différents shockers via Internet.", + "instance_meta_description": "Bienvenue sur {{siteName}}, une instance indépendante d’OpenShock, un écosystème libre et open source pour piloter différents shockers via Internet.", "header_sidebar_toggle": "Afficher ou masquer la barre latérale", - "header_avatar_alt": "Avatar de {name}", + "header_avatar_alt": "Avatar de {{name}}", "header_menu_profile": "Profil", "header_menu_settings": "Paramètres", "header_menu_logout": "Se déconnecter", @@ -17,16 +15,14 @@ "header_signup": "S'inscrire", "header_github_title": "OpenShock sur GitHub", "header_discord_title": "Discord de la communauté", - - "footer_made_with": "Fait avec {#heart/} par l'{#team}équipe OpenShock{/team}", + "footer_made_with": "Fait avec par l'équipe OpenShock", "footer_connection_status_label": "État de la connexion au serveur", "footer_signalr_state": "État de SignalR", "footer_frontend_version": "Version du frontend", - "footer_frontend_commit_title": "Commit {commit}", + "footer_frontend_commit_title": "Commit {{commit}}", "footer_backend_version": "Version du backend", - "footer_backend_commit_title": "Commit {commit}", + "footer_backend_commit_title": "Commit {{commit}}", "footer_language_label": "Langue", - "sidebar_home_link_label": "Accueil d'OpenShock", "sidebar_group_general": "Général", "sidebar_home": "Accueil", @@ -53,7 +49,6 @@ "sidebar_settings_audit_log": "Journal d'activité", "sidebar_settings_connections": "Comptes associés", "sidebar_settings_account": "Paramètres du compte", - "error_meta_title": "Service indisponible", "error_meta_description": "OpenShock est actuellement indisponible", "error_meta_logo_alt": "Logo d'OpenShock", @@ -62,10 +57,8 @@ "error_not_found_description": "La page que vous cherchez n'existe pas.", "error_unexpected_description": "Une erreur inattendue s'est produite.", "error_go_back": "Retour", - "auth_layout_logo_alt": "Logo d'OpenShock", "auth_layout_invalid_redirect_removed": "Une URL de redirection invalide a été supprimée pour votre sécurité.", - "auth_activate_breadcrumb": "Activer le compte", "auth_activate_title": "Activer le compte", "auth_activate_activating": "Activation de votre compte...", @@ -74,17 +67,15 @@ "auth_activate_missing_token": "Jeton d'activation manquant", "auth_activate_continue": "Continuer vers la connexion", "auth_activate_toast_success": "Compte activé", - "auth_forgot_breadcrumb": "Mot de passe oublié", "auth_forgot_title": "Mot de passe oublié", "auth_forgot_description": "Saisissez votre adresse e-mail pour réinitialiser votre mot de passe", "auth_forgot_email_label": "E-mail", "auth_forgot_email_placeholder": "E-mail", "auth_forgot_submit": "Réinitialiser le mot de passe", - "auth_forgot_signin_prompt": "Vous vous souvenez de votre mot de passe ? {#signin}Se connecter{/signin}", + "auth_forgot_signin_prompt": "Vous vous souvenez de votre mot de passe ? Se connecter", "auth_forgot_mail_disabled": "La réinitialisation des mots de passe n'est pas disponible sur cette instance, car aucun fournisseur d'e-mail n'est configuré. Contactez votre administrateur pour récupérer l'accès à votre compte.", "auth_forgot_toast_sent": "La demande de réinitialisation du mot de passe a été envoyée à l'adresse e-mail indiquée", - "auth_login_breadcrumb": "Connexion", "auth_login_title": "Bon retour parmi nous", "auth_login_loading_methods": "Chargement des méthodes de connexion disponibles", @@ -98,23 +89,20 @@ "auth_login_username_label": "Nom d'utilisateur ou e-mail", "auth_login_password_label": "Mot de passe", "auth_login_submit": "Se connecter", - "auth_login_signup_prompt": "Vous n'avez pas de compte ? {#signup}S'inscrire{/signup}", - "auth_login_legal": "En cliquant sur « Se connecter », vous acceptez nos {#tos}Conditions d'utilisation{/tos} et notre {#privacy}Politique de confidentialité{/privacy}.", - - "auth_oauth_create_breadcrumb": "S'inscrire avec {provider}", - "auth_oauth_create_title": "S'inscrire avec {#provider}{provider}{/provider}", + "auth_login_signup_prompt": "Vous n'avez pas de compte ? S'inscrire", + "auth_login_legal": "En cliquant sur « Se connecter », vous acceptez nos Conditions d'utilisation et notre Politique de confidentialité.", + "auth_oauth_create_breadcrumb": "S'inscrire avec {{provider}}", + "auth_oauth_create_title": "S'inscrire avec {{provider}}", "auth_oauth_create_description": "Complétez les informations de votre compte", "auth_oauth_create_username_label": "Nom d'utilisateur", "auth_oauth_create_username_placeholder": "Nom d'utilisateur", "auth_oauth_create_email_label": "E-mail", "auth_oauth_create_email_placeholder": "E-mail", "auth_oauth_create_submit": "S'inscrire", - "auth_oauth_create_legal": "En cliquant sur « S'inscrire », vous acceptez nos {#tos}Conditions d'utilisation{/tos} et notre {#privacy}Politique de confidentialité{/privacy}.", - + "auth_oauth_create_legal": "En cliquant sur « S'inscrire », vous acceptez nos Conditions d'utilisation et notre Politique de confidentialité.", "auth_oauth_error_breadcrumb": "Erreur d'authentification", "auth_oauth_error_title": "Erreur d'authentification", "auth_oauth_error_back": "Retour à la connexion", - "auth_reset_breadcrumb": "Réinitialiser le mot de passe", "auth_reset_title": "Réinitialiser le mot de passe", "auth_reset_checking": "Vérification du lien de réinitialisation...", @@ -127,7 +115,6 @@ "auth_reset_submit": "Réinitialiser le mot de passe", "auth_reset_request_new": "Demander un nouveau lien", "auth_reset_toast_success": "Le mot de passe a été réinitialisé", - "auth_signup_breadcrumb": "Inscription", "auth_signup_toast_created_mail": "Compte créé avec succès. Consultez vos e-mails pour vérifier votre compte.", "auth_signup_toast_created_no_mail": "Compte créé avec succès. Vous pouvez vous connecter dès maintenant.", @@ -150,11 +137,10 @@ "auth_signup_confirm_label": "Confirmer le mot de passe", "auth_signup_confirm_placeholder": "Confirmer le mot de passe", "auth_signup_submit": "Créer un compte", - "auth_signup_signin_prompt": "Vous avez déjà un compte ? {#signin}Se connecter{/signin}", + "auth_signup_signin_prompt": "Vous avez déjà un compte ? Se connecter", "auth_signup_or": "Ou", "auth_signup_with_email": "S'inscrire par e-mail", - "auth_signup_legal": "En cliquant sur « Créer un compte », vous acceptez nos {#tos}Conditions d'utilisation{/tos} et notre {#privacy}Politique de confidentialité{/privacy}.", - + "auth_signup_legal": "En cliquant sur « Créer un compte », vous acceptez nos Conditions d'utilisation et notre Politique de confidentialité.", "auth_verify_breadcrumb": "Vérifier l'e-mail", "auth_verify_title": "Vérifier l'e-mail", "auth_verify_verifying": "Vérification de votre adresse e-mail...", @@ -163,7 +149,6 @@ "auth_verify_missing_token": "Jeton de vérification manquant", "auth_verify_continue": "Continuer vers la connexion", "auth_verify_toast_success": "Adresse e-mail vérifiée", - "common_cancel": "Annuler", "common_delete": "Supprimer", "common_edit": "Modifier", @@ -194,7 +179,7 @@ "control_type_shock": "Choc", "control_type_vibrate": "Vibrer", "control_type_sound": "Son", - "live_tooltip_active": "En direct via {gateway} ({country}), {latency} ms", + "live_tooltip_active": "En direct via {{gateway}} ({{country}}), {{latency}} ms", "live_tooltip_connecting": "Connexion...", "live_tooltip_connect": "Se connecter au contrôle en direct", "live_tooltip_hub_start": "Ctrl+clic pour démarrer tout le hub", @@ -207,14 +192,14 @@ "shocker_hub": "Hub", "shocker_select_hub": "Sélectionner un hub", "shocker_rf_id": "ID RF", - "shocker_rf_id_invalid": "L'ID RF doit être un nombre entier compris entre {min} et {max}.", + "shocker_rf_id_invalid": "L'ID RF doit être un nombre entier compris entre {{min}} et {{max}}.", "shocker_model": "Modèle", "shocker_select_model": "Sélectionner un modèle", "shocker_name_placeholder": "Nom du shocker", "shocker_menu_view_logs": "Voir les journaux", "shocker_delete_title": "Supprimer le shocker", - "shocker_delete_desc": "Voulez-vous vraiment supprimer « {name} » ? Cette action est irréversible.", - "shocker_toast_deleted": "Shocker « {name} » supprimé", + "shocker_delete_desc": "Voulez-vous vraiment supprimer « {{name}} » ? Cette action est irréversible.", + "shocker_toast_deleted": "Shocker « {{name}} » supprimé", "shocker_toast_paused": "Shocker mis en pause", "shocker_toast_resumed": "Shocker repris", "shocker_add_desc": "Enregistrez un nouveau shocker sur l'un de vos hubs.", @@ -239,13 +224,8 @@ "shockers_empty_no_hubs": "Créez d'abord un hub, puis ajoutez-y des shockers.", "shockers_empty_has_hubs": "Ajoutez un shocker à l'un de vos hubs pour commencer.", "shockers_create_hub": "Créer un hub", - "shockers_count": [ - { - "declarations": ["input count", "local countPlural = count: plural"], - "selectors": ["countPlural"], - "match": { "countPlural=one": "{count} shocker", "countPlural=other": "{count} shockers" } - } - ], + "shockers_count_one": "{{count}} shocker", + "shockers_count_other": "{{count}} shockers", "shared_shockers_title": "Shockers partagés", "shared_shockers_subtitle": "Les shockers que d'autres utilisateurs ont partagés avec vous.", "shared_shockers_empty_title": "Aucun shocker n'a encore été partagé avec vous.", @@ -274,18 +254,17 @@ "shocker_edit_is_active": "Le shocker est actif", "shocker_edit_toast_updated": "Shocker mis à jour", "shocker_edit_delete_desc": "Supprimez définitivement ce shocker. Cette action est irréversible.", - "common_close": "Fermer", "common_continue": "Continuer", "common_loading": "Chargement...", "common_previous": "Précédent", "common_next": "Suivant", "common_steps": "Étapes", - "common_step_label": "Étape {number} : {title}", + "common_step_label": "Étape {{number}} : {{title}}", "common_copy": "Copier", "common_copied": "Copié", "common_never": "Jamais", - "common_error": "Erreur : {message}", + "common_error": "Erreur : {{message}}", "terminal_title": "Terminal série", "terminal_connecting": "Connexion...", "terminal_help_button": "Un problème ? Aide", @@ -298,7 +277,7 @@ "terminal_mode_raw_desc": "Juste la console. Lisez les journaux de l'appareil et envoyez des commandes.", "terminal_step_channel": "Sélectionner le canal", "terminal_step_board": "Sélectionner la carte", - "terminal_go_to_step": "Aller à l'étape {number} : {title}", + "terminal_go_to_step": "Aller à l'étape {{number}} : {{title}}", "terminal_erase": "Effacer avant de flasher", "terminal_erase_desc": "Efface toutes les données de l'appareil, y compris les configurations existantes", "terminal_unsupported": "Votre navigateur ne prend pas en charge cette fonctionnalité.", @@ -313,15 +292,15 @@ "terminal_try_driver": "Vérifiez que le pilote série est installé.", "terminal_open_troubleshooter": "Ouvrir le dépannage", "terminal_log_reset_no_device": "Erreur côté hôte pendant la réinitialisation : aucun appareil !", - "terminal_log_reset_error": "Erreur côté hôte pendant la réinitialisation : {error}", + "terminal_log_reset_error": "Erreur côté hôte pendant la réinitialisation : {{error}}", "terminal_log_send_no_device": "Envoi impossible : aucun appareil !", - "terminal_log_send_error": "Envoi impossible : {error}", - "terminal_log_firmware_disconnected": "Firmware déconnecté : {error}", - "terminal_log_erase_failed": "Impossible d'effacer la mémoire flash : {error}", - "terminal_log_hard_reset_failed": "Échec de la réinitialisation matérielle : {error}", + "terminal_log_send_error": "Envoi impossible : {{error}}", + "terminal_log_firmware_disconnected": "Firmware déconnecté : {{error}}", + "terminal_log_erase_failed": "Impossible d'effacer la mémoire flash : {{error}}", + "terminal_log_hard_reset_failed": "Échec de la réinitialisation matérielle : {{error}}", "terminal_log_flash_complete": "Flash terminé", - "terminal_log_flash_failed": "Échec du flash : {error}", - "terminal_log_command_failed": "Impossible d'écrire la commande : {error}", + "terminal_log_flash_failed": "Échec du flash : {{error}}", + "terminal_log_command_failed": "Impossible d'écrire la commande : {{error}}", "terminal_help_title": "Dépannage", "terminal_help_desc": "Suivez ces étapes dans l'ordre. Chacune écarte une cause fréquente.", "terminal_help_step_cable": "Câble USB", @@ -333,23 +312,23 @@ "terminal_help_port_body": "Branchez l'appareil directement sur un port USB de votre ordinateur. Évitez si possible les hubs USB, les stations d'accueil et les ports en façade, qui causent souvent des problèmes d'alimentation et de signal. Sur un ordinateur de bureau, essayez un port à l'arrière de la machine.", "terminal_help_driver_download": "Téléchargez le pilote CP210x :", "terminal_help_driver_extract": "Extrayez le contenu du fichier zip dans un dossier de votre ordinateur.", - "terminal_help_driver_run": "Ouvrez le dossier et lancez {#code}{installer}{/code}. Suivez les instructions pour l'installer.", + "terminal_help_driver_run": "Ouvrez le dossier et lancez {{installer}}. Suivez les instructions pour l'installer.", "terminal_help_driver_reconnect": "Reconnectez l'appareil.", "terminal_help_manual_intro": "Si le pilote a été installé mais que l'appareil n'apparaît toujours pas :", - "terminal_help_manual_open": "Ouvrez le Gestionnaire de périphériques (appuyez sur {#key}Win{/key} + {#key}X{/key} et sélectionnez {#code}Device Manager{/code}).", - "terminal_help_manual_ports": "Sous {#code}Ports (COM & LPT){/code}, cherchez une entrée comme :", + "terminal_help_manual_open": "Ouvrez le Gestionnaire de périphériques (appuyez sur Win + X et sélectionnez Device Manager).", + "terminal_help_manual_ports": "Sous Ports (COM & LPT), cherchez une entrée comme :", "terminal_help_manual_missing": "Si elle est absente, Windows ne détecte pas du tout l'appareil ; reprenez les étapes du câble et du port.", - "terminal_help_manual_update": "Faites un clic droit sur l'appareil et choisissez {#code}Update Driver{/code}.", - "terminal_help_manual_browse": "Choisissez {#code}Browse my computer for drivers{/code} et sélectionnez le dossier où vous avez extrait le zip du pilote. Vérifiez que {#code}Include subfolders{/code} est coché.", - "terminal_help_manual_success": "En cas de réussite, l'entrée doit maintenant indiquer {#code}{deviceName}{/code}.", - "terminal_help_discord_intro": "Toujours bloqué ? Rejoignez notre serveur Discord et posez votre question dans le salon {#code}{channel}{/code}. Indiquez :", + "terminal_help_manual_update": "Faites un clic droit sur l'appareil et choisissez Update Driver.", + "terminal_help_manual_browse": "Choisissez Browse my computer for drivers et sélectionnez le dossier où vous avez extrait le zip du pilote. Vérifiez que Include subfolders est coché.", + "terminal_help_manual_success": "En cas de réussite, l'entrée doit maintenant indiquer {{deviceName}}.", + "terminal_help_discord_intro": "Toujours bloqué ? Rejoignez notre serveur Discord et posez votre question dans le salon {{channel}}. Indiquez :", "terminal_help_discord_os": "votre système d'exploitation et votre navigateur", "terminal_help_discord_device": "l'appareil utilisé (modèle de carte, où vous l'avez obtenu)", "terminal_help_discord_tried": "ce que vous avez déjà essayé parmi les étapes précédentes", "terminal_help_discord_errors": "les messages d'erreur ou la sortie du terminal utiles", "terminal_help_discord_join": "Rejoindre notre serveur Discord", "terminal_risk_title": "⚠️ FIRMWARE INSTABLE", - "terminal_risk_intro": "Vous êtes sur le point de flasher un {#strong}firmware expérimental{/strong} {#strong}connu pour être instable{/strong}.", + "terminal_risk_intro": "Vous êtes sur le point de flasher un firmware expérimental connu pour être instable.", "terminal_risk_brick": "Cela peut rendre votre appareil définitivement inutilisable ou nécessiter une récupération manuelle.", "terminal_risk_no_support": "Nous n'assurerons AUCUN support pour les problèmes causés par ce firmware.", "terminal_risk_acknowledge": "Je comprends que c'est entièrement ma responsabilité", @@ -364,7 +343,7 @@ "terminal_board_search": "Rechercher des cartes...", "terminal_board_none": "Aucune carte trouvée.", "terminal_flash_button": "Flasher", - "terminal_flash_progress": "Progression : {status}", + "terminal_flash_progress": "Progression : {{status}}", "terminal_flash_idle": "En attente", "terminal_flash_no_device": "Aucun appareil sélectionné.", "terminal_flash_resetting": "Réinitialisation...", @@ -375,7 +354,7 @@ "terminal_flash_done": "Appareil redémarré ! Flash terminé.", "terminal_port_select": "Sélectionner l'appareil", "terminal_port_disconnect": "Déconnecter l'appareil", - "terminal_port_connected": "Appareil connecté : {#strong}{id}{/strong}", + "terminal_port_connected": "Appareil connecté : {{id}}", "terminal_console": "Console", "terminal_connected_device": "Appareil connecté", "terminal_resize": "Redimensionner le panneau du terminal", @@ -391,7 +370,7 @@ "terminal_colors_menu": "Couleurs...", "terminal_colors_label": "Couleurs de la console", "terminal_colors_close": "Fermer les couleurs", - "terminal_color_input": "Couleur {name}", + "terminal_color_input": "Couleur {{name}}", "terminal_colors_reset": "Rétablir les valeurs par défaut", "terminal_color_bg": "Arrière-plan", "terminal_color_fg": "Texte", @@ -421,13 +400,12 @@ "terminal_toast_clipboard_unreadable": "Impossible de lire le presse-papiers", "terminal_toast_settings_imported": "Paramètres de la console importés", "terminal_toast_settings_invalid": "Le presse-papiers ne contient pas de paramètres de console", - "common_try_again": "Réessayer", - "terminal_cfg_intro": "Les valeurs sont envoyées à l'appareil via UART. La réponse de l'appareil s'affiche dans la console ci-dessous. Les commandes sans argument lisent la valeur ; utilisez le bouton {#eye/} à côté de chaque champ pour lire la valeur actuelle.", + "terminal_cfg_intro": "Les valeurs sont envoyées à l'appareil via UART. La réponse de l'appareil s'affiche dans la console ci-dessous. Les commandes sans argument lisent la valeur ; utilisez le bouton à côté de chaque champ pour lire la valeur actuelle.", "terminal_cfg_rf_title": "Émetteur RF", "terminal_cfg_rf_desc": "Contrôle la sortie RF vers les shockers.", "terminal_cfg_tx_pin": "Broche GPIO TX", - "terminal_cfg_example": "ex. : {value}", + "terminal_cfg_example": "ex. : {{value}}", "terminal_cfg_read_value": "Lire la valeur actuelle", "terminal_cfg_set": "Définir", "terminal_cfg_read": "Lire", @@ -439,13 +417,13 @@ "terminal_cfg_estop_desc": "Bouton matériel qui interrompt toute sortie.", "terminal_cfg_estop_enabled": "Arrêt d'urgence activé", "terminal_cfg_estop_pin": "Broche GPIO de l'arrêt d'urgence", - "terminal_cfg_estop_note": "Remarque : {#code}{latching}{/code} et {#code}{active}{/code} n'ont pas de commande dédiée ; définissez-les via la configuration JSON ci-dessous.", + "terminal_cfg_estop_note": "Remarque : {{latching}} et {{active}} n'ont pas de commande dédiée ; définissez-les via la configuration JSON ci-dessous.", "terminal_cfg_wifi_title": "Wi-Fi", "terminal_cfg_wifi_desc": "Identifiants réseau et nom d'hôte de l'appareil.", "terminal_cfg_hostname": "Nom d'hôte", "terminal_cfg_networks": "Réseaux (tableau JSON)", "terminal_cfg_invalid_json_array": "Doit être un tableau JSON valide", - "terminal_cfg_ap_note": "Les paramètres AP ({#code}{ssid}{/code}, {#code}{password}{/code}, {#code}{disabled}{/code}, {#code}{staDisabled}{/code}, {#code}{offlineMode}{/code}) n'ont pas de commande dédiée ; utilisez la configuration JSON.", + "terminal_cfg_ap_note": "Les paramètres AP ({{ssid}}, {{password}}, {{disabled}}, {{staDisabled}}, {{offlineMode}}) n'ont pas de commande dédiée ; utilisez la configuration JSON.", "terminal_cfg_backend_title": "Backend", "terminal_cfg_backend_desc": "Serveur OpenShock et authentification.", "terminal_cfg_domain": "Domaine", @@ -473,12 +451,11 @@ "terminal_cfg_factory_reset_confirm": "Cela effacera toute la configuration de l'appareil : réseaux Wi-Fi, identifiants du backend, broches et tous les autres paramètres. L'appareil sera réinitialisé à ses valeurs par défaut.", "terminal_cfg_read_failed_json_title": "Impossible de lire la configuration JSON", "terminal_cfg_read_failed_raw_title": "Impossible de lire la configuration brute", - "terminal_cfg_read_failed_desc": "L'appareil n'a pas répondu après {attempts} tentatives.", + "terminal_cfg_read_failed_desc": "L'appareil n'a pas répondu après {{attempts}} tentatives.", "terminal_cfg_common_causes": "Causes fréquentes :", "terminal_cfg_cause_busy": "L'appareil est occupé à traiter une autre commande.", "terminal_cfg_cause_disconnected": "L'appareil s'est déconnecté ou a redémarré.", "terminal_cfg_cause_unsupported": "La version du firmware ne prend pas en charge cette commande.", - "common_status": "État", "common_version": "Version", "common_created": "Créé", @@ -499,25 +476,25 @@ "hubs_name_placeholder": "Mon hub", "hub_toast_not_connected": "Non connecté au serveur", "hub_toast_try_later": "Réessayez dans un instant.", - "hub_reboot_title": "Redémarrer {name} ?", + "hub_reboot_title": "Redémarrer {{name}} ?", "hub_reboot_desc": "Le hub va se déconnecter et redémarrer. Les shockers associés ne répondront plus jusqu'à son retour en ligne.", "hub_reboot": "Redémarrer", - "hub_hotspot_enable_title": "Activer le point d'accès Wi-Fi sur {name} ?", - "hub_hotspot_disable_title": "Désactiver le point d'accès Wi-Fi sur {name} ?", + "hub_hotspot_enable_title": "Activer le point d'accès Wi-Fi sur {{name}} ?", + "hub_hotspot_disable_title": "Désactiver le point d'accès Wi-Fi sur {{name}} ?", "hub_hotspot_enable_desc": "Le hub diffuse son propre réseau de configuration. Il reste accessible sur votre Wi-Fi, mais le point d'accès est ouvert à toute personne à portée jusqu'à ce que vous le désactiviez.", "hub_hotspot_disable_desc": "Le point d'accès de configuration s'arrête. Si le hub n'est pas déjà sur votre Wi-Fi, vous aurez besoin d'un accès physique pour le reconfigurer.", - "hub_delete_desc": "Vous êtes sur le point de supprimer le hub {#strong}{name}{/strong}.", + "hub_delete_desc": "Vous êtes sur le point de supprimer le hub {{name}}.", "hub_delete_shockers": "Cela supprimera aussi les shockers suivants :", "hub_edit_title": "Modifier le hub", "hub_edit_apply": "Appliquer", "hub_pair_title_generate": "Générer un code d'association ?", "hub_pair_title_generated": "Code d'association généré", "hub_pair_title_paired": "Hub associé", - "hub_pair_consumed": "{#strong}{name}{/strong} a utilisé ce code d'association et est maintenant associé.", + "hub_pair_consumed": "{{name}} a utilisé ce code d'association et est maintenant associé.", "hub_pair_used": "Le code a été utilisé et n'est plus valide.", - "hub_pair_generated_for": "Code d'association généré pour {#strong}{name}{/strong}.", + "hub_pair_generated_for": "Code d'association généré pour {{name}}.", "hub_copy_now": "Le code ci-dessous ne sera plus accessible ensuite. Copiez-le maintenant et mettez à jour vos clients.", - "hub_pair_generate_for": "Vous êtes sur le point de générer un code d'association pour {#strong}{name}{/strong}.", + "hub_pair_generate_for": "Vous êtes sur le point de générer un code d'association pour {{name}}.", "hub_pair_valid_for": "Il sera valable 15 minutes après sa création.", "hub_pair_one_active": "Il n'y a qu'un code d'association actif par hub ; un nouveau code remplace l'ancien.", "hub_pair_complete": "Association terminée", @@ -525,8 +502,8 @@ "hub_pair_copied_close": "Code copié, fermer", "hub_pair_get": "Obtenir le code", "hub_token_generated": "Jeton généré", - "hub_token_generated_for": "Nouveau jeton généré pour {#strong}{name}{/strong}.", - "hub_token_regenerate_for": "Vous êtes sur le point de régénérer le jeton de {#strong}{name}{/strong}.", + "hub_token_generated_for": "Nouveau jeton généré pour {{name}}.", + "hub_token_regenerate_for": "Vous êtes sur le point de régénérer le jeton de {{name}}.", "hub_token_invalidate": "Cette action invalidera le jeton actuel et déconnectera les clients qui l'utilisent.", "hub_token_confirm": "Voulez-vous vraiment continuer ?", "hub_token_label": "Nouveau jeton :", @@ -554,12 +531,12 @@ "hub_update_status_error": "Erreur", "hub_update_status_timeout": "Délai dépassé", "hub_update_confirm_title": "Confirmer la mise à jour du firmware", - "hub_update_confirm_desc": "Mettre à jour {#strong}{name}{/strong} vers la version {#strong}{version}{/strong} ?", + "hub_update_confirm_desc": "Mettre à jour {{name}} vers la version {{version}} ?", "hub_update_unstable_warning": "Cette version ne provient peut-être pas du canal stable et peut contenir des bugs.", - "hub_update_title": "Mettre à jour {name}", + "hub_update_title": "Mettre à jour {{name}}", "hub_update_subtitle": "Gérez les mises à jour du firmware de ce hub.", "hub_update_status_title": "État du hub", - "hub_update_firmware": "Firmware : {#mono}{version}{/mono}", + "hub_update_firmware": "Firmware : {{version}}", "hub_update_confirm": "Mettre à jour", "hub_update_success": "Mise à jour terminée avec succès", "hub_update_rolled_back": "L'appareil est revenu à la version précédente", @@ -567,9 +544,9 @@ "hub_update_flash_again": "Flasher à nouveau", "hub_update_card_title": "Mise à jour du firmware", "hub_update_card_desc": "Sélectionnez un canal et une version de firmware à installer.", - "hub_update_to": "Mettre à jour vers {version}", + "hub_update_to": "Mettre à jour vers {{version}}", "hub_update_must_be_online": "Le hub doit être en ligne pour lancer une mise à jour.", - "hub_update_updating_to": "Mise à jour vers {version}...", + "hub_update_updating_to": "Mise à jour vers {{version}}...", "hub_update_total": "Total", "hub_update_task": "Tâche", "hub_update_history": "Historique des mises à jour", @@ -581,14 +558,14 @@ "hub_update_not_found": "Hub introuvable.", "home_breadcrumb": "Accueil", "home_welcome": "Bon retour", - "home_welcome_name": "Bon retour, {name}", + "home_welcome_name": "Bon retour, {{name}}", "home_subtitle": "Voici un aperçu de votre configuration OpenShock.", - "home_hubs_online": "{count} en ligne", + "home_hubs_online": "{{count}} en ligne", "home_hub_status": "État des hubs", "home_no_hubs": "Aucun hub", "home_all_online": "Tous en ligne", "home_all_offline": "Tous hors ligne", - "home_some_online": "{online}/{total} en ligne", + "home_some_online": "{{online}}/{{total}} en ligne", "home_quick_links": "Liens rapides", "home_my_shockers": "Mes shockers", "home_my_shockers_desc": "Contrôlez vos shockers", @@ -599,24 +576,15 @@ "home_get_started_desc": "Vous n'avez pas encore de hub. Créez un hub pour connecter votre premier appareil, puis ajoutez-y des shockers.", "home_set_up_hub": "Configurer un hub", "home_first_shocker": "Ajoutez votre premier shocker", - "home_first_shocker_desc": [ - { - "declarations": ["input count", "local countPlural = count: plural"], - "selectors": ["countPlural"], - "match": { - "countPlural=one": "Vous avez configuré {count} hub. Ajoutez un shocker pour commencer à le contrôler.", - "countPlural=other": "Vous avez configuré {count} hubs. Ajoutez un shocker pour commencer à le contrôler." - } - } - ], + "home_first_shocker_desc_one": "Vous avez configuré {{count}} hub. Ajoutez un shocker pour commencer à le contrôler.", + "home_first_shocker_desc_other": "Vous avez configuré {{count}} hubs. Ajoutez un shocker pour commencer à le contrôler.", "home_go_to_shockers": "Aller aux shockers", "profile_title": "Profil", "profile_coming_soon": "Le profil arrive bientôt", "profile_coming_soon_desc": "Votre profil public n'est pas encore disponible. Les informations du compte se trouvent dans les paramètres.", - "common_retry": "Réessayer", "common_never_used": "Jamais utilisé", - "common_expires": "Expire {time}", + "common_expires": "Expire {{time}}", "common_search_placeholder": "Rechercher...", "common_unknown": "Inconnu", "settings_breadcrumb_account": "Compte", @@ -646,7 +614,7 @@ "account_deactivate": "Désactiver le compte", "account_email_title": "Changer l'e-mail", "account_email_desc": "Saisissez votre nouvelle adresse e-mail et confirmez avec votre mot de passe actuel.", - "account_email_toast_sent": "E-mail de vérification envoyé à {email}. Cliquez sur le lien qu'il contient pour appliquer la modification.", + "account_email_toast_sent": "E-mail de vérification envoyé à {{email}}. Cliquez sur le lien qu'il contient pour appliquer la modification.", "account_new_email": "Nouvel e-mail", "account_current_password": "Mot de passe actuel", "account_password_title": "Changer le mot de passe", @@ -661,8 +629,8 @@ "tokens_toast_refreshed": "Jetons actualisés", "tokens_empty_title": "Aucun jeton d'API", "tokens_empty_desc": "Générez un jeton pour vous authentifier auprès de l'API OpenShock.", - "tokens_created_on": "Créé le {date}", - "tokens_last_used": "Dernière utilisation {time}", + "tokens_created_on": "Créé le {{date}}", + "tokens_last_used": "Dernière utilisation {{time}}", "tokens_never_expires": "N'expire jamais", "tokens_load_failed": "Impossible de charger les jetons d'API.", "token_toast_edited": "Jeton modifié avec succès", @@ -684,7 +652,7 @@ "token_toast_paused": "Jeton en pause", "token_toast_resumed": "Jeton réactivé", "token_delete_title": "Supprimer le jeton d'API", - "token_delete_desc": "Voulez-vous vraiment supprimer {#strong}{name}{/strong} ?", + "token_delete_desc": "Voulez-vous vraiment supprimer {{name}} ?", "token_delete_permanent": "Cette action est irréversible. Le jeton sera définitivement supprimé.", "token_toast_deleted": "Jeton supprimé avec succès", "token_resume": "Réactiver le jeton", @@ -697,11 +665,11 @@ "token_new_breadcrumb": "Nouveau", "token_redirect_not_allowed": "La redirect_uri fournie n'est pas autorisée. Seules les adresses de bouclage ou les schémas d'application personnalisés sont acceptés.", "token_params_missing": "Des paramètres GET obligatoires sont manquants. Vérifiez que name, redirect_uri et permissions sont fournis.", - "token_invalid_permissions": "Autorisations non valides : {list}", + "token_invalid_permissions": "Autorisations non valides : {{list}}", "token_toast_created": "Jeton créé avec succès", "token_request_title": "Demande de jeton d'API", "token_access_granted": "Accès accordé", - "token_shared_redirecting": "Le jeton a été créé et transmis à l'application. Redirection vers {#b}{uri}{/b}.", + "token_shared_redirecting": "Le jeton a été créé et transmis à l'application. Redirection vers {{uri}}.", "token_not_redirected": "Si vous n'êtes pas redirigé automatiquement, utilisez le bouton ci-dessous.", "token_finish": "Terminer", "token_generated_title": "Jeton d'API généré", @@ -709,7 +677,7 @@ "token_new_title": "Nouveau jeton d'API", "token_external_desc": "Une application externe demande l'accès à votre compte. Vérifiez et ajustez les autorisations ci-dessous avant d'autoriser l'accès.", "token_new_desc": "Configurez et générez un nouveau jeton d'API pour votre compte.", - "token_external_requesting": "{#b}{name}{/b} demande un jeton d'API. Votre jeton sera transmis à l'application à l'adresse {#b}{uri}{/b}.", + "token_external_requesting": "{{name}} demande un jeton d'API. Votre jeton sera transmis à l'application à l'adresse {{uri}}.", "token_allow": "Autoriser", "token_generate": "Générer", "token_deny": "Refuser", @@ -719,13 +687,13 @@ "sessions_load_failed": "Impossible de charger les sessions.", "sessions_empty_title": "Aucune session active", "sessions_empty_desc": "Les sessions apparaissent ici dès que vous vous connectez depuis un navigateur ou une application.", - "sessions_last_seen": "Vu pour la dernière fois {time}", - "sessions_signed_in": "Connecté {time}", + "sessions_last_seen": "Vu pour la dernière fois {{time}}", + "sessions_signed_in": "Connecté {{time}}", "session_toast_revoked": "Session révoquée avec succès", "session_revoke_title": "Révoquer la session", "session_revoke": "Révoquer", "session_revoke_desc": "Voulez-vous vraiment révoquer cette session ?", - "session_revoke_from": "Session connectée depuis {#strong}{ip}{/strong} avec {#strong}{agent}{/strong}", + "session_revoke_from": "Session connectée depuis {{ip}} avec {{agent}}", "connections_title": "Connexions OAuth", "connections_subtitle": "Associez ou dissociez des comptes tiers pour vous connecter plus vite et garder votre profil synchronisé.", "connections_toast_linked": "Compte associé.", @@ -738,11 +706,11 @@ "connections_empty_desc": "Choisissez « Associer un fournisseur » ci-dessus pour connecter les fournisseurs disponibles.", "connections_unlink": "Dissocier", "connections_load_failed": "Impossible de charger les connexions OAuth.", - "connections_unlink_title": "Dissocier {name} ?", + "connections_unlink_title": "Dissocier {{name}} ?", "connections_unlink_title_generic": "Dissocier ce compte ?", "connections_unlink_desc": "Vous ne pourrez plus vous connecter avec ce fournisseur, sauf si vous l'associez à nouveau.", - "provider_starting": "Lancement de {name}...", - "provider_link": "Associer {name}", + "provider_starting": "Lancement de {{name}}...", + "provider_link": "Associer {{name}}", "audit_subtitle": "Activité liée à la sécurité de votre compte. Vérifiez tout ce que vous ne reconnaissez pas.", "audit_col_time": "Heure", "audit_col_action": "Action", @@ -768,22 +736,13 @@ "audit_action_automation_token_rotated": "Jeton d'automatisation renouvelé", "audit_action_automation_token_deleted": "Jeton d'automatisation supprimé", "audit_action_automation_token_used": "Jeton d'automatisation utilisé", - "audit_meta_session": "Session {id}", - "audit_meta_changed": "{old} vers {new}", - "audit_meta_email_requested": "Changement demandé vers {email}", - "audit_meta_accounts_removed": [ - { - "declarations": ["input count", "local countPlural = count: plural"], - "selectors": ["countPlural"], - "match": { - "countPlural=one": "{name} ({count} compte supprimé)", - "countPlural=other": "{name} ({count} comptes supprimés)" - } - } - ], + "audit_meta_session": "Session {{id}}", + "audit_meta_changed": "{{old}} vers {{new}}", + "audit_meta_email_requested": "Changement demandé vers {{email}}", + "audit_meta_accounts_removed_one": "{{name}} ({{count}} compte supprimé)", + "audit_meta_accounts_removed_other": "{{name}} ({{count}} comptes supprimés)", "audit_meta_scheduled_deletion": "Suppression programmée", "audit_meta_kept": "Conservé pour réactivation", - "common_view": "Voir", "common_save": "Enregistrer", "common_saving": "Enregistrement...", @@ -808,20 +767,12 @@ "public_share_create_title": "Créer un partage public", "public_share_toast_deleted": "Partage public supprimé", "public_share_delete_title": "Supprimer le partage public", - "public_share_delete_desc": "Voulez-vous vraiment supprimer le partage public {#strong}{name}{/strong} ?", - "public_share_edit_title": "Partage public : {name}", + "public_share_delete_desc": "Voulez-vous vraiment supprimer le partage public {{name}} ?", + "public_share_edit_title": "Partage public : {{name}}", "public_share_edit_subtitle": "Modification : les changements s'appliquent à l'enregistrement.", "public_share_add_shocker": "Ajouter un shocker", - "public_share_toast_added": [ - { - "declarations": ["input count", "local countPlural = count: plural"], - "selectors": ["countPlural"], - "match": { - "countPlural=one": "{count} shocker ajouté au partage", - "countPlural=other": "{count} shockers ajoutés au partage" - } - } - ], + "public_share_toast_added_one": "{{count}} shocker ajouté au partage", + "public_share_toast_added_other": "{{count}} shockers ajoutés au partage", "public_share_empty_shockers_title": "Aucun shocker dans ce partage", "public_share_empty_shockers_desc": "Ajoutez un shocker et toute personne disposant du lien pourra le contrôler.", "public_share_load_failed": "Erreur lors du chargement du partage public", @@ -851,15 +802,14 @@ "perm_live_on": "Live activé", "perm_live_off": "Live désactivé", "perm_live_control": "Contrôle en direct", - "user_selector_avatar_of": "Avatar de {name}", + "user_selector_avatar_of": "Avatar de {{name}}", "user_selector_placeholder": "Saisissez un nom d'utilisateur", "user_selector_aria": "Nom d'utilisateur à rechercher", "user_selector_search": "Rechercher l'utilisateur", "user_selector_found": "Utilisateur trouvé", - "common_remove": "Retirer", "user_shares_subtitle": "Partages directs et permanents avec d'autres utilisateurs.", - "user_shares_toast_invited": "Invitation de shocker envoyée à {name}", + "user_shares_toast_invited": "Invitation de shocker envoyée à {{name}}", "user_shares_redeem": "Utiliser un code", "user_shares_new": "Nouveau partage", "user_shares_tab_shares": "Partages", @@ -882,12 +832,12 @@ "share_code_redeem": "Utiliser", "incoming_shares_empty_title": "Rien n'est partagé avec vous", "incoming_shares_empty_desc": "Personne n'a encore partagé de shocker avec vous.", - "incoming_share_toast_removed": "Partage de {name} retiré", + "incoming_share_toast_removed": "Partage de {{name}} retiré", "incoming_share_remove_title": "Retirer le partage", - "incoming_share_remove_desc": "Voulez-vous vraiment retirer le partage de {#strong}{name}{/strong} ?", - "incoming_share_toast_removed_shocker": "{shocker} partagé par {name} retiré", + "incoming_share_remove_desc": "Voulez-vous vraiment retirer le partage de {{name}} ?", + "incoming_share_toast_removed_shocker": "{{shocker}} partagé par {{name}} retiré", "incoming_share_remove_shocker_title": "Retirer ce shocker partagé ?", - "incoming_share_remove_shocker_desc": "Voulez-vous vraiment retirer le shocker {#strong}{shocker}{/strong} partagé par {#strong}{name}{/strong} ?", + "incoming_share_remove_shocker_desc": "Voulez-vous vraiment retirer le shocker {{shocker}} partagé par {{name}} ?", "incoming_share_manage_from": "Gérer les partages de", "share_remove": "Retirer le partage", "invites_empty_title": "Aucune invitation pour l'instant", @@ -898,23 +848,23 @@ "invites_incoming": "Reçues", "invites_incoming_empty_title": "Aucune invitation reçue", "invites_incoming_empty_desc": "Vous n'avez reçu aucune invitation.", - "invite_toast_accepted": "Invitation de {name} acceptée", - "invite_toast_declined": "Invitation de {name} refusée", + "invite_toast_accepted": "Invitation de {{name}} acceptée", + "invite_toast_declined": "Invitation de {{name}} refusée", "invite_deny_title": "Refuser l'invitation", "invite_deny_label": "Refuser l'invitation", "invite_deny": "Refuser", - "invite_deny_desc": "Voulez-vous vraiment refuser l'invitation de {#strong}{name}{/strong} ?", + "invite_deny_desc": "Voulez-vous vraiment refuser l'invitation de {{name}} ?", "invite_accept": "Accepter l'invitation", - "invite_toast_cancelled_for": "Invitation pour {name} annulée ({id})", - "invite_toast_cancelled": "Invitation {id} annulée", + "invite_toast_cancelled_for": "Invitation pour {{name}} annulée ({{id}})", + "invite_toast_cancelled": "Invitation {{id}} annulée", "invite_cancel_title": "Annuler l'invitation", "invite_cancel": "Retirer", - "invite_cancel_for_desc": "Voulez-vous vraiment annuler l'invitation pour {#strong}{name}{/strong} ?", - "invite_cancel_code_desc": "Voulez-vous vraiment annuler l'invitation avec le code {#strong}{code}{/strong} ?", + "invite_cancel_for_desc": "Voulez-vous vraiment annuler l'invitation pour {{name}} ?", + "invite_cancel_code_desc": "Voulez-vous vraiment annuler l'invitation avec le code {{code}} ?", "invite_cancel_outstanding": "Annuler l'invitation en attente", "outgoing_shares_empty_title": "Aucun shocker partagé", "outgoing_shares_empty_desc": "Vous n'avez encore partagé aucun shocker avec d'autres utilisateurs.", - "outgoing_share_toast_removed": "Shocker partagé {name} retiré", + "outgoing_share_toast_removed": "Shocker partagé {{name}} retiré", "outgoing_share_remove_title": "Ne plus partager ce shocker ?", "outgoing_share_editing_for": "Modification des partages pour", "outgoing_share_limits": "Limites et autorisations", @@ -922,11 +872,9 @@ "outgoing_share_per_desc": "Ajustez les restrictions par shocker", "outgoing_share_all": "Tous", "outgoing_share_per": "Par shocker", - - "outgoing_share_remove_desc": "Voulez-vous vraiment ne plus partager {#strong}{shocker}{/strong} avec {#strong}{name}{/strong} ?", - + "outgoing_share_remove_desc": "Voulez-vous vraiment ne plus partager {{shocker}} avec {{name}} ?", "report_breadcrumb": "Signaler des jetons d'API", - "report_toast_clipboard_failed": "Impossible de lire le presse-papiers : {error}", + "report_toast_clipboard_failed": "Impossible de lire le presse-papiers : {{error}}", "report_title": "Signaler des jetons d'API divulgués", "report_paste": "Coller depuis le presse-papiers", "report_warning": "Ce formulaire sert uniquement à signaler des jetons d'API divulgués par accident.", @@ -944,16 +892,11 @@ "expiration_label": "Expiration", "expiration_never": "Jamais", "expiration_custom": "Personnalisé", - "expiration_days": [ - { - "declarations": ["input count", "local countPlural = count: plural"], - "selectors": ["countPlural"], - "match": { "countPlural=one": "{count} jour", "countPlural=other": "{count} jours" } - } - ], + "expiration_days_one": "{{count}} jour", + "expiration_days_other": "{{count}} jours", "expiration_required": "La date d'expiration est requise", "expiration_never_desc": "N'expirera jamais", - "expiration_expires_at": "Expire {time} ({date})", + "expiration_expires_at": "Expire {{time}} ({{date}})", "date_picker_placeholder": "Choisir une date", "telemetry_toast_title": "Aider à améliorer OpenShock ?", "telemetry_toast_desc": "Envoyez des diagnostics pour nous aider à corriger les plantages et les appels API lents. Les rapports incluent le message d'erreur, la trace de pile et votre IP. Vous pouvez modifier ce choix à tout moment dans les paramètres du compte.", @@ -963,28 +906,27 @@ "table_show_details": "Afficher les détails", "table_hide_details": "Masquer les détails", "table_no_results": "Aucun résultat.", - "table_sort_asc": "Trier par {name}, croissant", - "table_sort_desc": "Trier par {name}, décroissant", - "table_sort_none": "Trier par {name}, non trié", + "table_sort_asc": "Trier par {{name}}, croissant", + "table_sort_desc": "Trier par {{name}}, décroissant", + "table_sort_none": "Trier par {{name}}, non trié", "cell_na": "N/A", "cell_not_applicable": "Non applicable", "cell_invalid": "Invalide", "cell_unavailable": "Indisponible", "cell_none": "Aucun", - "oauth_login_with": "Se connecter avec {provider}", - "oauth_signup_with": "S'inscrire avec {provider}", + "oauth_login_with": "Se connecter avec {{provider}}", + "oauth_signup_with": "S'inscrire avec {{provider}}", "signalr_connect_failed": "Impossible de se connecter au serveur !", "signalr_disconnect_failed": "Erreur lors de la déconnexion du serveur !", "signalr_invalid_update": "Mise à jour invalide reçue du serveur !", "signalr_invalid_log": "Données de journal invalides reçues du serveur !", "signalr_invalid_ota": "Données de mise à jour du firmware invalides reçues du serveur !", - "ota_toast_failed": "La mise à jour du firmware du hub a échoué : {message}", + "ota_toast_failed": "La mise à jour du firmware du hub a échoué : {{message}}", "ota_toast_succeeded": "Mise à jour du firmware du hub terminée avec succès !", "ota_toast_rolled_back": "Le firmware du hub est revenu à la version précédente", "lcg_connect_failed": "Impossible de se connecter à la passerelle de contrôle en direct", - "terminal_toast_bootloader_failed": "Impossible de passer en mode bootloader : {error}", - "terminal_toast_app_mode_failed": "Impossible de passer en mode application : {error}", - + "terminal_toast_bootloader_failed": "Impossible de passer en mode bootloader : {{error}}", + "terminal_toast_app_mode_failed": "Impossible de passer en mode application : {{error}}", "problem_account_account_not_activated_title": "Compte non activé", "problem_account_account_not_activated_desc": "Recherchez l'e-mail d'activation dans votre boîte de réception.", "problem_account_activation_not_found_title": "Le lien d'activation est invalide", @@ -1102,22 +1044,12 @@ "problem_webhook_not_found_title": "Webhook introuvable", "problem_webhook_unsupported_title": "Seuls les webhooks Discord sont pris en charge", "problem_webhook_unsupported_desc": "Utilisez une URL discord.com, pas canary ni ptb.", - "error_too_many_requests": "Trop de requêtes", - "error_retry_after": [ - { - "declarations": ["input seconds", "local secondsPlural = seconds: plural"], - "selectors": ["secondsPlural"], - "match": { - "secondsPlural=one": "Réessayez dans {seconds} seconde.", - "secondsPlural=other": "Réessayez dans {seconds} secondes." - } - } - ], + "error_retry_after_one": "Réessayez dans {{count}} seconde.", + "error_retry_after_other": "Réessayez dans {{count}} secondes.", "error_unexpected_response": "Réponse inattendue du serveur", "error_internal": "Une erreur interne s'est produite", "error_network": "Une erreur réseau s'est produite", - - "dev_banner": "Ceci est l'environnement de {#b}DÉVELOPPEMENT{/b} d'OpenShock. {#u}Aucune donnée n'est conservée{/u}, et il est régulièrement écrasé par les données de production.", + "dev_banner": "Ceci est l'environnement de DÉVELOPPEMENT d'OpenShock. Aucune donnée n'est conservée, et il est régulièrement écrasé par les données de production.", "firmware_channel_bugs_warning": "Ce canal peut contenir des bugs." } From 7f6f62cffe415ac8598e65bd100e3a3ac9d22234 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Luc=20=E2=99=A5?= Date: Thu, 12 Nov 2026 17:43:01 +0100 Subject: [PATCH 03/27] New translations en.json (Spanish) [ci skip] --- messages/es.json | 302 ++++++++++++++++++----------------------------- 1 file changed, 117 insertions(+), 185 deletions(-) diff --git a/messages/es.json b/messages/es.json index 55b90656..5ae7e546 100644 --- a/messages/es.json +++ b/messages/es.json @@ -1,15 +1,13 @@ { - "$schema": "https://inlang.com/schema/inlang-message-format", - "landing_tagline": "La plataforma de referencia para controlar shockers a distancia de forma segura, fiable y con una latencia realmente baja.", "landing_section_label": "Inicio", "landing_hubs_online": "Shockers conectados ahora: ", "landing_learn_more": "Más información", "landing_wiki": "Wiki", "landing_meta_description": "Te damos la bienvenida a OpenShock, un ecosistema libre y de código abierto para controlar distintos shockers a través de internet.", - "instance_meta_description": "Te damos la bienvenida a {siteName}, una instancia independiente de OpenShock, un ecosistema libre y de código abierto para controlar distintos shockers a través de internet.", + "instance_meta_description": "Te damos la bienvenida a {{siteName}}, una instancia independiente de OpenShock, un ecosistema libre y de código abierto para controlar distintos shockers a través de internet.", "header_sidebar_toggle": "Mostrar u ocultar la barra lateral", - "header_avatar_alt": "Avatar de {name}", + "header_avatar_alt": "Avatar de {{name}}", "header_menu_profile": "Perfil", "header_menu_settings": "Ajustes", "header_menu_logout": "Cerrar sesión", @@ -17,16 +15,14 @@ "header_signup": "Registrarse", "header_github_title": "OpenShock en GitHub", "header_discord_title": "Discord de la comunidad", - - "footer_made_with": "Hecho con {#heart/} por el {#team}equipo de OpenShock{/team}", + "footer_made_with": "Hecho con por el equipo de OpenShock", "footer_connection_status_label": "Estado de la conexión con el servidor", "footer_signalr_state": "Estado de SignalR", "footer_frontend_version": "Versión del frontend", - "footer_frontend_commit_title": "Commit {commit}", + "footer_frontend_commit_title": "Commit {{commit}}", "footer_backend_version": "Versión del backend", - "footer_backend_commit_title": "Commit {commit}", + "footer_backend_commit_title": "Commit {{commit}}", "footer_language_label": "Idioma", - "sidebar_home_link_label": "Página de inicio de OpenShock", "sidebar_group_general": "General", "sidebar_home": "Inicio", @@ -53,7 +49,6 @@ "sidebar_settings_audit_log": "Registro de actividad", "sidebar_settings_connections": "Conexiones", "sidebar_settings_account": "Ajustes de la cuenta", - "error_meta_title": "Servicio no disponible", "error_meta_description": "OpenShock no está disponible en este momento", "error_meta_logo_alt": "Logotipo de OpenShock", @@ -62,10 +57,8 @@ "error_not_found_description": "La página que buscas no existe.", "error_unexpected_description": "Se ha producido un error inesperado.", "error_go_back": "Volver", - "auth_layout_logo_alt": "Logotipo de OpenShock", "auth_layout_invalid_redirect_removed": "Se ha eliminado una URL de redirección no válida por tu seguridad.", - "auth_activate_breadcrumb": "Activar cuenta", "auth_activate_title": "Activar cuenta", "auth_activate_activating": "Activando tu cuenta...", @@ -74,17 +67,15 @@ "auth_activate_missing_token": "Falta el token de activación", "auth_activate_continue": "Continuar al inicio de sesión", "auth_activate_toast_success": "Cuenta activada", - "auth_forgot_breadcrumb": "Contraseña olvidada", "auth_forgot_title": "Contraseña olvidada", "auth_forgot_description": "Introduce tu correo electrónico para restablecer tu contraseña", "auth_forgot_email_label": "Correo electrónico", "auth_forgot_email_placeholder": "Correo electrónico", "auth_forgot_submit": "Restablecer contraseña", - "auth_forgot_signin_prompt": "¿Recuerdas tu contraseña? {#signin}Inicia sesión{/signin}", + "auth_forgot_signin_prompt": "¿Recuerdas tu contraseña? Inicia sesión", "auth_forgot_mail_disabled": "No es posible restablecer contraseñas en esta instancia porque no tiene ningún proveedor de correo configurado. Ponte en contacto con tu administrador para recuperar el acceso a tu cuenta.", "auth_forgot_toast_sent": "Se ha enviado la solicitud de restablecimiento de contraseña al correo indicado", - "auth_login_breadcrumb": "Iniciar sesión", "auth_login_title": "Hola de nuevo", "auth_login_loading_methods": "Cargando los métodos de inicio de sesión disponibles", @@ -98,23 +89,20 @@ "auth_login_username_label": "Nombre de usuario o correo electrónico", "auth_login_password_label": "Contraseña", "auth_login_submit": "Iniciar sesión", - "auth_login_signup_prompt": "¿No tienes cuenta? {#signup}Regístrate{/signup}", - "auth_login_legal": "Al hacer clic en «Iniciar sesión», aceptas nuestros {#tos}Términos del servicio{/tos} y nuestra {#privacy}Política de privacidad{/privacy}.", - - "auth_oauth_create_breadcrumb": "Registrarse con {provider}", - "auth_oauth_create_title": "Registrarse con {#provider}{provider}{/provider}", + "auth_login_signup_prompt": "¿No tienes cuenta? Regístrate", + "auth_login_legal": "Al hacer clic en «Iniciar sesión», aceptas nuestros Términos del servicio y nuestra Política de privacidad.", + "auth_oauth_create_breadcrumb": "Registrarse con {{provider}}", + "auth_oauth_create_title": "Registrarse con {{provider}}", "auth_oauth_create_description": "Completa los datos de tu cuenta", "auth_oauth_create_username_label": "Nombre de usuario", "auth_oauth_create_username_placeholder": "Nombre de usuario", "auth_oauth_create_email_label": "Correo electrónico", "auth_oauth_create_email_placeholder": "Correo electrónico", "auth_oauth_create_submit": "Registrarse", - "auth_oauth_create_legal": "Al hacer clic en «Registrarse», aceptas nuestros {#tos}Términos del servicio{/tos} y nuestra {#privacy}Política de privacidad{/privacy}.", - + "auth_oauth_create_legal": "Al hacer clic en «Registrarse», aceptas nuestros Términos del servicio y nuestra Política de privacidad.", "auth_oauth_error_breadcrumb": "Error de autenticación", "auth_oauth_error_title": "Error de autenticación", "auth_oauth_error_back": "Volver al inicio de sesión", - "auth_reset_breadcrumb": "Restablecer contraseña", "auth_reset_title": "Restablecer contraseña", "auth_reset_checking": "Comprobando el enlace de restablecimiento...", @@ -127,7 +115,6 @@ "auth_reset_submit": "Restablecer contraseña", "auth_reset_request_new": "Solicitar un enlace nuevo", "auth_reset_toast_success": "Se ha restablecido la contraseña", - "auth_signup_breadcrumb": "Registrarse", "auth_signup_toast_created_mail": "Cuenta creada correctamente. Revisa tu correo electrónico para verificar tu cuenta.", "auth_signup_toast_created_no_mail": "Cuenta creada correctamente. Ya puedes iniciar sesión.", @@ -150,11 +137,10 @@ "auth_signup_confirm_label": "Confirmar contraseña", "auth_signup_confirm_placeholder": "Confirmar contraseña", "auth_signup_submit": "Crear cuenta", - "auth_signup_signin_prompt": "¿Ya tienes cuenta? {#signin}Inicia sesión{/signin}", + "auth_signup_signin_prompt": "¿Ya tienes cuenta? Inicia sesión", "auth_signup_or": "O", "auth_signup_with_email": "Registrarse con correo electrónico", - "auth_signup_legal": "Al hacer clic en «Crear cuenta», aceptas nuestros {#tos}Términos del servicio{/tos} y nuestra {#privacy}Política de privacidad{/privacy}.", - + "auth_signup_legal": "Al hacer clic en «Crear cuenta», aceptas nuestros Términos del servicio y nuestra Política de privacidad.", "auth_verify_breadcrumb": "Verificar correo electrónico", "auth_verify_title": "Verificar correo electrónico", "auth_verify_verifying": "Verificando tu correo electrónico...", @@ -163,7 +149,6 @@ "auth_verify_missing_token": "Falta el token de verificación", "auth_verify_continue": "Continuar al inicio de sesión", "auth_verify_toast_success": "Correo electrónico verificado", - "common_cancel": "Cancelar", "common_delete": "Eliminar", "common_edit": "Editar", @@ -194,7 +179,7 @@ "control_type_shock": "Descarga", "control_type_vibrate": "Vibrar", "control_type_sound": "Sonido", - "live_tooltip_active": "En directo vía {gateway} ({country}), {latency} ms", + "live_tooltip_active": "En directo vía {{gateway}} ({{country}}), {{latency}} ms", "live_tooltip_connecting": "Conectando...", "live_tooltip_connect": "Conectar al control en directo", "live_tooltip_hub_start": "Ctrl+clic para iniciar todo el hub", @@ -207,14 +192,14 @@ "shocker_hub": "Hub", "shocker_select_hub": "Seleccionar hub", "shocker_rf_id": "ID de RF", - "shocker_rf_id_invalid": "El ID de RF debe ser un número entero entre {min} y {max}.", + "shocker_rf_id_invalid": "El ID de RF debe ser un número entero entre {{min}} y {{max}}.", "shocker_model": "Modelo", "shocker_select_model": "Seleccionar modelo", "shocker_name_placeholder": "Nombre del shocker", "shocker_menu_view_logs": "Ver registros", "shocker_delete_title": "Eliminar shocker", - "shocker_delete_desc": "¿Seguro que quieres eliminar «{name}»? Esta acción no se puede deshacer.", - "shocker_toast_deleted": "Shocker «{name}» eliminado", + "shocker_delete_desc": "¿Seguro que quieres eliminar «{{name}}»? Esta acción no se puede deshacer.", + "shocker_toast_deleted": "Shocker «{{name}}» eliminado", "shocker_toast_paused": "Shocker en pausa", "shocker_toast_resumed": "Shocker reanudado", "shocker_add_desc": "Registra un nuevo shocker en uno de tus hubs.", @@ -239,13 +224,8 @@ "shockers_empty_no_hubs": "Primero crea un hub y luego añade shockers.", "shockers_empty_has_hubs": "Añade un shocker a uno de tus hubs para empezar.", "shockers_create_hub": "Crear un hub", - "shockers_count": [ - { - "declarations": ["input count", "local countPlural = count: plural"], - "selectors": ["countPlural"], - "match": { "countPlural=one": "{count} shocker", "countPlural=other": "{count} shockers" } - } - ], + "shockers_count_one": "{{count}} shocker", + "shockers_count_other": "{{count}} shockers", "shared_shockers_title": "Shockers compartidos", "shared_shockers_subtitle": "Shockers que otros usuarios han compartido contigo.", "shared_shockers_empty_title": "Todavía nadie ha compartido shockers contigo.", @@ -274,18 +254,17 @@ "shocker_edit_is_active": "El shocker está activo", "shocker_edit_toast_updated": "Shocker actualizado", "shocker_edit_delete_desc": "Elimina este shocker de forma permanente. Esta acción no se puede deshacer.", - "common_close": "Cerrar", "common_continue": "Continuar", "common_loading": "Cargando...", "common_previous": "Anterior", "common_next": "Siguiente", "common_steps": "Pasos", - "common_step_label": "Paso {number}: {title}", + "common_step_label": "Paso {{number}}: {{title}}", "common_copy": "Copiar", "common_copied": "Copiado", "common_never": "Nunca", - "common_error": "Error: {message}", + "common_error": "Error: {{message}}", "terminal_title": "Terminal serie", "terminal_connecting": "Conectando...", "terminal_help_button": "¿Tienes problemas? Ayuda", @@ -298,7 +277,7 @@ "terminal_mode_raw_desc": "Solo la consola. Lee los registros del dispositivo y envía comandos.", "terminal_step_channel": "Seleccionar canal", "terminal_step_board": "Seleccionar placa", - "terminal_go_to_step": "Ir al paso {number}: {title}", + "terminal_go_to_step": "Ir al paso {{number}}: {{title}}", "terminal_erase": "Borrar antes de flashear", "terminal_erase_desc": "Borra todos los datos del dispositivo, incluidas las configuraciones existentes", "terminal_unsupported": "Tu navegador no admite esta función.", @@ -313,15 +292,15 @@ "terminal_try_driver": "Asegúrate de que el controlador serie esté instalado.", "terminal_open_troubleshooter": "Abrir el solucionador de problemas", "terminal_log_reset_no_device": "Error del host durante el reinicio: ¡no hay dispositivo!", - "terminal_log_reset_error": "Error del host durante el reinicio: {error}", + "terminal_log_reset_error": "Error del host durante el reinicio: {{error}}", "terminal_log_send_no_device": "No se pudo enviar: ¡no hay dispositivo!", - "terminal_log_send_error": "No se pudo enviar: {error}", - "terminal_log_firmware_disconnected": "Firmware desconectado: {error}", - "terminal_log_erase_failed": "No se pudo borrar la flash: {error}", - "terminal_log_hard_reset_failed": "Error al reiniciar por hardware: {error}", + "terminal_log_send_error": "No se pudo enviar: {{error}}", + "terminal_log_firmware_disconnected": "Firmware desconectado: {{error}}", + "terminal_log_erase_failed": "No se pudo borrar la flash: {{error}}", + "terminal_log_hard_reset_failed": "Error al reiniciar por hardware: {{error}}", "terminal_log_flash_complete": "Flasheo completado", - "terminal_log_flash_failed": "Error al flashear: {error}", - "terminal_log_command_failed": "No se pudo escribir el comando: {error}", + "terminal_log_flash_failed": "Error al flashear: {{error}}", + "terminal_log_command_failed": "No se pudo escribir el comando: {{error}}", "terminal_help_title": "Solucionador de problemas", "terminal_help_desc": "Sigue estos pasos en orden. Cada uno descarta una causa habitual.", "terminal_help_step_cable": "Cable USB", @@ -333,23 +312,23 @@ "terminal_help_port_body": "Conecta el dispositivo directamente a un puerto USB del ordenador. Evita, si puedes, los hubs USB, las bases de conexión y los puertos frontales; suelen causar problemas de alimentación y de señal. Si usas un ordenador de sobremesa, prueba un puerto de la parte trasera.", "terminal_help_driver_download": "Descarga el controlador CP210x:", "terminal_help_driver_extract": "Extrae el contenido del archivo zip en una carpeta de tu ordenador.", - "terminal_help_driver_run": "Abre la carpeta y ejecuta {#code}{installer}{/code}. Sigue las instrucciones para instalarlo.", + "terminal_help_driver_run": "Abre la carpeta y ejecuta {{installer}}. Sigue las instrucciones para instalarlo.", "terminal_help_driver_reconnect": "Vuelve a conectar el dispositivo.", "terminal_help_manual_intro": "Si el instalador del controlador se ejecutó pero el dispositivo sigue sin aparecer:", - "terminal_help_manual_open": "Abre el Administrador de dispositivos (pulsa {#key}Win{/key} + {#key}X{/key} y selecciona {#code}Device Manager{/code}).", - "terminal_help_manual_ports": "En {#code}Ports (COM & LPT){/code}, busca una entrada como:", + "terminal_help_manual_open": "Abre el Administrador de dispositivos (pulsa Win + X y selecciona Device Manager).", + "terminal_help_manual_ports": "En Ports (COM & LPT), busca una entrada como:", "terminal_help_manual_missing": "Si no aparece, Windows no detecta el dispositivo; repasa los pasos del cable y del puerto.", - "terminal_help_manual_update": "Haz clic derecho en el dispositivo y elige {#code}Update Driver{/code}.", - "terminal_help_manual_browse": "Elige {#code}Browse my computer for drivers{/code} y selecciona la carpeta donde extrajiste el zip del controlador. Asegúrate de que {#code}Include subfolders{/code} esté marcado.", - "terminal_help_manual_success": "Si todo va bien, la entrada debería mostrar {#code}{deviceName}{/code}.", - "terminal_help_discord_intro": "¿Sigues sin solución? Entra en nuestro servidor de Discord y pregunta en el canal {#code}{channel}{/code}. Incluye:", + "terminal_help_manual_update": "Haz clic derecho en el dispositivo y elige Update Driver.", + "terminal_help_manual_browse": "Elige Browse my computer for drivers y selecciona la carpeta donde extrajiste el zip del controlador. Asegúrate de que Include subfolders esté marcado.", + "terminal_help_manual_success": "Si todo va bien, la entrada debería mostrar {{deviceName}}.", + "terminal_help_discord_intro": "¿Sigues sin solución? Entra en nuestro servidor de Discord y pregunta en el canal {{channel}}. Incluye:", "terminal_help_discord_os": "tu sistema operativo y navegador", "terminal_help_discord_device": "el dispositivo que usas (modelo de placa, dónde lo conseguiste)", "terminal_help_discord_tried": "lo que ya has probado de los pasos anteriores", "terminal_help_discord_errors": "cualquier mensaje de error o salida relevante del terminal", "terminal_help_discord_join": "Únete a nuestro servidor de Discord", "terminal_risk_title": "⚠️ FIRMWARE INESTABLE", - "terminal_risk_intro": "Estás a punto de flashear {#strong}firmware experimental{/strong} que se sabe que es {#strong}inestable{/strong}.", + "terminal_risk_intro": "Estás a punto de flashear firmware experimental que se sabe que es inestable.", "terminal_risk_brick": "Esto puede inutilizar tu dispositivo de forma permanente o requerir una recuperación manual.", "terminal_risk_no_support": "NO daremos soporte para problemas causados por este firmware.", "terminal_risk_acknowledge": "Entiendo que es completamente mi responsabilidad", @@ -364,7 +343,7 @@ "terminal_board_search": "Buscar placas...", "terminal_board_none": "No se encontró ninguna placa.", "terminal_flash_button": "Flashear", - "terminal_flash_progress": "Progreso: {status}", + "terminal_flash_progress": "Progreso: {{status}}", "terminal_flash_idle": "En espera", "terminal_flash_no_device": "No hay ningún dispositivo seleccionado.", "terminal_flash_resetting": "Reiniciando...", @@ -375,7 +354,7 @@ "terminal_flash_done": "¡Dispositivo reiniciado! Flasheo completado.", "terminal_port_select": "Seleccionar dispositivo", "terminal_port_disconnect": "Desconectar dispositivo", - "terminal_port_connected": "Dispositivo conectado: {#strong}{id}{/strong}", + "terminal_port_connected": "Dispositivo conectado: {{id}}", "terminal_console": "Consola", "terminal_connected_device": "Dispositivo conectado", "terminal_resize": "Cambiar el tamaño del panel del terminal", @@ -391,7 +370,7 @@ "terminal_colors_menu": "Colores...", "terminal_colors_label": "Colores de la consola", "terminal_colors_close": "Cerrar colores", - "terminal_color_input": "Color de {name}", + "terminal_color_input": "Color de {{name}}", "terminal_colors_reset": "Restablecer valores predeterminados", "terminal_color_bg": "Fondo", "terminal_color_fg": "Texto", @@ -421,13 +400,12 @@ "terminal_toast_clipboard_unreadable": "No se pudo leer el portapapeles", "terminal_toast_settings_imported": "Ajustes de la consola importados", "terminal_toast_settings_invalid": "El portapapeles no contiene ajustes de la consola", - "common_try_again": "Reintentar", - "terminal_cfg_intro": "Los valores se envían al dispositivo por UART. La respuesta del dispositivo aparece en la consola de abajo. Los comandos sin argumento leen el valor; usa el botón {#eye/} junto a cada campo para leer el valor actual.", + "terminal_cfg_intro": "Los valores se envían al dispositivo por UART. La respuesta del dispositivo aparece en la consola de abajo. Los comandos sin argumento leen el valor; usa el botón junto a cada campo para leer el valor actual.", "terminal_cfg_rf_title": "Transmisor RF", "terminal_cfg_rf_desc": "Controla la salida RF hacia los shockers.", "terminal_cfg_tx_pin": "Pin GPIO de TX", - "terminal_cfg_example": "p. ej. {value}", + "terminal_cfg_example": "p. ej. {{value}}", "terminal_cfg_read_value": "Leer el valor actual", "terminal_cfg_set": "Establecer", "terminal_cfg_read": "Leer", @@ -439,13 +417,13 @@ "terminal_cfg_estop_desc": "Botón físico que detiene toda la salida.", "terminal_cfg_estop_enabled": "Parada de emergencia activada", "terminal_cfg_estop_pin": "Pin GPIO de parada de emergencia", - "terminal_cfg_estop_note": "Nota: {#code}{latching}{/code} y {#code}{active}{/code} no tienen comandos propios; configúralos con la configuración JSON de abajo.", + "terminal_cfg_estop_note": "Nota: {{latching}} y {{active}} no tienen comandos propios; configúralos con la configuración JSON de abajo.", "terminal_cfg_wifi_title": "WiFi", "terminal_cfg_wifi_desc": "Credenciales de red y nombre de host del dispositivo.", "terminal_cfg_hostname": "Nombre de host", "terminal_cfg_networks": "Redes (array JSON)", "terminal_cfg_invalid_json_array": "Debe ser un array JSON válido", - "terminal_cfg_ap_note": "Los ajustes de AP ({#code}{ssid}{/code}, {#code}{password}{/code}, {#code}{disabled}{/code}, {#code}{staDisabled}{/code}, {#code}{offlineMode}{/code}) no tienen comandos propios; usa la configuración JSON.", + "terminal_cfg_ap_note": "Los ajustes de AP ({{ssid}}, {{password}}, {{disabled}}, {{staDisabled}}, {{offlineMode}}) no tienen comandos propios; usa la configuración JSON.", "terminal_cfg_backend_title": "Backend", "terminal_cfg_backend_desc": "Servidor de OpenShock y autenticación.", "terminal_cfg_domain": "Dominio", @@ -473,12 +451,11 @@ "terminal_cfg_factory_reset_confirm": "Esto borrará toda la configuración del dispositivo: redes WiFi, credenciales del backend, pines y todos los demás ajustes. El dispositivo volverá a los valores predeterminados.", "terminal_cfg_read_failed_json_title": "No se pudo leer la configuración JSON", "terminal_cfg_read_failed_raw_title": "No se pudo leer la configuración sin procesar", - "terminal_cfg_read_failed_desc": "El dispositivo no respondió tras {attempts} intentos.", + "terminal_cfg_read_failed_desc": "El dispositivo no respondió tras {{attempts}} intentos.", "terminal_cfg_common_causes": "Causas habituales:", "terminal_cfg_cause_busy": "El dispositivo está ocupado con otro comando.", "terminal_cfg_cause_disconnected": "El dispositivo se desconectó o se reinició.", "terminal_cfg_cause_unsupported": "La versión del firmware no admite este comando.", - "common_status": "Estado", "common_version": "Versión", "common_created": "Creado", @@ -499,25 +476,25 @@ "hubs_name_placeholder": "Mi hub", "hub_toast_not_connected": "No conectado al servidor", "hub_toast_try_later": "Inténtalo de nuevo en un momento.", - "hub_reboot_title": "¿Reiniciar {name}?", + "hub_reboot_title": "¿Reiniciar {{name}}?", "hub_reboot_desc": "El hub se desconectará y se reiniciará. Los shockers vinculados dejarán de responder hasta que vuelva a estar en línea.", "hub_reboot": "Reiniciar", - "hub_hotspot_enable_title": "¿Activar el punto de acceso Wi-Fi en {name}?", - "hub_hotspot_disable_title": "¿Desactivar el punto de acceso Wi-Fi en {name}?", + "hub_hotspot_enable_title": "¿Activar el punto de acceso Wi-Fi en {{name}}?", + "hub_hotspot_disable_title": "¿Desactivar el punto de acceso Wi-Fi en {{name}}?", "hub_hotspot_enable_desc": "El hub emite su propia red de configuración. Sigue accesible en tu Wi-Fi, pero el punto de acceso queda abierto a cualquiera que esté cerca hasta que lo desactives.", "hub_hotspot_disable_desc": "El punto de acceso de configuración se apagará. Si el hub aún no está en tu Wi-Fi, necesitarás acceso físico para volver a configurarlo.", - "hub_delete_desc": "Estás a punto de eliminar el hub {#strong}{name}{/strong}.", + "hub_delete_desc": "Estás a punto de eliminar el hub {{name}}.", "hub_delete_shockers": "También se eliminarán los siguientes shockers:", "hub_edit_title": "Editar hub", "hub_edit_apply": "Aplicar", "hub_pair_title_generate": "¿Generar código de vinculación?", "hub_pair_title_generated": "Código de vinculación generado", "hub_pair_title_paired": "Hub vinculado", - "hub_pair_consumed": "{#strong}{name}{/strong} usó este código de vinculación y ya está vinculado.", + "hub_pair_consumed": "{{name}} usó este código de vinculación y ya está vinculado.", "hub_pair_used": "El código ya se usó y ha dejado de ser válido.", - "hub_pair_generated_for": "Código de vinculación generado para {#strong}{name}{/strong}.", + "hub_pair_generated_for": "Código de vinculación generado para {{name}}.", "hub_copy_now": "El código de abajo no estará disponible más adelante. Cópialo ahora y actualiza tus clientes con él.", - "hub_pair_generate_for": "Estás a punto de generar un código de vinculación para {#strong}{name}{/strong}.", + "hub_pair_generate_for": "Estás a punto de generar un código de vinculación para {{name}}.", "hub_pair_valid_for": "Será válido durante 15 minutos tras su creación.", "hub_pair_one_active": "Solo hay un código de vinculación activo por hub; los nuevos sustituyen a los anteriores.", "hub_pair_complete": "Vinculación completada", @@ -525,8 +502,8 @@ "hub_pair_copied_close": "Código copiado, cerrar", "hub_pair_get": "Obtener código", "hub_token_generated": "Token generado", - "hub_token_generated_for": "Nuevo token generado para {#strong}{name}{/strong}.", - "hub_token_regenerate_for": "Estás a punto de regenerar el token de {#strong}{name}{/strong}.", + "hub_token_generated_for": "Nuevo token generado para {{name}}.", + "hub_token_regenerate_for": "Estás a punto de regenerar el token de {{name}}.", "hub_token_invalidate": "Esto invalidará el token actual y desconectará a los clientes que lo usen.", "hub_token_confirm": "¿Seguro que quieres hacerlo?", "hub_token_label": "Nuevo token:", @@ -554,12 +531,12 @@ "hub_update_status_error": "Error", "hub_update_status_timeout": "Tiempo agotado", "hub_update_confirm_title": "Confirmar actualización de firmware", - "hub_update_confirm_desc": "¿Actualizar {#strong}{name}{/strong} a la versión {#strong}{version}{/strong}?", + "hub_update_confirm_desc": "¿Actualizar {{name}} a la versión {{version}}?", "hub_update_unstable_warning": "Puede que esta versión no sea del canal estable y contenga errores.", - "hub_update_title": "Actualizar {name}", + "hub_update_title": "Actualizar {{name}}", "hub_update_subtitle": "Gestiona las actualizaciones de firmware de este hub.", "hub_update_status_title": "Estado del hub", - "hub_update_firmware": "Firmware: {#mono}{version}{/mono}", + "hub_update_firmware": "Firmware: {{version}}", "hub_update_confirm": "Actualizar", "hub_update_success": "Actualización completada correctamente", "hub_update_rolled_back": "El dispositivo volvió a la versión anterior", @@ -567,9 +544,9 @@ "hub_update_flash_again": "Volver a flashear", "hub_update_card_title": "Actualización de firmware", "hub_update_card_desc": "Selecciona un canal y una versión de firmware para instalar.", - "hub_update_to": "Actualizar a {version}", + "hub_update_to": "Actualizar a {{version}}", "hub_update_must_be_online": "El hub debe estar en línea para iniciar una actualización.", - "hub_update_updating_to": "Actualizando a {version}...", + "hub_update_updating_to": "Actualizando a {{version}}...", "hub_update_total": "Total", "hub_update_task": "Tarea", "hub_update_history": "Historial de actualizaciones", @@ -581,14 +558,14 @@ "hub_update_not_found": "No se encontró el hub.", "home_breadcrumb": "Inicio", "home_welcome": "Bienvenido de nuevo", - "home_welcome_name": "Bienvenido de nuevo, {name}", + "home_welcome_name": "Bienvenido de nuevo, {{name}}", "home_subtitle": "Este es un resumen de tu configuración de OpenShock.", - "home_hubs_online": "{count} en línea", + "home_hubs_online": "{{count}} en línea", "home_hub_status": "Estado de los hubs", "home_no_hubs": "Sin hubs", "home_all_online": "Todos en línea", "home_all_offline": "Todos sin conexión", - "home_some_online": "{online}/{total} en línea", + "home_some_online": "{{online}}/{{total}} en línea", "home_quick_links": "Accesos rápidos", "home_my_shockers": "Mis shockers", "home_my_shockers_desc": "Controla tus shockers", @@ -599,24 +576,15 @@ "home_get_started_desc": "Aún no tienes hubs. Crea un hub para conectar tu primer dispositivo y luego añádele shockers.", "home_set_up_hub": "Configurar un hub", "home_first_shocker": "Añade tu primer shocker", - "home_first_shocker_desc": [ - { - "declarations": ["input count", "local countPlural = count: plural"], - "selectors": ["countPlural"], - "match": { - "countPlural=one": "Tienes {count} hub configurado. Añade un shocker para empezar a controlarlo.", - "countPlural=other": "Tienes {count} hubs configurados. Añade un shocker para empezar a controlarlo." - } - } - ], + "home_first_shocker_desc_one": "Tienes {{count}} hub configurado. Añade un shocker para empezar a controlarlo.", + "home_first_shocker_desc_other": "Tienes {{count}} hubs configurados. Añade un shocker para empezar a controlarlo.", "home_go_to_shockers": "Ir a los shockers", "profile_title": "Perfil", "profile_coming_soon": "El perfil llegará pronto", "profile_coming_soon_desc": "Tu perfil público aún no está disponible. Los datos de tu cuenta están en Ajustes.", - "common_retry": "Reintentar", "common_never_used": "Nunca usado", - "common_expires": "Caduca {time}", + "common_expires": "Caduca {{time}}", "common_search_placeholder": "Buscar...", "common_unknown": "Desconocido", "settings_breadcrumb_account": "Cuenta", @@ -646,7 +614,7 @@ "account_deactivate": "Desactivar cuenta", "account_email_title": "Cambiar correo", "account_email_desc": "Introduce tu nuevo correo electrónico y confírmalo con tu contraseña actual.", - "account_email_toast_sent": "Correo de verificación enviado a {email}. Haz clic en el enlace del correo para aplicar el cambio.", + "account_email_toast_sent": "Correo de verificación enviado a {{email}}. Haz clic en el enlace del correo para aplicar el cambio.", "account_new_email": "Nuevo correo", "account_current_password": "Contraseña actual", "account_password_title": "Cambiar contraseña", @@ -661,8 +629,8 @@ "tokens_toast_refreshed": "Tokens actualizados", "tokens_empty_title": "No hay tokens de API", "tokens_empty_desc": "Genera un token para autenticarte en la API de OpenShock.", - "tokens_created_on": "Creado el {date}", - "tokens_last_used": "Usado por última vez {time}", + "tokens_created_on": "Creado el {{date}}", + "tokens_last_used": "Usado por última vez {{time}}", "tokens_never_expires": "No caduca", "tokens_load_failed": "No se pudieron cargar los tokens de API.", "token_toast_edited": "Token editado correctamente", @@ -684,7 +652,7 @@ "token_toast_paused": "Token en pausa", "token_toast_resumed": "Token reanudado", "token_delete_title": "Eliminar token de API", - "token_delete_desc": "¿Seguro que quieres eliminar {#strong}{name}{/strong}?", + "token_delete_desc": "¿Seguro que quieres eliminar {{name}}?", "token_delete_permanent": "Esta acción no se puede deshacer. El token se eliminará de forma permanente.", "token_toast_deleted": "Token eliminado correctamente", "token_resume": "Reanudar token", @@ -697,11 +665,11 @@ "token_new_breadcrumb": "Nuevo", "token_redirect_not_allowed": "La redirect_uri indicada no está permitida. Solo se admiten direcciones de bucle local o esquemas de aplicación propios.", "token_params_missing": "Faltan parámetros GET obligatorios. Asegúrate de indicar name, redirect_uri y permissions.", - "token_invalid_permissions": "Permisos no válidos: {list}", + "token_invalid_permissions": "Permisos no válidos: {{list}}", "token_toast_created": "Token creado correctamente", "token_request_title": "Solicitud de token de API", "token_access_granted": "Acceso concedido", - "token_shared_redirecting": "El token se ha creado y compartido con la aplicación. Te estamos redirigiendo a {#b}{uri}{/b}.", + "token_shared_redirecting": "El token se ha creado y compartido con la aplicación. Te estamos redirigiendo a {{uri}}.", "token_not_redirected": "Si no se te redirige automáticamente, usa el botón de abajo.", "token_finish": "Finalizar", "token_generated_title": "Token de API generado", @@ -709,7 +677,7 @@ "token_new_title": "Nuevo token de API", "token_external_desc": "Una aplicación externa solicita acceso a tu cuenta. Revisa y ajusta los permisos de abajo antes de permitir el acceso.", "token_new_desc": "Configura y genera un nuevo token de API para tu cuenta.", - "token_external_requesting": "{#b}{name}{/b} solicita un token de API. Tu token se compartirá con la aplicación en {#b}{uri}{/b}.", + "token_external_requesting": "{{name}} solicita un token de API. Tu token se compartirá con la aplicación en {{uri}}.", "token_allow": "Permitir", "token_generate": "Generar", "token_deny": "Denegar", @@ -719,13 +687,13 @@ "sessions_load_failed": "No se pudieron cargar las sesiones.", "sessions_empty_title": "No hay sesiones activas", "sessions_empty_desc": "Las sesiones aparecen aquí cuando inicias sesión desde un navegador o una aplicación.", - "sessions_last_seen": "Visto por última vez {time}", - "sessions_signed_in": "Sesión iniciada {time}", + "sessions_last_seen": "Visto por última vez {{time}}", + "sessions_signed_in": "Sesión iniciada {{time}}", "session_toast_revoked": "Sesión revocada correctamente", "session_revoke_title": "Revocar sesión", "session_revoke": "Revocar", "session_revoke_desc": "¿Seguro que quieres revocar esta sesión?", - "session_revoke_from": "Sesión iniciada desde {#strong}{ip}{/strong} con {#strong}{agent}{/strong}", + "session_revoke_from": "Sesión iniciada desde {{ip}} con {{agent}}", "connections_title": "Conexiones OAuth", "connections_subtitle": "Vincula o desvincula cuentas de terceros para iniciar sesión más rápido y mantener tu perfil sincronizado.", "connections_toast_linked": "Cuenta vinculada.", @@ -738,11 +706,11 @@ "connections_empty_desc": "Elige «Vincular nuevo proveedor» arriba para conectar los proveedores disponibles.", "connections_unlink": "Desvincular", "connections_load_failed": "No se pudieron cargar las conexiones OAuth.", - "connections_unlink_title": "¿Desvincular {name}?", + "connections_unlink_title": "¿Desvincular {{name}}?", "connections_unlink_title_generic": "¿Desvincular esta cuenta?", "connections_unlink_desc": "Ya no podrás iniciar sesión con este proveedor a menos que lo vuelvas a vincular.", - "provider_starting": "Iniciando {name}...", - "provider_link": "Vincular {name}", + "provider_starting": "Iniciando {{name}}...", + "provider_link": "Vincular {{name}}", "audit_subtitle": "Actividad de seguridad en tu cuenta. Revisa todo lo que no reconozcas.", "audit_col_time": "Hora", "audit_col_action": "Acción", @@ -768,22 +736,13 @@ "audit_action_automation_token_rotated": "Token de automatización rotado", "audit_action_automation_token_deleted": "Token de automatización eliminado", "audit_action_automation_token_used": "Token de automatización usado", - "audit_meta_session": "Sesión {id}", - "audit_meta_changed": "{old} a {new}", - "audit_meta_email_requested": "Cambio solicitado a {email}", - "audit_meta_accounts_removed": [ - { - "declarations": ["input count", "local countPlural = count: plural"], - "selectors": ["countPlural"], - "match": { - "countPlural=one": "{name} ({count} cuenta eliminada)", - "countPlural=other": "{name} ({count} cuentas eliminadas)" - } - } - ], + "audit_meta_session": "Sesión {{id}}", + "audit_meta_changed": "{{old}} a {{new}}", + "audit_meta_email_requested": "Cambio solicitado a {{email}}", + "audit_meta_accounts_removed_one": "{{name}} ({{count}} cuenta eliminada)", + "audit_meta_accounts_removed_other": "{{name}} ({{count}} cuentas eliminadas)", "audit_meta_scheduled_deletion": "Programada para eliminación", "audit_meta_kept": "Conservada para reactivación", - "common_view": "Ver", "common_save": "Guardar", "common_saving": "Guardando...", @@ -808,20 +767,12 @@ "public_share_create_title": "Crear enlace público", "public_share_toast_deleted": "Enlace público eliminado", "public_share_delete_title": "Eliminar enlace público", - "public_share_delete_desc": "¿Seguro que quieres eliminar el enlace público {#strong}{name}{/strong}?", - "public_share_edit_title": "Enlace público: {name}", + "public_share_delete_desc": "¿Seguro que quieres eliminar el enlace público {{name}}?", + "public_share_edit_title": "Enlace público: {{name}}", "public_share_edit_subtitle": "Edición: los cambios se aplican al guardar.", "public_share_add_shocker": "Añadir shocker", - "public_share_toast_added": [ - { - "declarations": ["input count", "local countPlural = count: plural"], - "selectors": ["countPlural"], - "match": { - "countPlural=one": "Se añadió {count} shocker al enlace", - "countPlural=other": "Se añadieron {count} shockers al enlace" - } - } - ], + "public_share_toast_added_one": "Se añadió {{count}} shocker al enlace", + "public_share_toast_added_other": "Se añadieron {{count}} shockers al enlace", "public_share_empty_shockers_title": "No hay shockers en este enlace", "public_share_empty_shockers_desc": "Añade un shocker y cualquiera con el enlace podrá controlarlo.", "public_share_load_failed": "Error al obtener los detalles del enlace público", @@ -851,15 +802,14 @@ "perm_live_on": "Live activado", "perm_live_off": "Live desactivado", "perm_live_control": "Control en vivo", - "user_selector_avatar_of": "Avatar de {name}", + "user_selector_avatar_of": "Avatar de {{name}}", "user_selector_placeholder": "Introduce el nombre de usuario", "user_selector_aria": "Nombre de usuario a buscar", "user_selector_search": "Buscar usuario", "user_selector_found": "Usuario encontrado", - "common_remove": "Quitar", "user_shares_subtitle": "Comparticiones directas y permanentes con otros usuarios.", - "user_shares_toast_invited": "Invitación de shocker enviada a {name}", + "user_shares_toast_invited": "Invitación de shocker enviada a {{name}}", "user_shares_redeem": "Canjear código", "user_shares_new": "Nuevo enlace", "user_shares_tab_shares": "Compartidos", @@ -882,12 +832,12 @@ "share_code_redeem": "Canjear", "incoming_shares_empty_title": "Nada compartido contigo", "incoming_shares_empty_desc": "Nadie ha compartido un shocker contigo todavía.", - "incoming_share_toast_removed": "Se quitó lo compartido por {name}", + "incoming_share_toast_removed": "Se quitó lo compartido por {{name}}", "incoming_share_remove_title": "Quitar compartido", - "incoming_share_remove_desc": "¿Seguro que quieres quitar lo compartido por {#strong}{name}{/strong}?", - "incoming_share_toast_removed_shocker": "Se quitó {shocker} compartido por {name}", + "incoming_share_remove_desc": "¿Seguro que quieres quitar lo compartido por {{name}}?", + "incoming_share_toast_removed_shocker": "Se quitó {{shocker}} compartido por {{name}}", "incoming_share_remove_shocker_title": "¿Quitar este shocker compartido?", - "incoming_share_remove_shocker_desc": "¿Seguro que quieres quitar el shocker {#strong}{shocker}{/strong} compartido por {#strong}{name}{/strong}?", + "incoming_share_remove_shocker_desc": "¿Seguro que quieres quitar el shocker {{shocker}} compartido por {{name}}?", "incoming_share_manage_from": "Gestionar lo compartido por", "share_remove": "Quitar compartido", "invites_empty_title": "Aún no hay invitaciones", @@ -898,23 +848,23 @@ "invites_incoming": "Entrantes", "invites_incoming_empty_title": "No hay invitaciones entrantes", "invites_incoming_empty_desc": "No tienes invitaciones entrantes.", - "invite_toast_accepted": "Aceptaste la invitación de {name}", - "invite_toast_declined": "Rechazaste la invitación de {name}", + "invite_toast_accepted": "Aceptaste la invitación de {{name}}", + "invite_toast_declined": "Rechazaste la invitación de {{name}}", "invite_deny_title": "Rechazar invitación", "invite_deny_label": "Rechazar invitación", "invite_deny": "Rechazar", - "invite_deny_desc": "¿Seguro que quieres rechazar la invitación de {#strong}{name}{/strong}?", + "invite_deny_desc": "¿Seguro que quieres rechazar la invitación de {{name}}?", "invite_accept": "Aceptar invitación", - "invite_toast_cancelled_for": "Invitación para {name} cancelada ({id})", - "invite_toast_cancelled": "Invitación {id} cancelada", + "invite_toast_cancelled_for": "Invitación para {{name}} cancelada ({{id}})", + "invite_toast_cancelled": "Invitación {{id}} cancelada", "invite_cancel_title": "Cancelar invitación", "invite_cancel": "Retirar", - "invite_cancel_for_desc": "¿Seguro que quieres cancelar la invitación para {#strong}{name}{/strong}?", - "invite_cancel_code_desc": "¿Seguro que quieres cancelar la invitación con el código {#strong}{code}{/strong}?", + "invite_cancel_for_desc": "¿Seguro que quieres cancelar la invitación para {{name}}?", + "invite_cancel_code_desc": "¿Seguro que quieres cancelar la invitación con el código {{code}}?", "invite_cancel_outstanding": "Cancelar invitación pendiente", "outgoing_shares_empty_title": "No hay shockers compartidos", "outgoing_shares_empty_desc": "Aún no has compartido ningún shocker con otros usuarios.", - "outgoing_share_toast_removed": "Se quitó el shocker compartido {name}", + "outgoing_share_toast_removed": "Se quitó el shocker compartido {{name}}", "outgoing_share_remove_title": "¿Dejar de compartir este shocker?", "outgoing_share_editing_for": "Editando lo compartido con", "outgoing_share_limits": "Límites y permisos", @@ -922,11 +872,9 @@ "outgoing_share_per_desc": "Ajusta las restricciones de cada shocker", "outgoing_share_all": "Todos", "outgoing_share_per": "Por shocker", - - "outgoing_share_remove_desc": "¿Seguro que quieres dejar de compartir {#strong}{shocker}{/strong} con {#strong}{name}{/strong}?", - + "outgoing_share_remove_desc": "¿Seguro que quieres dejar de compartir {{shocker}} con {{name}}?", "report_breadcrumb": "Denunciar tokens de API", - "report_toast_clipboard_failed": "No se pudo leer el portapapeles: {error}", + "report_toast_clipboard_failed": "No se pudo leer el portapapeles: {{error}}", "report_title": "Denunciar tokens de API filtrados", "report_paste": "Pegar del portapapeles", "report_warning": "Este formulario es solo para denunciar tokens de API filtrados por accidente.", @@ -944,16 +892,11 @@ "expiration_label": "Caducidad", "expiration_never": "Nunca", "expiration_custom": "Personalizado", - "expiration_days": [ - { - "declarations": ["input count", "local countPlural = count: plural"], - "selectors": ["countPlural"], - "match": { "countPlural=one": "{count} día", "countPlural=other": "{count} días" } - } - ], + "expiration_days_one": "{{count}} día", + "expiration_days_other": "{{count}} días", "expiration_required": "La fecha de caducidad es obligatoria", "expiration_never_desc": "Nunca caducará", - "expiration_expires_at": "Caduca {time} ({date})", + "expiration_expires_at": "Caduca {{time}} ({{date}})", "date_picker_placeholder": "Elige una fecha", "telemetry_toast_title": "¿Nos ayudas a mejorar OpenShock?", "telemetry_toast_desc": "Envía diagnósticos para ayudarnos a corregir fallos y llamadas lentas a la API. Los informes incluyen el mensaje de error, la traza de la pila y tu IP. Puedes cambiarlo cuando quieras en los ajustes de la cuenta.", @@ -963,28 +906,27 @@ "table_show_details": "Mostrar detalles", "table_hide_details": "Ocultar detalles", "table_no_results": "Sin resultados.", - "table_sort_asc": "Ordenar por {name}, ascendente", - "table_sort_desc": "Ordenar por {name}, descendente", - "table_sort_none": "Ordenar por {name}, sin ordenar", + "table_sort_asc": "Ordenar por {{name}}, ascendente", + "table_sort_desc": "Ordenar por {{name}}, descendente", + "table_sort_none": "Ordenar por {{name}}, sin ordenar", "cell_na": "N/D", "cell_not_applicable": "No aplica", "cell_invalid": "No válido", "cell_unavailable": "No disponible", "cell_none": "Ninguno", - "oauth_login_with": "Iniciar sesión con {provider}", - "oauth_signup_with": "Registrarse con {provider}", + "oauth_login_with": "Iniciar sesión con {{provider}}", + "oauth_signup_with": "Registrarse con {{provider}}", "signalr_connect_failed": "¡No se pudo conectar con el servidor!", "signalr_disconnect_failed": "¡Error al desconectarse del servidor!", "signalr_invalid_update": "¡Se recibió una actualización no válida del servidor!", "signalr_invalid_log": "¡Se recibieron datos de registro no válidos del servidor!", "signalr_invalid_ota": "¡Se recibieron datos de actualización de firmware no válidos!", - "ota_toast_failed": "La actualización de firmware del hub falló: {message}", + "ota_toast_failed": "La actualización de firmware del hub falló: {{message}}", "ota_toast_succeeded": "¡La actualización de firmware del hub se completó!", "ota_toast_rolled_back": "El firmware del hub volvió a la versión anterior", "lcg_connect_failed": "No se pudo conectar con la pasarela de control en vivo", - "terminal_toast_bootloader_failed": "No se pudo entrar en el cargador de arranque: {error}", - "terminal_toast_app_mode_failed": "No se pudo entrar en el modo de aplicación: {error}", - + "terminal_toast_bootloader_failed": "No se pudo entrar en el cargador de arranque: {{error}}", + "terminal_toast_app_mode_failed": "No se pudo entrar en el modo de aplicación: {{error}}", "problem_account_account_not_activated_title": "Cuenta no activada", "problem_account_account_not_activated_desc": "Busca el correo de activación en tu bandeja de entrada.", "problem_account_activation_not_found_title": "El enlace de activación no es válido", @@ -1102,22 +1044,12 @@ "problem_webhook_not_found_title": "No se encontró el webhook", "problem_webhook_unsupported_title": "Solo se admiten webhooks de Discord", "problem_webhook_unsupported_desc": "Usa una URL de discord.com, no de canary ni ptb.", - "error_too_many_requests": "Demasiadas solicitudes", - "error_retry_after": [ - { - "declarations": ["input seconds", "local secondsPlural = seconds: plural"], - "selectors": ["secondsPlural"], - "match": { - "secondsPlural=one": "Inténtalo de nuevo en {seconds} segundo.", - "secondsPlural=other": "Inténtalo de nuevo en {seconds} segundos." - } - } - ], + "error_retry_after_one": "Inténtalo de nuevo en {{count}} segundo.", + "error_retry_after_other": "Inténtalo de nuevo en {{count}} segundos.", "error_unexpected_response": "Respuesta inesperada del servidor", "error_internal": "Se produjo un error interno", "error_network": "Se produjo un error de red", - - "dev_banner": "Este es el entorno de {#b}DESARROLLO{/b} de OpenShock. {#u}No se guarda ningún dato{/u} y se sobrescribe a menudo con datos de producción.", + "dev_banner": "Este es el entorno de DESARROLLO de OpenShock. No se guarda ningún dato y se sobrescribe a menudo con datos de producción.", "firmware_channel_bugs_warning": "Este canal puede contener errores." } From 3de6b99560757f1d388d7c65d6b1ce600210b6c6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Luc=20=E2=99=A5?= Date: Thu, 12 Nov 2026 17:43:03 +0100 Subject: [PATCH 04/27] New translations en.json (Afrikaans) [ci skip] --- messages/af.json | 1055 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 1055 insertions(+) create mode 100644 messages/af.json diff --git a/messages/af.json b/messages/af.json new file mode 100644 index 00000000..ef4df56c --- /dev/null +++ b/messages/af.json @@ -0,0 +1,1055 @@ +{ + "landing_tagline": "The go-to platform for safe, reliable, real low-latency remote shocking.", + "landing_section_label": "Home", + "landing_hubs_online": "Hubs online right now: ", + "landing_learn_more": "Learn More", + "landing_wiki": "Wiki", + "landing_meta_description": "Welcome to OpenShock, a free and open-source ecosystem to control various shock collars over the internet.", + "instance_meta_description": "Welcome to {{siteName}}, an independent instance of OpenShock, a free and open-source ecosystem to control various shock collars over the internet.", + "header_sidebar_toggle": "Toggle Sidebar", + "header_avatar_alt": "{{name}}'s avatar", + "header_menu_profile": "Profile", + "header_menu_settings": "Settings", + "header_menu_logout": "Logout", + "header_login": "Login", + "header_signup": "Sign Up", + "header_github_title": "OpenShock on GitHub", + "header_discord_title": "Community Discord", + "footer_made_with": "Made with by the OpenShock Team", + "footer_connection_status_label": "Server connection status", + "footer_signalr_state": "SignalR State", + "footer_frontend_version": "Frontend Version", + "footer_frontend_commit_title": "Commit {{commit}}", + "footer_backend_version": "Backend Version", + "footer_backend_commit_title": "Commit {{commit}}", + "footer_language_label": "Language", + "sidebar_home_link_label": "OpenShock home", + "sidebar_group_general": "General", + "sidebar_home": "Home", + "sidebar_shockers": "Shockers", + "sidebar_shared_shockers": "Shared Shockers", + "sidebar_hubs": "Hubs", + "sidebar_user_shares": "User Shares", + "sidebar_public_shares": "Public Shares", + "sidebar_serial_terminal": "Serial Terminal", + "sidebar_group_admin": "Admin", + "sidebar_admin_monitoring": "Monitoring", + "sidebar_admin_online_hubs": "Online Hubs", + "sidebar_admin_online_gateways": "Online Gateways", + "sidebar_admin_management": "Management", + "sidebar_admin_users": "Users", + "sidebar_admin_blacklists": "Blacklists", + "sidebar_admin_webhooks": "Webhooks", + "sidebar_admin_mail": "Mail", + "sidebar_admin_automation_tokens": "Automation Tokens", + "sidebar_admin_configuration": "Configuration", + "sidebar_group_settings": "Settings", + "sidebar_settings_api_tokens": "API Tokens", + "sidebar_settings_sessions": "Sessions", + "sidebar_settings_audit_log": "Audit Log", + "sidebar_settings_connections": "Connections", + "sidebar_settings_account": "Account Settings", + "error_meta_title": "Service Unavailable", + "error_meta_description": "OpenShock is currently unavailable", + "error_meta_logo_alt": "OpenShock Logo", + "error_fallback_message": "Something went wrong.", + "error_not_found_message": "Page not found", + "error_not_found_description": "The page you're looking for doesn't exist.", + "error_unexpected_description": "An unexpected error occurred.", + "error_go_back": "Go back", + "auth_layout_logo_alt": "OpenShock Logo", + "auth_layout_invalid_redirect_removed": "An invalid redirect URL was removed for your safety.", + "auth_activate_breadcrumb": "Activate Account", + "auth_activate_title": "Activate Account", + "auth_activate_activating": "Activating your account...", + "auth_activate_success": "Your account has been activated", + "auth_activate_failed": "This activation link is invalid or has expired", + "auth_activate_missing_token": "Missing activation token", + "auth_activate_continue": "Continue to login", + "auth_activate_toast_success": "Account activated", + "auth_forgot_breadcrumb": "Forgot Password", + "auth_forgot_title": "Forgot Password", + "auth_forgot_description": "Enter your email to reset your password", + "auth_forgot_email_label": "Email", + "auth_forgot_email_placeholder": "Email", + "auth_forgot_submit": "Reset Password", + "auth_forgot_signin_prompt": "Remember your password? Sign in", + "auth_forgot_mail_disabled": "Password resets are unavailable on this instance because it has no mail provider configured. Please contact your administrator for help recovering your account.", + "auth_forgot_toast_sent": "Reset password request has been sent to the given email", + "auth_login_breadcrumb": "Login", + "auth_login_title": "Welcome back", + "auth_login_loading_methods": "Loading available login methods", + "auth_login_choose_method": "Login with one of these methods", + "auth_login_with_account": "Login with your OpenShock Account", + "auth_login_activation_after_signup": "Your account has been created. We've sent an activation link to your email address. Check your inbox and spam folder.", + "auth_login_activation_pending": "Your account isn't activated yet. We've sent an activation link to your email address. Check your inbox and spam folder. If nothing arrives, try logging in again later to get a new link.", + "auth_login_oauth_only": "This account has no password. Sign in with the provider you signed up with.", + "auth_login_oauth_only_with_buttons": "This account has no password. Sign in with the provider you signed up with using the buttons above.", + "auth_login_or_continue_with": "Or continue with", + "auth_login_username_label": "Username or Email", + "auth_login_password_label": "Password", + "auth_login_submit": "Login", + "auth_login_signup_prompt": "Don't have an account? Sign up", + "auth_login_legal": "By clicking Login, you agree to our Terms of Service and Privacy Policy.", + "auth_oauth_create_breadcrumb": "Sign Up With {{provider}}", + "auth_oauth_create_title": "Sign Up With {{provider}}", + "auth_oauth_create_description": "Complete your account details", + "auth_oauth_create_username_label": "Username", + "auth_oauth_create_username_placeholder": "Username", + "auth_oauth_create_email_label": "Email", + "auth_oauth_create_email_placeholder": "Email", + "auth_oauth_create_submit": "Sign Up", + "auth_oauth_create_legal": "By clicking Sign Up, you agree to our Terms of Service and Privacy Policy.", + "auth_oauth_error_breadcrumb": "Authentication Error", + "auth_oauth_error_title": "Authentication Error", + "auth_oauth_error_back": "Back to login", + "auth_reset_breadcrumb": "Reset Password", + "auth_reset_title": "Reset Password", + "auth_reset_checking": "Verifying reset link...", + "auth_reset_choose_password": "Choose a new password for your account", + "auth_reset_invalid": "This reset link is invalid or has expired", + "auth_reset_password_label": "New Password", + "auth_reset_password_placeholder": "New Password", + "auth_reset_confirm_label": "Confirm New Password", + "auth_reset_confirm_placeholder": "Confirm New Password", + "auth_reset_submit": "Reset Password", + "auth_reset_request_new": "Request a new reset link", + "auth_reset_toast_success": "Password has been reset", + "auth_signup_breadcrumb": "Sign Up", + "auth_signup_toast_created_mail": "Account created successfully. Please check your email to verify your account.", + "auth_signup_toast_created_no_mail": "Account created successfully. You can log in now.", + "auth_signup_dialog_title": "Welcome! Thank you for signing up! ❤️", + "auth_signup_dialog_created_mail": "Your account has been created. 🎉 Please check your email to verify your account.", + "auth_signup_dialog_verify_then_login": "After verifying your email, you can log in to your account.", + "auth_signup_dialog_created_no_mail": "Your account has been created and is ready to use. 🎉", + "auth_signup_dialog_login_now": "You can log in to your account now.", + "auth_signup_title": "Create your account", + "auth_signup_loading_methods": "Loading available sign-up methods", + "auth_signup_using_email": "Signing up using email", + "auth_signup_choose_method": "Choose your preferred sign-up method", + "auth_signup_back": "Back", + "auth_signup_username_label": "Username", + "auth_signup_username_placeholder": "John OpenShock", + "auth_signup_email_label": "Email", + "auth_signup_email_placeholder": "john@example.com", + "auth_signup_password_label": "Password", + "auth_signup_password_placeholder": "Password", + "auth_signup_confirm_label": "Confirm Password", + "auth_signup_confirm_placeholder": "Confirm Password", + "auth_signup_submit": "Create Account", + "auth_signup_signin_prompt": "Already have an account? Sign in", + "auth_signup_or": "Or", + "auth_signup_with_email": "Signup with Email", + "auth_signup_legal": "By clicking Create Account, you agree to our Terms of Service and Privacy Policy.", + "auth_verify_breadcrumb": "Verify Email", + "auth_verify_title": "Verify Email", + "auth_verify_verifying": "Verifying your email address...", + "auth_verify_success": "Your email has been verified", + "auth_verify_failed": "This verification link is invalid or has expired", + "auth_verify_missing_token": "Missing verification token", + "auth_verify_continue": "Continue to login", + "auth_verify_toast_success": "Email verified", + "common_cancel": "Cancel", + "common_delete": "Delete", + "common_edit": "Edit", + "common_share": "Share", + "common_copy_id": "Copy ID", + "common_id_copied": "ID copied to clipboard", + "common_open_menu": "Open menu", + "common_refresh": "Refresh", + "common_settings": "Settings", + "common_clear": "Clear", + "common_online": "Online", + "common_offline": "Offline", + "common_paused": "Paused", + "common_resume": "Resume", + "common_resuming": "Resuming...", + "common_coming_soon": "(Coming soon)", + "common_save_changes": "Save Changes", + "common_danger_zone": "Danger Zone", + "common_name": "Name", + "control_intensity": "Intensity", + "control_duration": "Duration", + "control_max_intensity": "Max Intensity", + "control_max_duration": "Max Duration", + "control_vibration": "Vibration", + "control_value": "Value", + "control_live_intensity": "Live intensity", + "control_type_stop": "Stop", + "control_type_shock": "Shock", + "control_type_vibrate": "Vibrate", + "control_type_sound": "Sound", + "live_tooltip_active": "Live via {{gateway}} ({{country}}), {{latency}}ms", + "live_tooltip_connecting": "Connecting...", + "live_tooltip_connect": "Connect to Live Control", + "live_tooltip_hub_start": "Ctrl+click to start the whole hub", + "live_tooltip_hub_stop": "Ctrl+click to stop the whole hub", + "pause_resume_shocker": "Resume shocker", + "pause_pause_shocker": "Pause shocker", + "pause_resume_all": "Resume all shockers", + "pause_pause_all": "Pause all shockers", + "shocker_label": "Shocker", + "shocker_hub": "Hub", + "shocker_select_hub": "Select hub", + "shocker_rf_id": "RF ID", + "shocker_rf_id_invalid": "RF ID must be a whole number between {{min}} and {{max}}.", + "shocker_model": "Model", + "shocker_select_model": "Select model", + "shocker_name_placeholder": "Shocker name", + "shocker_menu_view_logs": "View Logs", + "shocker_delete_title": "Delete Shocker", + "shocker_delete_desc": "Are you sure you want to delete \"{{name}}\"? This action cannot be undone.", + "shocker_toast_deleted": "Shocker \"{{name}}\" deleted", + "shocker_toast_paused": "Shocker paused", + "shocker_toast_resumed": "Shocker resumed", + "shocker_add_desc": "Register a new shocker to one of your hubs.", + "shocker_add_name_placeholder": "My Shocker", + "shockers_title": "Shockers", + "shockers_subtitle": "Every shocker paired to your hubs.", + "shockers_loading": "Loading shockers...", + "shockers_toast_refreshed": "Shockers refreshed", + "shockers_toast_need_hub": "You need to create a hub before adding shockers.", + "shockers_toast_added": "Shocker added", + "shockers_unknown_module": "Unknown module type", + "shockers_add": "Add Shocker", + "shockers_view_mode": "View mode", + "shockers_mode_classic": "Classic", + "shockers_mode_rich": "Rich", + "shockers_mode_simple": "Simple", + "shockers_mode_map": "Map", + "shockers_group_by_hub": "Group by Hub", + "shockers_global_limits": "Global Limits", + "shockers_logs_label": "Logs", + "shockers_empty_title": "No shockers yet", + "shockers_empty_no_hubs": "Create a hub first, then add shockers to it.", + "shockers_empty_has_hubs": "Add a shocker to one of your hubs to get started.", + "shockers_create_hub": "Create a Hub", + "shockers_count_one": "{{count}} shocker", + "shockers_count_other": "{{count}} shockers", + "shared_shockers_title": "Shared Shockers", + "shared_shockers_subtitle": "Shockers other users have shared with you.", + "shared_shockers_empty_title": "No shockers have been shared with you yet.", + "shared_shockers_empty_desc": "When someone shares their shockers with you, they'll appear here.", + "shocker_logs_title": "Shocker Logs", + "shocker_logs_subtitle": "Every control command sent to your shockers.", + "shocker_logs_live_title": "New logs appear in real time", + "shocker_logs_paused_title": "Live updates pause when sorting or viewing a page other than the first", + "shocker_logs_live": "Live", + "shocker_logs_col_time": "Time", + "shocker_logs_col_type": "Type", + "shocker_logs_col_by": "By", + "shocker_logs_filter_label": "Filter by shocker", + "shocker_logs_filter_placeholder": "Search shockers...", + "shocker_logs_filter_all": "All shockers", + "shocker_logs_filter_none": "No matching shockers", + "shocker_edit_title": "Edit Shocker", + "shocker_edit_subtitle": "Change this shocker's details or remove it.", + "shocker_edit_back": "Back to Shockers", + "shocker_edit_load_failed": "Failed to load shocker.", + "shocker_edit_loading": "Loading shocker...", + "shocker_edit_details_title": "Shocker Details", + "shocker_edit_details_desc": "Update the name, RF ID, and model for this shocker.", + "shocker_edit_pause_state": "Pause State", + "shocker_edit_is_paused": "Shocker is paused", + "shocker_edit_is_active": "Shocker is active", + "shocker_edit_toast_updated": "Shocker updated", + "shocker_edit_delete_desc": "Permanently delete this shocker. This action cannot be undone.", + "common_close": "Close", + "common_continue": "Continue", + "common_loading": "Loading...", + "common_previous": "Previous", + "common_next": "Next", + "common_steps": "Steps", + "common_step_label": "Step {{number}}: {{title}}", + "common_copy": "Copy", + "common_copied": "Copied", + "common_never": "Never", + "common_error": "Error: {{message}}", + "terminal_title": "Serial Terminal", + "terminal_connecting": "Connecting...", + "terminal_help_button": "I'm having trouble, help?", + "terminal_back_to_modes": "Back to mode picker", + "terminal_mode_configure": "Configure Device", + "terminal_mode_configure_desc": "Configure WiFi, authentication, and more. Includes an interactive serial console.", + "terminal_mode_flash": "Flash Firmware", + "terminal_mode_flash_desc": "Install or update firmware on a connected device.", + "terminal_mode_raw": "Serial Monitor", + "terminal_mode_raw_desc": "Just the console. Read device logs and send commands.", + "terminal_step_channel": "Select Channel", + "terminal_step_board": "Select Board", + "terminal_go_to_step": "Go to step {{number}}: {{title}}", + "terminal_erase": "Erase before flashing", + "terminal_erase_desc": "Clears all data on the device including existing configs", + "terminal_unsupported": "Your browser does not support this feature.", + "terminal_update_browser": "Please update your browser to the latest version.", + "terminal_use_browsers": "Please use one of the following browsers:", + "terminal_connect_failed_bootloader": "Could not enter bootloader mode", + "terminal_connect_failed": "Device connection failed", + "terminal_connect_failed_desc": "We couldn't establish a serial connection with the device.", + "terminal_quick_tries": "Quick things to try:", + "terminal_try_replug": "Unplug and replug the device.", + "terminal_try_cable": "Try a different USB cable or port.", + "terminal_try_driver": "Make sure the serial driver is installed.", + "terminal_open_troubleshooter": "Open troubleshooter", + "terminal_log_reset_no_device": "Host-side error during reset: no device!", + "terminal_log_reset_error": "Host-side error during reset: {{error}}", + "terminal_log_send_no_device": "Couldn't send: no device!", + "terminal_log_send_error": "Couldn't send: {{error}}", + "terminal_log_firmware_disconnected": "Firmware disconnected: {{error}}", + "terminal_log_erase_failed": "Failed to erase flash: {{error}}", + "terminal_log_hard_reset_failed": "Failed to hard reset: {{error}}", + "terminal_log_flash_complete": "Flash complete", + "terminal_log_flash_failed": "Failed to flash: {{error}}", + "terminal_log_command_failed": "Failed to write application command: {{error}}", + "terminal_help_title": "Troubleshooter", + "terminal_help_desc": "Work through these steps in order. Each one rules out a common cause.", + "terminal_help_step_cable": "USB cable", + "terminal_help_step_port": "USB port", + "terminal_help_step_driver": "Install driver", + "terminal_help_step_manual": "Manual driver update", + "terminal_help_step_discord": "Ask on Discord", + "terminal_help_cable_body": "Many USB-C and micro-USB cables are charge-only and don't carry data. Swap to a known-good data cable (one you've used to transfer files or connect other devices) and reconnect the hub.", + "terminal_help_port_body": "Plug the device directly into a USB port on your computer. Avoid USB hubs, docking stations, and front-panel ports if possible; these are common sources of power and signal issues. If you're on a desktop, try a port on the back of the machine.", + "terminal_help_driver_download": "Download the CP210x driver:", + "terminal_help_driver_extract": "Extract the contents of the zip file to a folder on your computer.", + "terminal_help_driver_run": "Open the folder and run {{installer}}. Follow the prompts to install.", + "terminal_help_driver_reconnect": "Reconnect the device.", + "terminal_help_manual_intro": "If the driver installer ran but the device still doesn't show up:", + "terminal_help_manual_open": "Open Device Manager (press Win + X and select Device Manager).", + "terminal_help_manual_ports": "Under Ports (COM & LPT), look for an entry like:", + "terminal_help_manual_missing": "If it's missing, the device isn't being detected by Windows at all; revisit the cable and port steps.", + "terminal_help_manual_update": "Right-click the device and pick Update Driver.", + "terminal_help_manual_browse": "Choose Browse my computer for drivers and select the folder you extracted the driver zip into. Make sure Include subfolders is checked.", + "terminal_help_manual_success": "On success, the entry should now read {{deviceName}}.", + "terminal_help_discord_intro": "Still stuck after all of the above? Hop into our Discord server and ask in the {{channel}} channel. Please include:", + "terminal_help_discord_os": "your operating system and browser", + "terminal_help_discord_device": "the device you're using (board model, where you got it)", + "terminal_help_discord_tried": "what you've already tried from the previous steps", + "terminal_help_discord_errors": "any error messages or relevant terminal output", + "terminal_help_discord_join": "Join our Discord server", + "terminal_risk_title": "⚠️ UNSTABLE FIRMWARE", + "terminal_risk_intro": "You are about to flash experimental firmware that is known to be unstable.", + "terminal_risk_brick": "This may permanently brick your device, require manual recovery, or render it unusable.", + "terminal_risk_no_support": "We will NOT provide support for issues caused by this firmware.", + "terminal_risk_acknowledge": "I understand this is entirely my responsibility", + "terminal_risk_abort": "Abort", + "terminal_risk_accept": "I ACCEPT FULL RESPONSIBILITY", + "firmware_channel_recommended": "This is the recommended channel.", + "firmware_channel_danger": "DO NOT USE THIS UNLESS YOU KNOW WHAT YOU ARE DOING", + "firmware_channel_stable": "Stable", + "firmware_channel_beta": "Beta", + "firmware_channel_develop": "Develop", + "terminal_board_select": "Select a board...", + "terminal_board_search": "Search boards...", + "terminal_board_none": "No board found.", + "terminal_flash_button": "Flash", + "terminal_flash_progress": "Flash Progress: {{status}}", + "terminal_flash_idle": "Idle", + "terminal_flash_no_device": "No device selected.", + "terminal_flash_resetting": "Resetting...", + "terminal_flash_downloading": "Downloading firmware...", + "terminal_flash_download_failed": "Failed to download firmware.", + "terminal_flash_flashing": "Flashing firmware...", + "terminal_flash_rebooting": "Rebooting device... (Reconnect to power manually if stuck)", + "terminal_flash_done": "Rebooted device! Flashing complete.", + "terminal_port_select": "Select Device", + "terminal_port_disconnect": "Disconnect Device", + "terminal_port_connected": "Device connected: {{id}}", + "terminal_console": "Console", + "terminal_connected_device": "Connected device", + "terminal_resize": "Resize terminal panel", + "terminal_reboot": "Reboot", + "terminal_disconnect": "Disconnect", + "terminal_fullscreen_exit_esc": "Exit fullscreen (Esc)", + "terminal_fullscreen_exit": "Exit fullscreen", + "terminal_fullscreen_fill": "Fill the window", + "terminal_command_label": "Serial command", + "terminal_command_placeholder": "Type a command...", + "terminal_command_send": "Send command", + "terminal_colors": "Colors", + "terminal_colors_menu": "Colors...", + "terminal_colors_label": "Console colors", + "terminal_colors_close": "Close colors", + "terminal_color_input": "{{name}} color", + "terminal_colors_reset": "Reset to defaults", + "terminal_color_bg": "Background", + "terminal_color_fg": "Text", + "terminal_color_ts": "Timestamp", + "terminal_color_error": "Error", + "terminal_color_warning": "Warning", + "terminal_color_info": "Info", + "terminal_color_debug": "Debug", + "terminal_color_verbose": "Verbose", + "terminal_options": "Options", + "terminal_options_label": "Console options", + "terminal_hide_system": "Hide system messages", + "terminal_stick_bottom": "Stick to bottom", + "terminal_raw_output": "Raw output", + "terminal_timestamps": "Timestamps", + "terminal_timestamp_uptime": "Uptime", + "terminal_timestamp_local": "Local", + "terminal_timestamp_ms": "Ms", + "terminal_timestamp_off": "Off", + "terminal_copy_settings": "Copy settings", + "terminal_import_settings": "Import settings", + "terminal_copy_selection": "Copy selection", + "terminal_copy_all": "Copy all output", + "terminal_toast_selection_copied": "Selection copied", + "terminal_toast_output_copied": "Console output copied", + "terminal_toast_settings_copied": "Console settings copied", + "terminal_toast_clipboard_unreadable": "Could not read the clipboard", + "terminal_toast_settings_imported": "Console settings imported", + "terminal_toast_settings_invalid": "Clipboard does not contain console settings", + "common_try_again": "Try again", + "terminal_cfg_intro": "Values are sent to the device via UART. Read the device's response in the console below. Commands without an argument act as getters; use the button next to each field to read the current value.", + "terminal_cfg_rf_title": "RF Transmitter", + "terminal_cfg_rf_desc": "Controls the shocker RF output.", + "terminal_cfg_tx_pin": "TX GPIO pin", + "terminal_cfg_example": "e.g. {{value}}", + "terminal_cfg_read_value": "Read current value", + "terminal_cfg_set": "Set", + "terminal_cfg_read": "Read", + "terminal_cfg_reading": "Reading…", + "terminal_cfg_apply": "Apply", + "terminal_cfg_keepalive": "Keepalive enabled", + "terminal_cfg_keepalive_desc": "Periodically pings paired shockers to keep them awake.", + "terminal_cfg_estop_title": "Emergency Stop", + "terminal_cfg_estop_desc": "Hardware button that halts all output.", + "terminal_cfg_estop_enabled": "EStop enabled", + "terminal_cfg_estop_pin": "EStop GPIO pin", + "terminal_cfg_estop_note": "Note: {{latching}} and {{active}} have no dedicated commands; set them via the JSON config below.", + "terminal_cfg_wifi_title": "WiFi", + "terminal_cfg_wifi_desc": "Station credentials and device hostname.", + "terminal_cfg_hostname": "Hostname", + "terminal_cfg_networks": "Networks (JSON array)", + "terminal_cfg_invalid_json_array": "Must be a valid JSON array", + "terminal_cfg_ap_note": "AP settings ({{ssid}}, {{password}}, {{disabled}}, {{staDisabled}}, {{offlineMode}}) have no dedicated commands; use the JSON config.", + "terminal_cfg_backend_title": "Backend", + "terminal_cfg_backend_desc": "OpenShock server and authentication.", + "terminal_cfg_domain": "Domain", + "terminal_cfg_domain_restart": "Setting the domain will restart the device.", + "terminal_cfg_auth_token": "Auth token", + "terminal_cfg_auth_token_placeholder": "Paste device token", + "terminal_cfg_hide": "Hide", + "terminal_cfg_show": "Show", + "terminal_cfg_serial_title": "Serial Input", + "terminal_cfg_echo": "Echo enabled", + "terminal_cfg_echo_desc": "Print typed characters back to the console.", + "terminal_cfg_advanced_title": "Advanced: full config", + "terminal_cfg_advanced_desc": "For fields without dedicated commands (captive portal, OTA, LAN, etc.), replace the entire config.", + "terminal_cfg_json_config": "JSON config", + "terminal_cfg_invalid_json": "Must be valid JSON", + "terminal_cfg_read_json": "Read current config as JSON", + "terminal_cfg_json_restart": "Applying a JSON config will restart the device.", + "terminal_cfg_raw_config": "Raw FlatBuffer config (base64)", + "terminal_cfg_invalid_base64": "Must be a valid base64 string", + "terminal_cfg_read_raw": "Read current config as base64", + "terminal_cfg_factory_reset": "Factory reset", + "terminal_cfg_factory_reset_desc": "Wipes the entire device configuration.", + "terminal_cfg_factory_reset_title": "Factory reset device?", + "terminal_cfg_factory_reset_action": "Wipe config", + "terminal_cfg_factory_reset_confirm": "This will erase all configuration on the device; WiFi networks, backend credentials, pins, and all other settings. The device will be reset to defaults.", + "terminal_cfg_read_failed_json_title": "Couldn't read the JSON config", + "terminal_cfg_read_failed_raw_title": "Couldn't read the raw config", + "terminal_cfg_read_failed_desc": "The device didn't respond after {{attempts}} attempts.", + "terminal_cfg_common_causes": "Common causes:", + "terminal_cfg_cause_busy": "The device is busy handling another command.", + "terminal_cfg_cause_disconnected": "The device disconnected or rebooted.", + "terminal_cfg_cause_unsupported": "The firmware version doesn't support this command.", + "common_status": "Status", + "common_version": "Version", + "common_created": "Created", + "common_create": "Create", + "common_done": "Done", + "common_enable": "Enable", + "common_disable": "Disable", + "common_are_you_sure": "Are you sure?", + "common_generating": "Generating...", + "hubs_title": "Hubs", + "hubs_subtitle": "Every hub registered to your account.", + "hubs_add": "Add Hub", + "hubs_load_failed": "Failed to load hubs.", + "hubs_empty_title": "No hubs yet", + "hubs_empty_desc": "A hub is the device that relays commands to your shockers. Add one to get started.", + "hubs_create_title": "Create hub", + "hubs_name_label": "Hub Name", + "hubs_name_placeholder": "My Hub", + "hub_toast_not_connected": "Not connected to the server", + "hub_toast_try_later": "Try again in a moment.", + "hub_reboot_title": "Reboot {{name}}?", + "hub_reboot_desc": "The hub will disconnect and restart. Any shockers paired to it stop responding until it comes back online.", + "hub_reboot": "Reboot", + "hub_hotspot_enable_title": "Enable Wi-Fi hotspot on {{name}}?", + "hub_hotspot_disable_title": "Disable Wi-Fi hotspot on {{name}}?", + "hub_hotspot_enable_desc": "The hub broadcasts its own setup network. It stays reachable on your Wi-Fi, but the hotspot is open to anyone in range until you turn it off.", + "hub_hotspot_disable_desc": "The setup hotspot shuts down. If the hub is not already on your Wi-Fi you will need physical access to set it up again.", + "hub_delete_desc": "You are about to delete hub {{name}}.", + "hub_delete_shockers": "This will also delete the following shockers:", + "hub_edit_title": "Edit hub", + "hub_edit_apply": "Apply", + "hub_pair_title_generate": "Generate pair code?", + "hub_pair_title_generated": "Pair code generated", + "hub_pair_title_paired": "Hub paired", + "hub_pair_consumed": "{{name}} consumed this pair code and is now paired.", + "hub_pair_used": "The code has been used and is no longer valid.", + "hub_pair_generated_for": "Pair code generated for {{name}}.", + "hub_copy_now": "The code below will not be accessible later, please copy it now and update clients with it.", + "hub_pair_generate_for": "You are about to generate a pair code for {{name}}.", + "hub_pair_valid_for": "It will be valid for 15 minutes after its creation.", + "hub_pair_one_active": "There is only one active pair code per hub, newly generated ones will override the older active ones.", + "hub_pair_complete": "Pairing complete", + "hub_pair_code_label": "Pair code:", + "hub_pair_copied_close": "Code has been copied, close", + "hub_pair_get": "Get Pair Code", + "hub_token_generated": "Token generated", + "hub_token_generated_for": "New token generated for {{name}}.", + "hub_token_regenerate_for": "You are about to regenerate the token for {{name}}.", + "hub_token_invalidate": "This action will invalidate the current token and disconnect clients using it.", + "hub_token_confirm": "Are you sure you want to do this?", + "hub_token_label": "New token:", + "hub_token_copied_close": "Token has been copied, close", + "hub_token_regenerate": "Regenerate Token", + "hub_menu_update": "Update", + "hub_menu_label": "Hub", + "hub_menu_hotspot_enable": "Enable Wi-Fi hotspot", + "hub_menu_hotspot_disable": "Disable Wi-Fi hotspot", + "hub_menu_pair": "Pair", + "hub_menu_estop": "Emergency Stop", + "hub_update_breadcrumb": "Update", + "hub_update_unknown_hub": "Unknown Hub", + "hub_update_unknown_task": "Unknown Task", + "hub_update_task_metadata": "Fetching Metadata", + "hub_update_task_preparing": "Preparing for Update", + "hub_update_task_flash_fs": "Flashing Filesystem", + "hub_update_task_verify_fs": "Verifying Filesystem", + "hub_update_task_flash_app": "Flashing Application", + "hub_update_task_bootable": "Marking Application Bootable", + "hub_update_task_rebooting": "Rebooting", + "hub_update_status_started": "Started", + "hub_update_status_running": "Running", + "hub_update_status_finished": "Finished", + "hub_update_status_error": "Error", + "hub_update_status_timeout": "Timeout", + "hub_update_confirm_title": "Confirm firmware update", + "hub_update_confirm_desc": "Update {{name}} to version {{version}}?", + "hub_update_unstable_warning": "This version may not be from the stable channel and could contain bugs.", + "hub_update_title": "Update {{name}}", + "hub_update_subtitle": "Manage firmware updates for this hub.", + "hub_update_status_title": "Hub Status", + "hub_update_firmware": "Firmware: {{version}}", + "hub_update_confirm": "Update", + "hub_update_success": "Update completed successfully", + "hub_update_rolled_back": "Device rolled back to previous version", + "hub_update_back": "Back to Hubs", + "hub_update_flash_again": "Flash Again", + "hub_update_card_title": "Firmware Update", + "hub_update_card_desc": "Select a firmware channel and version to install.", + "hub_update_to": "Update to {{version}}", + "hub_update_must_be_online": "Hub must be online to start an update.", + "hub_update_updating_to": "Updating to {{version}}...", + "hub_update_total": "Total", + "hub_update_task": "Task", + "hub_update_history": "Update History", + "hub_update_no_history": "No update history found for this hub.", + "hub_update_col_id": "ID", + "hub_update_col_started": "Started", + "hub_update_col_message": "Message", + "hub_update_loading": "Loading hub information...", + "hub_update_not_found": "Hub not found.", + "home_breadcrumb": "Home", + "home_welcome": "Welcome back", + "home_welcome_name": "Welcome back, {{name}}", + "home_subtitle": "Here's an overview of your OpenShock setup.", + "home_hubs_online": "{{count}} online", + "home_hub_status": "Hub Status", + "home_no_hubs": "No hubs", + "home_all_online": "All online", + "home_all_offline": "All offline", + "home_some_online": "{{online}}/{{total}} online", + "home_quick_links": "Quick Links", + "home_my_shockers": "My Shockers", + "home_my_shockers_desc": "Control your shockers", + "home_hubs_desc": "Manage your hubs", + "home_shared_desc": "Shockers shared with you", + "home_public_desc": "Manage share links", + "home_get_started": "Get Started", + "home_get_started_desc": "You don't have any hubs yet. Create a hub to connect your first device, then add shockers to it.", + "home_set_up_hub": "Set Up a Hub", + "home_first_shocker": "Add Your First Shocker", + "home_first_shocker_desc_one": "You have {{count}} hub set up. Add a shocker to start controlling it.", + "home_first_shocker_desc_other": "You have {{count}} hubs set up. Add a shocker to start controlling it.", + "home_go_to_shockers": "Go to Shockers", + "profile_title": "Profile", + "profile_coming_soon": "Profile is coming soon", + "profile_coming_soon_desc": "Your public profile is not available yet. Account details live under Settings.", + "common_retry": "Retry", + "common_never_used": "Never used", + "common_expires": "Expires {{time}}", + "common_search_placeholder": "Search...", + "common_unknown": "Unknown", + "settings_breadcrumb_account": "Account", + "account_subtitle": "Your sign-in details and account actions.", + "account_change_username": "Change Username", + "account_change_email": "Change Email", + "account_change_password": "Change Password", + "account_username_label": "Username", + "account_email_label": "Email", + "account_password_label": "Password", + "account_new_password_label": "New Password", + "account_confirm_password_label": "Confirm New Password", + "account_oauth_only": "Not available for OAuth-only accounts", + "account_oauth_no_password": "This account signs in via OAuth and has no password.", + "account_diagnostics": "Diagnostics", + "account_diagnostics_desc": "Help us fix crashes and slow API calls. Reports include the error message, stack trace and your IP. Off by default.", + "account_diagnostics_level": "Diagnostics level", + "account_telemetry_off": "Off", + "account_telemetry_off_desc": "Send nothing.", + "account_telemetry_errors": "Errors", + "account_telemetry_errors_desc": "Send browser error reports only.", + "account_telemetry_full": "Full", + "account_telemetry_full_desc": "Error reports plus traces of API calls (no page navigations).", + "account_toast_deactivated": "Account deactivated successfully", + "account_deactivate_title": "Deactivate account", + "account_deactivate_desc": "Are you sure you want to deactivate your account?", + "account_deactivate": "Deactivate Account", + "account_email_title": "Change email", + "account_email_desc": "Enter your new email address and confirm with your current password.", + "account_email_toast_sent": "Verification email sent to {{email}}. Click the link in that email to apply the change.", + "account_new_email": "New Email", + "account_current_password": "Current Password", + "account_password_title": "Change password", + "account_password_desc": "Enter your current password and choose a new one.", + "account_password_toast": "Password has been changed", + "account_username_title": "Change username", + "account_username_desc": "Enter a new username.", + "account_new_username": "New Username", + "account_username_toast": "Username changed successfully", + "tokens_subtitle": "API Tokens are used to authenticate with the OpenShock API.", + "tokens_generate": "Generate Token", + "tokens_toast_refreshed": "Tokens refreshed successfully", + "tokens_empty_title": "No API tokens", + "tokens_empty_desc": "Generate a token to authenticate with the OpenShock API.", + "tokens_created_on": "Created {{date}}", + "tokens_last_used": "Last used {{time}}", + "tokens_never_expires": "Never expires", + "tokens_load_failed": "Failed to load API tokens.", + "token_toast_edited": "Token edited successfully", + "token_name_required": "Name is required", + "token_name_too_long": "Name is too long", + "token_edit_title": "Edit API token", + "token_name_label": "Token Name", + "token_name_placeholder": "Token name...", + "token_permissions": "Permissions", + "token_perm_category_shockers": "Shockers", + "token_perm_category_devices": "Hubs", + "token_perm_category_usershares": "User Shares", + "token_perm_category_publicshares": "Public Shares", + "token_perm_use": "Use", + "token_perm_edit": "Edit", + "token_perm_pause": "Pause", + "token_perm_auth": "Authenticate", + "token_shocker_control": "Shocker Control", + "token_toast_paused": "Token paused", + "token_toast_resumed": "Token resumed", + "token_delete_title": "Delete API token", + "token_delete_desc": "Are you sure you want to delete {{name}}?", + "token_delete_permanent": "This action cannot be undone. This will permanently delete the token.", + "token_toast_deleted": "Token deleted successfully", + "token_resume": "Resume token", + "token_pause": "Pause token", + "token_mode_clamp_desc": "Clamp: requests outside the allowed range are capped to the nearest limit (the min or the max).", + "token_mode_lerp_desc": "Lerp: the full input range is linearly rescaled so it fits within your allowed min–max range.", + "token_paused_desc": "A paused token may not send shocker control messages.", + "token_intensity_range": "Intensity range", + "token_duration_range": "Duration range", + "token_new_breadcrumb": "New", + "token_redirect_not_allowed": "The provided redirect_uri is not allowed. Only loopback addresses or custom application schemes are permitted.", + "token_params_missing": "Required get parameters are missing. Make sure name, redirect_uri, and permissions are provided.", + "token_invalid_permissions": "Invalid permissions provided: {{list}}", + "token_toast_created": "Token created successfully", + "token_request_title": "API Token Request", + "token_access_granted": "Access granted", + "token_shared_redirecting": "The token has been created and shared with the application. Redirecting you back to {{uri}}.", + "token_not_redirected": "If you are not redirected automatically, use the button below.", + "token_finish": "Finish", + "token_generated_title": "API Token Generated", + "token_copy_now": "Please copy your API Token now, you will not be able to view it again later!", + "token_new_title": "New API Token", + "token_external_desc": "An external application is requesting access to your account. Review and adjust the permissions below before allowing access.", + "token_new_desc": "Configure and generate a new API token for your account.", + "token_external_requesting": "{{name}} is requesting an API Token. Your token will be shared with the application at {{uri}}.", + "token_allow": "Allow", + "token_generate": "Generate", + "token_deny": "Deny", + "sessions_subtitle": "Every active session on your account. Revoke any you do not recognize.", + "sessions_unknown_device": "Unknown device", + "sessions_toast_refreshed": "Sessions refreshed successfully", + "sessions_load_failed": "Failed to load sessions.", + "sessions_empty_title": "No active sessions", + "sessions_empty_desc": "Sessions appear here once you sign in from a browser or app.", + "sessions_last_seen": "Last seen {{time}}", + "sessions_signed_in": "Signed in {{time}}", + "session_toast_revoked": "Session revoked successfully", + "session_revoke_title": "Revoke session", + "session_revoke": "Revoke", + "session_revoke_desc": "Are you sure you want to revoke this session?", + "session_revoke_from": "Session logged in from {{ip}} using {{agent}}", + "connections_title": "OAuth Connections", + "connections_subtitle": "Link or unlink third-party accounts to sign in faster and keep your profile in sync.", + "connections_toast_linked": "Account linked.", + "connections_toast_cancelled": "Link flow cancelled.", + "connections_toast_failed": "Linking failed.", + "connections_toast_removed": "Connection removed", + "connections_refreshing": "Refreshing…", + "connections_link_new": "Link new provider", + "connections_empty_title": "No connections yet", + "connections_empty_desc": "Choose “Link new provider” above to connect available providers.", + "connections_unlink": "Unlink", + "connections_load_failed": "Failed to load OAuth connections.", + "connections_unlink_title": "Unlink {{name}}?", + "connections_unlink_title_generic": "Unlink this account?", + "connections_unlink_desc": "You'll no longer be able to sign in with this provider unless you link it again.", + "provider_starting": "Starting {{name}}...", + "provider_link": "Link {{name}}", + "audit_subtitle": "Security-relevant activity on your account. Review anything you do not recognize.", + "audit_col_time": "Time", + "audit_col_action": "Action", + "audit_col_details": "Details", + "audit_col_reason": "Reason", + "audit_col_ip": "IP address", + "audit_col_device": "Device", + "audit_action_login": "Signed in", + "audit_action_logout": "Signed out", + "audit_action_password_changed": "Password changed", + "audit_action_email_change_requested": "Email change requested", + "audit_action_email_changed": "Email changed", + "audit_action_username_changed": "Username changed", + "audit_action_api_token_created": "API token created", + "audit_action_api_token_deleted": "API token deleted", + "audit_action_oauth_connected": "Connection added", + "audit_action_oauth_disconnected": "Connection removed", + "audit_action_account_deactivated": "Account deactivated", + "audit_action_account_reactivated": "Account reactivated", + "audit_action_account_deleted": "Account deleted", + "audit_action_automation_token_created": "Automation token created", + "audit_action_automation_token_updated": "Automation token updated", + "audit_action_automation_token_rotated": "Automation token rotated", + "audit_action_automation_token_deleted": "Automation token deleted", + "audit_action_automation_token_used": "Automation token used", + "audit_meta_session": "Session {{id}}", + "audit_meta_changed": "{{old}} to {{new}}", + "audit_meta_email_requested": "Requested change to {{email}}", + "audit_meta_accounts_removed_one": "{{name}} ({{count}} account removed)", + "audit_meta_accounts_removed_other": "{{name}} ({{count}} accounts removed)", + "audit_meta_scheduled_deletion": "Scheduled for deletion", + "audit_meta_kept": "Kept for reactivation", + "common_view": "View", + "common_save": "Save", + "common_saving": "Saving...", + "common_back": "Back", + "common_shared_by": "Shared by", + "common_user_avatar": "User Avatar", + "common_toast_saved": "Changes saved successfully", + "pause_reason_shocker": "Paused at shocker level", + "pause_reason_shocker_user_share": "Paused at shocker and user share level", + "pause_reason_shocker_public_share": "Paused at shocker and public share level", + "pause_reason_user_share": "Paused at user share level", + "pause_reason_public_share": "Paused at public share level", + "public_shares_subtitle": "A link anyone can use, no account required.", + "public_shares_new": "New Share", + "public_share_never_expires": "Never expires", + "public_shares_empty_title": "No public shares yet", + "public_shares_empty_desc": "Create a link that anyone can use to control your shockers.", + "public_share_expired": "Expired", + "public_share_no_expiry": "No expiry", + "public_share_label": "Public Share", + "public_share_toast_created": "Created new public share", + "public_share_create_title": "Create public share", + "public_share_toast_deleted": "Deleted public share", + "public_share_delete_title": "Delete public share", + "public_share_delete_desc": "Are you sure you want to delete public share {{name}}?", + "public_share_edit_title": "Public Share: {{name}}", + "public_share_edit_subtitle": "Editing: changes apply when you save.", + "public_share_add_shocker": "Add Shocker", + "public_share_toast_added_one": "Added {{count}} shocker to share", + "public_share_toast_added_other": "Added {{count}} shockers to share", + "public_share_empty_shockers_title": "No shockers in this share", + "public_share_empty_shockers_desc": "Add a shocker and anyone with the link will be able to control it.", + "public_share_load_failed": "Error fetching public share details", + "public_share_paused_here": "Paused for this share", + "public_share_resume_shocker": "Resume shocker", + "public_share_pause_shocker": "Pause shocker", + "public_share_remove": "Remove from share", + "public_share_toast_removed": "Shocker removed from share", + "public_share_add_title": "Add shockers", + "public_share_add_desc": "Add shockers to this public share. You can set their limits once they are added.", + "public_share_add_placeholder": "Select shockers to share...", + "public_share_add_no_match": "No matching shockers", + "public_share_add_submit": "Add Shockers", + "public_share_view_loading": "Loading share details...", + "public_share_view_title": "Public Share Link", + "public_share_view_desc": "Enter as a guest or login with your OpenShock account", + "public_share_view_guest_name": "Guest Name", + "public_share_view_enter": "Enter", + "public_share_view_enter_guest": "Enter as Guest", + "public_share_login": "Login", + "perm_shock_on": "Shock enabled", + "perm_shock_off": "Shock disabled", + "perm_vibrate_on": "Vibrate enabled", + "perm_vibrate_off": "Vibrate disabled", + "perm_sound_on": "Sound enabled", + "perm_sound_off": "Sound disabled", + "perm_live_on": "Live enabled", + "perm_live_off": "Live disabled", + "perm_live_control": "Live Control", + "user_selector_avatar_of": "{{name}}'s avatar", + "user_selector_placeholder": "Enter user name", + "user_selector_aria": "Username to search", + "user_selector_search": "Search user", + "user_selector_found": "User found", + "common_remove": "Remove", + "user_shares_subtitle": "Direct permanent shares with other users.", + "user_shares_toast_invited": "Sent a shocker invite to {{name}}", + "user_shares_redeem": "Redeem Code", + "user_shares_new": "New Share", + "user_shares_tab_shares": "Shares", + "user_shares_tab_incoming": "Shared with Me", + "user_shares_tab_invites": "Invites", + "share_code_create_title": "New share code", + "share_code_create_desc": "Create a Share Code or Invite", + "share_code_shocker_placeholder": "Select shockers to share...", + "share_code_no_match": "No matching shockers", + "share_code_send_invite": "Send Share Invite", + "share_code_create": "Create Share Code", + "share_code_created_title": "Share code generated", + "share_code_created_desc": "Please copy share code or code link!", + "share_code_redeem_title": "Redeem share code", + "share_code_redeem_desc": "Enter the share code to redeem", + "share_code_redeem_placeholder": "Enter share code", + "share_code_redeemed": "Redeemed successfully!", + "share_code_shared_shockers": "Shared shockers", + "share_code_redeeming": "Redeeming...", + "share_code_redeem": "Redeem", + "incoming_shares_empty_title": "Nothing shared with you", + "incoming_shares_empty_desc": "No one has shared a shocker with you yet.", + "incoming_share_toast_removed": "Removed share for {{name}}", + "incoming_share_remove_title": "Remove Share", + "incoming_share_remove_desc": "Are you sure you want to remove the share for {{name}}?", + "incoming_share_toast_removed_shocker": "Removed {{shocker}} shared by {{name}}", + "incoming_share_remove_shocker_title": "Remove this shared shocker?", + "incoming_share_remove_shocker_desc": "Are you sure you want to remove the shocker share {{shocker}} by {{name}}?", + "incoming_share_manage_from": "Manage shares from", + "share_remove": "Remove share", + "invites_empty_title": "No invites yet", + "invites_empty_desc": "You have no incoming or outgoing share invites.", + "invites_outgoing": "Outgoing", + "invites_outgoing_empty_title": "No outgoing invites", + "invites_outgoing_empty_desc": "You have no outgoing share invites.", + "invites_incoming": "Incoming", + "invites_incoming_empty_title": "No incoming invites", + "invites_incoming_empty_desc": "You have no incoming share invites.", + "invite_toast_accepted": "Accepted share invite from {{name}}", + "invite_toast_declined": "Declined share invite from {{name}}", + "invite_deny_title": "Deny Invite", + "invite_deny_label": "Deny Invite", + "invite_deny": "Deny", + "invite_deny_desc": "Are you sure you want to deny the invite from {{name}}?", + "invite_accept": "Accept Invite", + "invite_toast_cancelled_for": "Cancelled invite for {{name}} ({{id}})", + "invite_toast_cancelled": "Cancelled invite {{id}}", + "invite_cancel_title": "Cancel Invite", + "invite_cancel": "Cancel", + "invite_cancel_for_desc": "Are you sure you want to cancel the invite for {{name}}?", + "invite_cancel_code_desc": "Are you sure you want to cancel the invite with code {{code}}?", + "invite_cancel_outstanding": "Cancel Outstanding Invite", + "outgoing_shares_empty_title": "No shared shockers", + "outgoing_shares_empty_desc": "You haven't shared any shockers with other users yet.", + "outgoing_share_toast_removed": "Removed shocker share {{name}}", + "outgoing_share_remove_title": "Stop sharing this shocker?", + "outgoing_share_editing_for": "Editing shares for", + "outgoing_share_limits": "Limits & Permissions", + "outgoing_share_same": "Same restrictions on every shocker", + "outgoing_share_per_desc": "Tune restrictions per shocker", + "outgoing_share_all": "All", + "outgoing_share_per": "Per shocker", + "outgoing_share_remove_desc": "Are you sure you want to stop sharing {{shocker}} with {{name}}?", + "report_breadcrumb": "Report API Tokens", + "report_toast_clipboard_failed": "Failed to read clipboard: {{error}}", + "report_title": "Report Leaked API Tokens", + "report_paste": "Paste from clipboard", + "report_warning": "This form is only for reporting accidentally leaked API tokens.", + "report_abuse_warning": "Intentional abuse will result in bans or severe endpoint restrictions.", + "report_detected": "Detected Tokens", + "report_invalid": "One or more tokens appear to be invalid. Please check for formatting issues.", + "report_acknowledge": "I confirm I understand what this feature is for and accept responsibility.", + "report_submit": "Submit Report", + "turnstile_disabled": "Turnstile disabled", + "common_internal_error": "Internal error", + "resend_toast_sent": "Activation email sent. Check your inbox and spam folder.", + "resend_toast_throttled": "Too many activation emails have been requested. Please try again later.", + "resend_toast_unavailable": "No activation email can be resent from this browser. If your account isn't activated yet, logging in sends a new link.", + "resend_button": "Didn't get the email? Resend", + "expiration_label": "Expiration", + "expiration_never": "Never", + "expiration_custom": "Custom", + "expiration_days_one": "{{count}} Day", + "expiration_days_other": "{{count}} Days", + "expiration_required": "Expire date is required", + "expiration_never_desc": "This will never expire", + "expiration_expires_at": "Expires {{time}} ({{date}})", + "date_picker_placeholder": "Pick a date", + "telemetry_toast_title": "Help improve OpenShock?", + "telemetry_toast_desc": "Send diagnostics to help us fix crashes and slow API calls. Reports include the error message, stack trace and your IP. You can change this any time in Account settings.", + "telemetry_toast_no": "No thanks", + "telemetry_toast_errors": "Errors only", + "telemetry_toast_full": "Full", + "table_show_details": "Show details", + "table_hide_details": "Hide details", + "table_no_results": "No results.", + "table_sort_asc": "Sort by {{name}}, ascending", + "table_sort_desc": "Sort by {{name}}, descending", + "table_sort_none": "Sort by {{name}}, unsorted", + "cell_na": "N/A", + "cell_not_applicable": "Not applicable", + "cell_invalid": "Invalid", + "cell_unavailable": "Unavailable", + "cell_none": "None", + "oauth_login_with": "Login with {{provider}}", + "oauth_signup_with": "Signup with {{provider}}", + "signalr_connect_failed": "Failed to connect to server!", + "signalr_disconnect_failed": "Encountered error while disconnecting from server!", + "signalr_invalid_update": "Received invalid update from server!", + "signalr_invalid_log": "Received invalid log data from server!", + "signalr_invalid_ota": "Received invalid firmware update data from server!", + "ota_toast_failed": "Hub firmware update failed: {{message}}", + "ota_toast_succeeded": "Hub firmware update completed successfully!", + "ota_toast_rolled_back": "Hub firmware rolled back to previous version", + "lcg_connect_failed": "Failed to connect to live control gateway", + "terminal_toast_bootloader_failed": "Failed to enter bootloader: {{error}}", + "terminal_toast_app_mode_failed": "Failed to enter application mode: {{error}}", + "problem_account_account_not_activated_title": "Account not activated", + "problem_account_account_not_activated_desc": "Check your inbox for the activation email.", + "problem_account_activation_not_found_title": "Activation link is invalid", + "problem_account_activation_not_found_desc": "The link may have expired or already been used.", + "problem_account_activation_resend_too_many_title": "Too many activation emails requested", + "problem_account_activation_resend_too_many_desc": "Please wait a while before trying again.", + "problem_account_activation_resend_unavailable_title": "Cannot resend activation email", + "problem_account_activation_resend_unavailable_desc": "Log in again to request a new activation link.", + "problem_account_deactivate_already_deactivated_title": "Account is already deactivated", + "problem_account_deactivate_denied_privileged_title": "Privileged accounts cannot be deactivated", + "problem_account_deactivate_unauthorized_title": "You are not allowed to do this", + "problem_account_deactivated_title": "This account has been deactivated", + "problem_account_email_already_in_use_title": "That email address is already in use", + "problem_account_email_invalid_title": "That email address is not valid", + "problem_account_email_taken_title": "That email address is already in use", + "problem_account_email_too_many_requests_title": "Too many email change requests", + "problem_account_email_too_many_requests_desc": "Please wait a while before trying again.", + "problem_account_email_unchanged_title": "That is already your email address", + "problem_account_email_verify_not_found_title": "Verification link is invalid", + "problem_account_email_verify_not_found_desc": "The link may have expired or already been used.", + "problem_account_o_auth_only_title": "This account has no password", + "problem_account_o_auth_only_desc": "Sign in with the provider you signed up with.", + "problem_account_password_not_set_title": "No password set", + "problem_account_password_not_set_desc": "This account signs in through an external provider.", + "problem_account_password_old_password_invalid_title": "Current password is incorrect", + "problem_account_username_invalid_title": "That username is not allowed", + "problem_account_username_recently_changed_title": "Username changed too recently", + "problem_account_username_recently_changed_desc": "You can change your username once every 7 days.", + "problem_account_username_taken_title": "That username is already taken", + "problem_admin_user_deactivated_title": "This user is deactivated", + "problem_admin_user_not_activated_title": "This user has not been activated yet", + "problem_api_token_can_only_delete_self_title": "An API token can only delete itself", + "problem_api_token_not_found_title": "API token not found", + "problem_api_token_paused_title": "This API token is paused", + "problem_assign_lcg_bad_schema_version_title": "Unsupported hub protocol version", + "problem_assign_lcg_bad_schema_version_desc": "Update the hub firmware to connect.", + "problem_assign_lcg_no_lcg_available_title": "No gateway available", + "problem_assign_lcg_no_lcg_available_desc": "No live control gateway is available right now. Please try again later.", + "problem_authentication_account_deactivated_title": "This account has been deactivated", + "problem_authentication_account_not_activated_title": "This account has not been activated", + "problem_authentication_cookie_missing_or_invalid_title": "You are not logged in", + "problem_authentication_cookie_missing_or_invalid_desc": "Your session may have expired. Please log in again.", + "problem_authentication_header_missing_or_invalid_title": "Invalid API token", + "problem_authentication_session_invalid_title": "Session expired", + "problem_authentication_session_invalid_desc": "Please log in again.", + "problem_authentication_token_invalid_title": "Invalid API token", + "problem_authentication_unknown_error_title": "Authentication failed", + "problem_authorization_policy_not_met_title": "You do not have permission to do this", + "problem_authorization_token_only_title": "This action requires an API token", + "problem_authorization_token_permission_missing_title": "This API token is missing a required permission", + "problem_authorization_unknown_error_title": "Authorization failed", + "problem_authorization_user_session_only_title": "This action requires a logged-in session", + "problem_automation_token_not_allowed_for_account_title": "Automation tokens cannot be used with privileged accounts", + "problem_configuration_already_exists_title": "A configuration entry with that name already exists", + "problem_configuration_invalid_name_format_title": "Invalid configuration name", + "problem_configuration_invalid_name_format_desc": "Only A to Z and underscores are allowed.", + "problem_configuration_invalid_value_format_title": "Value does not match the configuration type", + "problem_configuration_not_found_title": "Configuration entry not found", + "problem_control_stats_invalid_range_title": "The from date must not be after the to date", + "problem_control_stats_invalid_time_zone_title": "Unknown time zone", + "problem_control_stats_missing_capability_title": "Control statistics are not available on this server", + "problem_device_not_found_title": "Hub not found", + "problem_device_not_online_title": "Hub is offline", + "problem_device_too_many_hubs_title": "You have reached the maximum number of hubs", + "problem_device_too_many_shockers_title": "This hub has reached its maximum number of shockers", + "problem_endpoint_retired_title": "This feature is no longer available", + "problem_expression_error_title": "Invalid filter expression", + "problem_internal_server_error_title": "Something went wrong on our end", + "problem_login_invalid_credentials_title": "Invalid username or password", + "problem_login_invalid_domain_title": "Logging in from this address is not allowed", + "problem_o_auth_connection_already_exists_title": "Your account is already connected to this provider", + "problem_o_auth_connection_already_linked_title": "This external account is already linked to another user", + "problem_o_auth_flow_anonymous_only_title": "You are already signed in", + "problem_o_auth_flow_mismatch_title": "Sign-in attempt does not match", + "problem_o_auth_flow_mismatch_desc": "Please start over.", + "problem_o_auth_flow_missing_data_title": "The provider did not return your account details", + "problem_o_auth_flow_missing_data_desc": "Please try again.", + "problem_o_auth_flow_not_found_title": "Sign-in attempt expired", + "problem_o_auth_flow_not_found_desc": "Please start over.", + "problem_o_auth_flow_unsupported_title": "Unsupported sign-in flow", + "problem_o_auth_internal_error_title": "Something went wrong during sign-in", + "problem_o_auth_internal_error_desc": "Please try again in a moment.", + "problem_o_auth_link_authenticated_user_only_title": "You must be signed in to link an external account", + "problem_o_auth_provider_mismatch_title": "Sign-in attempt does not match the provider", + "problem_o_auth_provider_mismatch_desc": "Please start over.", + "problem_o_auth_provider_unsupported_title": "This sign-in provider is not supported", + "problem_pair_code_not_found_title": "Pair code not found", + "problem_password_reset_not_found_title": "Password reset link is invalid", + "problem_password_reset_not_found_desc": "The link may have expired or already been used.", + "problem_session_not_found_title": "Session not found", + "problem_share_get_no_shares_title": "You have no shares with this user", + "problem_share_request_create_cannot_share_with_self_title": "You cannot share with yourself", + "problem_share_request_create_shocker_not_found_title": "One or more shockers were not found", + "problem_share_request_create_shocker_not_found_desc": "They may have been removed or do not belong to you.", + "problem_share_request_not_found_title": "Share invite not found", + "problem_share_user_not_found_title": "Share not found", + "problem_share_code_already_linked_title": "Shocker is already linked to your account", + "problem_share_code_cant_link_own_share_code_title": "You cannot redeem your own share code", + "problem_share_code_not_found_title": "Share code not found", + "problem_share_link_expiry_date_in_past_title": "Expiry date cannot be in the past", + "problem_share_link_not_found_title": "Public share not found", + "problem_share_link_shocker_already_in_share_link_title": "Shocker is already in this public share", + "problem_share_link_shocker_not_in_share_link_title": "Shocker is not in this public share", + "problem_shocker_control_no_permission_title": "You do not have permission to control this shocker", + "problem_shocker_control_not_found_title": "Shocker not found", + "problem_shocker_control_paused_title": "Shocker is paused", + "problem_shocker_not_found_title": "Shocker not found", + "problem_signup_registration_disabled_title": "Registration is currently disabled", + "problem_signup_username_or_email_exists_title": "That username or email is already in use", + "problem_turnstile_invalid_title": "Verification failed", + "problem_turnstile_invalid_desc": "Please complete the challenge again and retry.", + "problem_user_not_found_title": "User not found", + "problem_user_privileged_delete_denied_title": "Privileged users cannot be deleted", + "problem_validation_error_title": "Some fields are invalid", + "problem_webhook_not_found_title": "Webhook not found", + "problem_webhook_unsupported_title": "Only Discord webhooks are supported", + "problem_webhook_unsupported_desc": "Use a discord.com URL, not canary or ptb.", + "error_too_many_requests": "Too many requests", + "error_retry_after_one": "Try again in {{count}} second.", + "error_retry_after_other": "Try again in {{count}} seconds.", + "error_unexpected_response": "Unexpected server response", + "error_internal": "Internal error occurred", + "error_network": "Network error occurred", + "dev_banner": "This is the OpenShock DEVELOPMENT environment. No data is saved, and it is regularly overwritten by production data.", + "firmware_channel_bugs_warning": "This channel might contain bugs." +} From 3432f96898cdbc4bb256d38f085410abec9e1072 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Luc=20=E2=99=A5?= Date: Thu, 12 Nov 2026 17:43:04 +0100 Subject: [PATCH 05/27] New translations en.json (Arabic) [ci skip] --- messages/ar.json | 1055 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 1055 insertions(+) create mode 100644 messages/ar.json diff --git a/messages/ar.json b/messages/ar.json new file mode 100644 index 00000000..ef4df56c --- /dev/null +++ b/messages/ar.json @@ -0,0 +1,1055 @@ +{ + "landing_tagline": "The go-to platform for safe, reliable, real low-latency remote shocking.", + "landing_section_label": "Home", + "landing_hubs_online": "Hubs online right now: ", + "landing_learn_more": "Learn More", + "landing_wiki": "Wiki", + "landing_meta_description": "Welcome to OpenShock, a free and open-source ecosystem to control various shock collars over the internet.", + "instance_meta_description": "Welcome to {{siteName}}, an independent instance of OpenShock, a free and open-source ecosystem to control various shock collars over the internet.", + "header_sidebar_toggle": "Toggle Sidebar", + "header_avatar_alt": "{{name}}'s avatar", + "header_menu_profile": "Profile", + "header_menu_settings": "Settings", + "header_menu_logout": "Logout", + "header_login": "Login", + "header_signup": "Sign Up", + "header_github_title": "OpenShock on GitHub", + "header_discord_title": "Community Discord", + "footer_made_with": "Made with by the OpenShock Team", + "footer_connection_status_label": "Server connection status", + "footer_signalr_state": "SignalR State", + "footer_frontend_version": "Frontend Version", + "footer_frontend_commit_title": "Commit {{commit}}", + "footer_backend_version": "Backend Version", + "footer_backend_commit_title": "Commit {{commit}}", + "footer_language_label": "Language", + "sidebar_home_link_label": "OpenShock home", + "sidebar_group_general": "General", + "sidebar_home": "Home", + "sidebar_shockers": "Shockers", + "sidebar_shared_shockers": "Shared Shockers", + "sidebar_hubs": "Hubs", + "sidebar_user_shares": "User Shares", + "sidebar_public_shares": "Public Shares", + "sidebar_serial_terminal": "Serial Terminal", + "sidebar_group_admin": "Admin", + "sidebar_admin_monitoring": "Monitoring", + "sidebar_admin_online_hubs": "Online Hubs", + "sidebar_admin_online_gateways": "Online Gateways", + "sidebar_admin_management": "Management", + "sidebar_admin_users": "Users", + "sidebar_admin_blacklists": "Blacklists", + "sidebar_admin_webhooks": "Webhooks", + "sidebar_admin_mail": "Mail", + "sidebar_admin_automation_tokens": "Automation Tokens", + "sidebar_admin_configuration": "Configuration", + "sidebar_group_settings": "Settings", + "sidebar_settings_api_tokens": "API Tokens", + "sidebar_settings_sessions": "Sessions", + "sidebar_settings_audit_log": "Audit Log", + "sidebar_settings_connections": "Connections", + "sidebar_settings_account": "Account Settings", + "error_meta_title": "Service Unavailable", + "error_meta_description": "OpenShock is currently unavailable", + "error_meta_logo_alt": "OpenShock Logo", + "error_fallback_message": "Something went wrong.", + "error_not_found_message": "Page not found", + "error_not_found_description": "The page you're looking for doesn't exist.", + "error_unexpected_description": "An unexpected error occurred.", + "error_go_back": "Go back", + "auth_layout_logo_alt": "OpenShock Logo", + "auth_layout_invalid_redirect_removed": "An invalid redirect URL was removed for your safety.", + "auth_activate_breadcrumb": "Activate Account", + "auth_activate_title": "Activate Account", + "auth_activate_activating": "Activating your account...", + "auth_activate_success": "Your account has been activated", + "auth_activate_failed": "This activation link is invalid or has expired", + "auth_activate_missing_token": "Missing activation token", + "auth_activate_continue": "Continue to login", + "auth_activate_toast_success": "Account activated", + "auth_forgot_breadcrumb": "Forgot Password", + "auth_forgot_title": "Forgot Password", + "auth_forgot_description": "Enter your email to reset your password", + "auth_forgot_email_label": "Email", + "auth_forgot_email_placeholder": "Email", + "auth_forgot_submit": "Reset Password", + "auth_forgot_signin_prompt": "Remember your password? Sign in", + "auth_forgot_mail_disabled": "Password resets are unavailable on this instance because it has no mail provider configured. Please contact your administrator for help recovering your account.", + "auth_forgot_toast_sent": "Reset password request has been sent to the given email", + "auth_login_breadcrumb": "Login", + "auth_login_title": "Welcome back", + "auth_login_loading_methods": "Loading available login methods", + "auth_login_choose_method": "Login with one of these methods", + "auth_login_with_account": "Login with your OpenShock Account", + "auth_login_activation_after_signup": "Your account has been created. We've sent an activation link to your email address. Check your inbox and spam folder.", + "auth_login_activation_pending": "Your account isn't activated yet. We've sent an activation link to your email address. Check your inbox and spam folder. If nothing arrives, try logging in again later to get a new link.", + "auth_login_oauth_only": "This account has no password. Sign in with the provider you signed up with.", + "auth_login_oauth_only_with_buttons": "This account has no password. Sign in with the provider you signed up with using the buttons above.", + "auth_login_or_continue_with": "Or continue with", + "auth_login_username_label": "Username or Email", + "auth_login_password_label": "Password", + "auth_login_submit": "Login", + "auth_login_signup_prompt": "Don't have an account? Sign up", + "auth_login_legal": "By clicking Login, you agree to our Terms of Service and Privacy Policy.", + "auth_oauth_create_breadcrumb": "Sign Up With {{provider}}", + "auth_oauth_create_title": "Sign Up With {{provider}}", + "auth_oauth_create_description": "Complete your account details", + "auth_oauth_create_username_label": "Username", + "auth_oauth_create_username_placeholder": "Username", + "auth_oauth_create_email_label": "Email", + "auth_oauth_create_email_placeholder": "Email", + "auth_oauth_create_submit": "Sign Up", + "auth_oauth_create_legal": "By clicking Sign Up, you agree to our Terms of Service and Privacy Policy.", + "auth_oauth_error_breadcrumb": "Authentication Error", + "auth_oauth_error_title": "Authentication Error", + "auth_oauth_error_back": "Back to login", + "auth_reset_breadcrumb": "Reset Password", + "auth_reset_title": "Reset Password", + "auth_reset_checking": "Verifying reset link...", + "auth_reset_choose_password": "Choose a new password for your account", + "auth_reset_invalid": "This reset link is invalid or has expired", + "auth_reset_password_label": "New Password", + "auth_reset_password_placeholder": "New Password", + "auth_reset_confirm_label": "Confirm New Password", + "auth_reset_confirm_placeholder": "Confirm New Password", + "auth_reset_submit": "Reset Password", + "auth_reset_request_new": "Request a new reset link", + "auth_reset_toast_success": "Password has been reset", + "auth_signup_breadcrumb": "Sign Up", + "auth_signup_toast_created_mail": "Account created successfully. Please check your email to verify your account.", + "auth_signup_toast_created_no_mail": "Account created successfully. You can log in now.", + "auth_signup_dialog_title": "Welcome! Thank you for signing up! ❤️", + "auth_signup_dialog_created_mail": "Your account has been created. 🎉 Please check your email to verify your account.", + "auth_signup_dialog_verify_then_login": "After verifying your email, you can log in to your account.", + "auth_signup_dialog_created_no_mail": "Your account has been created and is ready to use. 🎉", + "auth_signup_dialog_login_now": "You can log in to your account now.", + "auth_signup_title": "Create your account", + "auth_signup_loading_methods": "Loading available sign-up methods", + "auth_signup_using_email": "Signing up using email", + "auth_signup_choose_method": "Choose your preferred sign-up method", + "auth_signup_back": "Back", + "auth_signup_username_label": "Username", + "auth_signup_username_placeholder": "John OpenShock", + "auth_signup_email_label": "Email", + "auth_signup_email_placeholder": "john@example.com", + "auth_signup_password_label": "Password", + "auth_signup_password_placeholder": "Password", + "auth_signup_confirm_label": "Confirm Password", + "auth_signup_confirm_placeholder": "Confirm Password", + "auth_signup_submit": "Create Account", + "auth_signup_signin_prompt": "Already have an account? Sign in", + "auth_signup_or": "Or", + "auth_signup_with_email": "Signup with Email", + "auth_signup_legal": "By clicking Create Account, you agree to our Terms of Service and Privacy Policy.", + "auth_verify_breadcrumb": "Verify Email", + "auth_verify_title": "Verify Email", + "auth_verify_verifying": "Verifying your email address...", + "auth_verify_success": "Your email has been verified", + "auth_verify_failed": "This verification link is invalid or has expired", + "auth_verify_missing_token": "Missing verification token", + "auth_verify_continue": "Continue to login", + "auth_verify_toast_success": "Email verified", + "common_cancel": "Cancel", + "common_delete": "Delete", + "common_edit": "Edit", + "common_share": "Share", + "common_copy_id": "Copy ID", + "common_id_copied": "ID copied to clipboard", + "common_open_menu": "Open menu", + "common_refresh": "Refresh", + "common_settings": "Settings", + "common_clear": "Clear", + "common_online": "Online", + "common_offline": "Offline", + "common_paused": "Paused", + "common_resume": "Resume", + "common_resuming": "Resuming...", + "common_coming_soon": "(Coming soon)", + "common_save_changes": "Save Changes", + "common_danger_zone": "Danger Zone", + "common_name": "Name", + "control_intensity": "Intensity", + "control_duration": "Duration", + "control_max_intensity": "Max Intensity", + "control_max_duration": "Max Duration", + "control_vibration": "Vibration", + "control_value": "Value", + "control_live_intensity": "Live intensity", + "control_type_stop": "Stop", + "control_type_shock": "Shock", + "control_type_vibrate": "Vibrate", + "control_type_sound": "Sound", + "live_tooltip_active": "Live via {{gateway}} ({{country}}), {{latency}}ms", + "live_tooltip_connecting": "Connecting...", + "live_tooltip_connect": "Connect to Live Control", + "live_tooltip_hub_start": "Ctrl+click to start the whole hub", + "live_tooltip_hub_stop": "Ctrl+click to stop the whole hub", + "pause_resume_shocker": "Resume shocker", + "pause_pause_shocker": "Pause shocker", + "pause_resume_all": "Resume all shockers", + "pause_pause_all": "Pause all shockers", + "shocker_label": "Shocker", + "shocker_hub": "Hub", + "shocker_select_hub": "Select hub", + "shocker_rf_id": "RF ID", + "shocker_rf_id_invalid": "RF ID must be a whole number between {{min}} and {{max}}.", + "shocker_model": "Model", + "shocker_select_model": "Select model", + "shocker_name_placeholder": "Shocker name", + "shocker_menu_view_logs": "View Logs", + "shocker_delete_title": "Delete Shocker", + "shocker_delete_desc": "Are you sure you want to delete \"{{name}}\"? This action cannot be undone.", + "shocker_toast_deleted": "Shocker \"{{name}}\" deleted", + "shocker_toast_paused": "Shocker paused", + "shocker_toast_resumed": "Shocker resumed", + "shocker_add_desc": "Register a new shocker to one of your hubs.", + "shocker_add_name_placeholder": "My Shocker", + "shockers_title": "Shockers", + "shockers_subtitle": "Every shocker paired to your hubs.", + "shockers_loading": "Loading shockers...", + "shockers_toast_refreshed": "Shockers refreshed", + "shockers_toast_need_hub": "You need to create a hub before adding shockers.", + "shockers_toast_added": "Shocker added", + "shockers_unknown_module": "Unknown module type", + "shockers_add": "Add Shocker", + "shockers_view_mode": "View mode", + "shockers_mode_classic": "Classic", + "shockers_mode_rich": "Rich", + "shockers_mode_simple": "Simple", + "shockers_mode_map": "Map", + "shockers_group_by_hub": "Group by Hub", + "shockers_global_limits": "Global Limits", + "shockers_logs_label": "Logs", + "shockers_empty_title": "No shockers yet", + "shockers_empty_no_hubs": "Create a hub first, then add shockers to it.", + "shockers_empty_has_hubs": "Add a shocker to one of your hubs to get started.", + "shockers_create_hub": "Create a Hub", + "shockers_count_one": "{{count}} shocker", + "shockers_count_other": "{{count}} shockers", + "shared_shockers_title": "Shared Shockers", + "shared_shockers_subtitle": "Shockers other users have shared with you.", + "shared_shockers_empty_title": "No shockers have been shared with you yet.", + "shared_shockers_empty_desc": "When someone shares their shockers with you, they'll appear here.", + "shocker_logs_title": "Shocker Logs", + "shocker_logs_subtitle": "Every control command sent to your shockers.", + "shocker_logs_live_title": "New logs appear in real time", + "shocker_logs_paused_title": "Live updates pause when sorting or viewing a page other than the first", + "shocker_logs_live": "Live", + "shocker_logs_col_time": "Time", + "shocker_logs_col_type": "Type", + "shocker_logs_col_by": "By", + "shocker_logs_filter_label": "Filter by shocker", + "shocker_logs_filter_placeholder": "Search shockers...", + "shocker_logs_filter_all": "All shockers", + "shocker_logs_filter_none": "No matching shockers", + "shocker_edit_title": "Edit Shocker", + "shocker_edit_subtitle": "Change this shocker's details or remove it.", + "shocker_edit_back": "Back to Shockers", + "shocker_edit_load_failed": "Failed to load shocker.", + "shocker_edit_loading": "Loading shocker...", + "shocker_edit_details_title": "Shocker Details", + "shocker_edit_details_desc": "Update the name, RF ID, and model for this shocker.", + "shocker_edit_pause_state": "Pause State", + "shocker_edit_is_paused": "Shocker is paused", + "shocker_edit_is_active": "Shocker is active", + "shocker_edit_toast_updated": "Shocker updated", + "shocker_edit_delete_desc": "Permanently delete this shocker. This action cannot be undone.", + "common_close": "Close", + "common_continue": "Continue", + "common_loading": "Loading...", + "common_previous": "Previous", + "common_next": "Next", + "common_steps": "Steps", + "common_step_label": "Step {{number}}: {{title}}", + "common_copy": "Copy", + "common_copied": "Copied", + "common_never": "Never", + "common_error": "Error: {{message}}", + "terminal_title": "Serial Terminal", + "terminal_connecting": "Connecting...", + "terminal_help_button": "I'm having trouble, help?", + "terminal_back_to_modes": "Back to mode picker", + "terminal_mode_configure": "Configure Device", + "terminal_mode_configure_desc": "Configure WiFi, authentication, and more. Includes an interactive serial console.", + "terminal_mode_flash": "Flash Firmware", + "terminal_mode_flash_desc": "Install or update firmware on a connected device.", + "terminal_mode_raw": "Serial Monitor", + "terminal_mode_raw_desc": "Just the console. Read device logs and send commands.", + "terminal_step_channel": "Select Channel", + "terminal_step_board": "Select Board", + "terminal_go_to_step": "Go to step {{number}}: {{title}}", + "terminal_erase": "Erase before flashing", + "terminal_erase_desc": "Clears all data on the device including existing configs", + "terminal_unsupported": "Your browser does not support this feature.", + "terminal_update_browser": "Please update your browser to the latest version.", + "terminal_use_browsers": "Please use one of the following browsers:", + "terminal_connect_failed_bootloader": "Could not enter bootloader mode", + "terminal_connect_failed": "Device connection failed", + "terminal_connect_failed_desc": "We couldn't establish a serial connection with the device.", + "terminal_quick_tries": "Quick things to try:", + "terminal_try_replug": "Unplug and replug the device.", + "terminal_try_cable": "Try a different USB cable or port.", + "terminal_try_driver": "Make sure the serial driver is installed.", + "terminal_open_troubleshooter": "Open troubleshooter", + "terminal_log_reset_no_device": "Host-side error during reset: no device!", + "terminal_log_reset_error": "Host-side error during reset: {{error}}", + "terminal_log_send_no_device": "Couldn't send: no device!", + "terminal_log_send_error": "Couldn't send: {{error}}", + "terminal_log_firmware_disconnected": "Firmware disconnected: {{error}}", + "terminal_log_erase_failed": "Failed to erase flash: {{error}}", + "terminal_log_hard_reset_failed": "Failed to hard reset: {{error}}", + "terminal_log_flash_complete": "Flash complete", + "terminal_log_flash_failed": "Failed to flash: {{error}}", + "terminal_log_command_failed": "Failed to write application command: {{error}}", + "terminal_help_title": "Troubleshooter", + "terminal_help_desc": "Work through these steps in order. Each one rules out a common cause.", + "terminal_help_step_cable": "USB cable", + "terminal_help_step_port": "USB port", + "terminal_help_step_driver": "Install driver", + "terminal_help_step_manual": "Manual driver update", + "terminal_help_step_discord": "Ask on Discord", + "terminal_help_cable_body": "Many USB-C and micro-USB cables are charge-only and don't carry data. Swap to a known-good data cable (one you've used to transfer files or connect other devices) and reconnect the hub.", + "terminal_help_port_body": "Plug the device directly into a USB port on your computer. Avoid USB hubs, docking stations, and front-panel ports if possible; these are common sources of power and signal issues. If you're on a desktop, try a port on the back of the machine.", + "terminal_help_driver_download": "Download the CP210x driver:", + "terminal_help_driver_extract": "Extract the contents of the zip file to a folder on your computer.", + "terminal_help_driver_run": "Open the folder and run {{installer}}. Follow the prompts to install.", + "terminal_help_driver_reconnect": "Reconnect the device.", + "terminal_help_manual_intro": "If the driver installer ran but the device still doesn't show up:", + "terminal_help_manual_open": "Open Device Manager (press Win + X and select Device Manager).", + "terminal_help_manual_ports": "Under Ports (COM & LPT), look for an entry like:", + "terminal_help_manual_missing": "If it's missing, the device isn't being detected by Windows at all; revisit the cable and port steps.", + "terminal_help_manual_update": "Right-click the device and pick Update Driver.", + "terminal_help_manual_browse": "Choose Browse my computer for drivers and select the folder you extracted the driver zip into. Make sure Include subfolders is checked.", + "terminal_help_manual_success": "On success, the entry should now read {{deviceName}}.", + "terminal_help_discord_intro": "Still stuck after all of the above? Hop into our Discord server and ask in the {{channel}} channel. Please include:", + "terminal_help_discord_os": "your operating system and browser", + "terminal_help_discord_device": "the device you're using (board model, where you got it)", + "terminal_help_discord_tried": "what you've already tried from the previous steps", + "terminal_help_discord_errors": "any error messages or relevant terminal output", + "terminal_help_discord_join": "Join our Discord server", + "terminal_risk_title": "⚠️ UNSTABLE FIRMWARE", + "terminal_risk_intro": "You are about to flash experimental firmware that is known to be unstable.", + "terminal_risk_brick": "This may permanently brick your device, require manual recovery, or render it unusable.", + "terminal_risk_no_support": "We will NOT provide support for issues caused by this firmware.", + "terminal_risk_acknowledge": "I understand this is entirely my responsibility", + "terminal_risk_abort": "Abort", + "terminal_risk_accept": "I ACCEPT FULL RESPONSIBILITY", + "firmware_channel_recommended": "This is the recommended channel.", + "firmware_channel_danger": "DO NOT USE THIS UNLESS YOU KNOW WHAT YOU ARE DOING", + "firmware_channel_stable": "Stable", + "firmware_channel_beta": "Beta", + "firmware_channel_develop": "Develop", + "terminal_board_select": "Select a board...", + "terminal_board_search": "Search boards...", + "terminal_board_none": "No board found.", + "terminal_flash_button": "Flash", + "terminal_flash_progress": "Flash Progress: {{status}}", + "terminal_flash_idle": "Idle", + "terminal_flash_no_device": "No device selected.", + "terminal_flash_resetting": "Resetting...", + "terminal_flash_downloading": "Downloading firmware...", + "terminal_flash_download_failed": "Failed to download firmware.", + "terminal_flash_flashing": "Flashing firmware...", + "terminal_flash_rebooting": "Rebooting device... (Reconnect to power manually if stuck)", + "terminal_flash_done": "Rebooted device! Flashing complete.", + "terminal_port_select": "Select Device", + "terminal_port_disconnect": "Disconnect Device", + "terminal_port_connected": "Device connected: {{id}}", + "terminal_console": "Console", + "terminal_connected_device": "Connected device", + "terminal_resize": "Resize terminal panel", + "terminal_reboot": "Reboot", + "terminal_disconnect": "Disconnect", + "terminal_fullscreen_exit_esc": "Exit fullscreen (Esc)", + "terminal_fullscreen_exit": "Exit fullscreen", + "terminal_fullscreen_fill": "Fill the window", + "terminal_command_label": "Serial command", + "terminal_command_placeholder": "Type a command...", + "terminal_command_send": "Send command", + "terminal_colors": "Colors", + "terminal_colors_menu": "Colors...", + "terminal_colors_label": "Console colors", + "terminal_colors_close": "Close colors", + "terminal_color_input": "{{name}} color", + "terminal_colors_reset": "Reset to defaults", + "terminal_color_bg": "Background", + "terminal_color_fg": "Text", + "terminal_color_ts": "Timestamp", + "terminal_color_error": "Error", + "terminal_color_warning": "Warning", + "terminal_color_info": "Info", + "terminal_color_debug": "Debug", + "terminal_color_verbose": "Verbose", + "terminal_options": "Options", + "terminal_options_label": "Console options", + "terminal_hide_system": "Hide system messages", + "terminal_stick_bottom": "Stick to bottom", + "terminal_raw_output": "Raw output", + "terminal_timestamps": "Timestamps", + "terminal_timestamp_uptime": "Uptime", + "terminal_timestamp_local": "Local", + "terminal_timestamp_ms": "Ms", + "terminal_timestamp_off": "Off", + "terminal_copy_settings": "Copy settings", + "terminal_import_settings": "Import settings", + "terminal_copy_selection": "Copy selection", + "terminal_copy_all": "Copy all output", + "terminal_toast_selection_copied": "Selection copied", + "terminal_toast_output_copied": "Console output copied", + "terminal_toast_settings_copied": "Console settings copied", + "terminal_toast_clipboard_unreadable": "Could not read the clipboard", + "terminal_toast_settings_imported": "Console settings imported", + "terminal_toast_settings_invalid": "Clipboard does not contain console settings", + "common_try_again": "Try again", + "terminal_cfg_intro": "Values are sent to the device via UART. Read the device's response in the console below. Commands without an argument act as getters; use the button next to each field to read the current value.", + "terminal_cfg_rf_title": "RF Transmitter", + "terminal_cfg_rf_desc": "Controls the shocker RF output.", + "terminal_cfg_tx_pin": "TX GPIO pin", + "terminal_cfg_example": "e.g. {{value}}", + "terminal_cfg_read_value": "Read current value", + "terminal_cfg_set": "Set", + "terminal_cfg_read": "Read", + "terminal_cfg_reading": "Reading…", + "terminal_cfg_apply": "Apply", + "terminal_cfg_keepalive": "Keepalive enabled", + "terminal_cfg_keepalive_desc": "Periodically pings paired shockers to keep them awake.", + "terminal_cfg_estop_title": "Emergency Stop", + "terminal_cfg_estop_desc": "Hardware button that halts all output.", + "terminal_cfg_estop_enabled": "EStop enabled", + "terminal_cfg_estop_pin": "EStop GPIO pin", + "terminal_cfg_estop_note": "Note: {{latching}} and {{active}} have no dedicated commands; set them via the JSON config below.", + "terminal_cfg_wifi_title": "WiFi", + "terminal_cfg_wifi_desc": "Station credentials and device hostname.", + "terminal_cfg_hostname": "Hostname", + "terminal_cfg_networks": "Networks (JSON array)", + "terminal_cfg_invalid_json_array": "Must be a valid JSON array", + "terminal_cfg_ap_note": "AP settings ({{ssid}}, {{password}}, {{disabled}}, {{staDisabled}}, {{offlineMode}}) have no dedicated commands; use the JSON config.", + "terminal_cfg_backend_title": "Backend", + "terminal_cfg_backend_desc": "OpenShock server and authentication.", + "terminal_cfg_domain": "Domain", + "terminal_cfg_domain_restart": "Setting the domain will restart the device.", + "terminal_cfg_auth_token": "Auth token", + "terminal_cfg_auth_token_placeholder": "Paste device token", + "terminal_cfg_hide": "Hide", + "terminal_cfg_show": "Show", + "terminal_cfg_serial_title": "Serial Input", + "terminal_cfg_echo": "Echo enabled", + "terminal_cfg_echo_desc": "Print typed characters back to the console.", + "terminal_cfg_advanced_title": "Advanced: full config", + "terminal_cfg_advanced_desc": "For fields without dedicated commands (captive portal, OTA, LAN, etc.), replace the entire config.", + "terminal_cfg_json_config": "JSON config", + "terminal_cfg_invalid_json": "Must be valid JSON", + "terminal_cfg_read_json": "Read current config as JSON", + "terminal_cfg_json_restart": "Applying a JSON config will restart the device.", + "terminal_cfg_raw_config": "Raw FlatBuffer config (base64)", + "terminal_cfg_invalid_base64": "Must be a valid base64 string", + "terminal_cfg_read_raw": "Read current config as base64", + "terminal_cfg_factory_reset": "Factory reset", + "terminal_cfg_factory_reset_desc": "Wipes the entire device configuration.", + "terminal_cfg_factory_reset_title": "Factory reset device?", + "terminal_cfg_factory_reset_action": "Wipe config", + "terminal_cfg_factory_reset_confirm": "This will erase all configuration on the device; WiFi networks, backend credentials, pins, and all other settings. The device will be reset to defaults.", + "terminal_cfg_read_failed_json_title": "Couldn't read the JSON config", + "terminal_cfg_read_failed_raw_title": "Couldn't read the raw config", + "terminal_cfg_read_failed_desc": "The device didn't respond after {{attempts}} attempts.", + "terminal_cfg_common_causes": "Common causes:", + "terminal_cfg_cause_busy": "The device is busy handling another command.", + "terminal_cfg_cause_disconnected": "The device disconnected or rebooted.", + "terminal_cfg_cause_unsupported": "The firmware version doesn't support this command.", + "common_status": "Status", + "common_version": "Version", + "common_created": "Created", + "common_create": "Create", + "common_done": "Done", + "common_enable": "Enable", + "common_disable": "Disable", + "common_are_you_sure": "Are you sure?", + "common_generating": "Generating...", + "hubs_title": "Hubs", + "hubs_subtitle": "Every hub registered to your account.", + "hubs_add": "Add Hub", + "hubs_load_failed": "Failed to load hubs.", + "hubs_empty_title": "No hubs yet", + "hubs_empty_desc": "A hub is the device that relays commands to your shockers. Add one to get started.", + "hubs_create_title": "Create hub", + "hubs_name_label": "Hub Name", + "hubs_name_placeholder": "My Hub", + "hub_toast_not_connected": "Not connected to the server", + "hub_toast_try_later": "Try again in a moment.", + "hub_reboot_title": "Reboot {{name}}?", + "hub_reboot_desc": "The hub will disconnect and restart. Any shockers paired to it stop responding until it comes back online.", + "hub_reboot": "Reboot", + "hub_hotspot_enable_title": "Enable Wi-Fi hotspot on {{name}}?", + "hub_hotspot_disable_title": "Disable Wi-Fi hotspot on {{name}}?", + "hub_hotspot_enable_desc": "The hub broadcasts its own setup network. It stays reachable on your Wi-Fi, but the hotspot is open to anyone in range until you turn it off.", + "hub_hotspot_disable_desc": "The setup hotspot shuts down. If the hub is not already on your Wi-Fi you will need physical access to set it up again.", + "hub_delete_desc": "You are about to delete hub {{name}}.", + "hub_delete_shockers": "This will also delete the following shockers:", + "hub_edit_title": "Edit hub", + "hub_edit_apply": "Apply", + "hub_pair_title_generate": "Generate pair code?", + "hub_pair_title_generated": "Pair code generated", + "hub_pair_title_paired": "Hub paired", + "hub_pair_consumed": "{{name}} consumed this pair code and is now paired.", + "hub_pair_used": "The code has been used and is no longer valid.", + "hub_pair_generated_for": "Pair code generated for {{name}}.", + "hub_copy_now": "The code below will not be accessible later, please copy it now and update clients with it.", + "hub_pair_generate_for": "You are about to generate a pair code for {{name}}.", + "hub_pair_valid_for": "It will be valid for 15 minutes after its creation.", + "hub_pair_one_active": "There is only one active pair code per hub, newly generated ones will override the older active ones.", + "hub_pair_complete": "Pairing complete", + "hub_pair_code_label": "Pair code:", + "hub_pair_copied_close": "Code has been copied, close", + "hub_pair_get": "Get Pair Code", + "hub_token_generated": "Token generated", + "hub_token_generated_for": "New token generated for {{name}}.", + "hub_token_regenerate_for": "You are about to regenerate the token for {{name}}.", + "hub_token_invalidate": "This action will invalidate the current token and disconnect clients using it.", + "hub_token_confirm": "Are you sure you want to do this?", + "hub_token_label": "New token:", + "hub_token_copied_close": "Token has been copied, close", + "hub_token_regenerate": "Regenerate Token", + "hub_menu_update": "Update", + "hub_menu_label": "Hub", + "hub_menu_hotspot_enable": "Enable Wi-Fi hotspot", + "hub_menu_hotspot_disable": "Disable Wi-Fi hotspot", + "hub_menu_pair": "Pair", + "hub_menu_estop": "Emergency Stop", + "hub_update_breadcrumb": "Update", + "hub_update_unknown_hub": "Unknown Hub", + "hub_update_unknown_task": "Unknown Task", + "hub_update_task_metadata": "Fetching Metadata", + "hub_update_task_preparing": "Preparing for Update", + "hub_update_task_flash_fs": "Flashing Filesystem", + "hub_update_task_verify_fs": "Verifying Filesystem", + "hub_update_task_flash_app": "Flashing Application", + "hub_update_task_bootable": "Marking Application Bootable", + "hub_update_task_rebooting": "Rebooting", + "hub_update_status_started": "Started", + "hub_update_status_running": "Running", + "hub_update_status_finished": "Finished", + "hub_update_status_error": "Error", + "hub_update_status_timeout": "Timeout", + "hub_update_confirm_title": "Confirm firmware update", + "hub_update_confirm_desc": "Update {{name}} to version {{version}}?", + "hub_update_unstable_warning": "This version may not be from the stable channel and could contain bugs.", + "hub_update_title": "Update {{name}}", + "hub_update_subtitle": "Manage firmware updates for this hub.", + "hub_update_status_title": "Hub Status", + "hub_update_firmware": "Firmware: {{version}}", + "hub_update_confirm": "Update", + "hub_update_success": "Update completed successfully", + "hub_update_rolled_back": "Device rolled back to previous version", + "hub_update_back": "Back to Hubs", + "hub_update_flash_again": "Flash Again", + "hub_update_card_title": "Firmware Update", + "hub_update_card_desc": "Select a firmware channel and version to install.", + "hub_update_to": "Update to {{version}}", + "hub_update_must_be_online": "Hub must be online to start an update.", + "hub_update_updating_to": "Updating to {{version}}...", + "hub_update_total": "Total", + "hub_update_task": "Task", + "hub_update_history": "Update History", + "hub_update_no_history": "No update history found for this hub.", + "hub_update_col_id": "ID", + "hub_update_col_started": "Started", + "hub_update_col_message": "Message", + "hub_update_loading": "Loading hub information...", + "hub_update_not_found": "Hub not found.", + "home_breadcrumb": "Home", + "home_welcome": "Welcome back", + "home_welcome_name": "Welcome back, {{name}}", + "home_subtitle": "Here's an overview of your OpenShock setup.", + "home_hubs_online": "{{count}} online", + "home_hub_status": "Hub Status", + "home_no_hubs": "No hubs", + "home_all_online": "All online", + "home_all_offline": "All offline", + "home_some_online": "{{online}}/{{total}} online", + "home_quick_links": "Quick Links", + "home_my_shockers": "My Shockers", + "home_my_shockers_desc": "Control your shockers", + "home_hubs_desc": "Manage your hubs", + "home_shared_desc": "Shockers shared with you", + "home_public_desc": "Manage share links", + "home_get_started": "Get Started", + "home_get_started_desc": "You don't have any hubs yet. Create a hub to connect your first device, then add shockers to it.", + "home_set_up_hub": "Set Up a Hub", + "home_first_shocker": "Add Your First Shocker", + "home_first_shocker_desc_one": "You have {{count}} hub set up. Add a shocker to start controlling it.", + "home_first_shocker_desc_other": "You have {{count}} hubs set up. Add a shocker to start controlling it.", + "home_go_to_shockers": "Go to Shockers", + "profile_title": "Profile", + "profile_coming_soon": "Profile is coming soon", + "profile_coming_soon_desc": "Your public profile is not available yet. Account details live under Settings.", + "common_retry": "Retry", + "common_never_used": "Never used", + "common_expires": "Expires {{time}}", + "common_search_placeholder": "Search...", + "common_unknown": "Unknown", + "settings_breadcrumb_account": "Account", + "account_subtitle": "Your sign-in details and account actions.", + "account_change_username": "Change Username", + "account_change_email": "Change Email", + "account_change_password": "Change Password", + "account_username_label": "Username", + "account_email_label": "Email", + "account_password_label": "Password", + "account_new_password_label": "New Password", + "account_confirm_password_label": "Confirm New Password", + "account_oauth_only": "Not available for OAuth-only accounts", + "account_oauth_no_password": "This account signs in via OAuth and has no password.", + "account_diagnostics": "Diagnostics", + "account_diagnostics_desc": "Help us fix crashes and slow API calls. Reports include the error message, stack trace and your IP. Off by default.", + "account_diagnostics_level": "Diagnostics level", + "account_telemetry_off": "Off", + "account_telemetry_off_desc": "Send nothing.", + "account_telemetry_errors": "Errors", + "account_telemetry_errors_desc": "Send browser error reports only.", + "account_telemetry_full": "Full", + "account_telemetry_full_desc": "Error reports plus traces of API calls (no page navigations).", + "account_toast_deactivated": "Account deactivated successfully", + "account_deactivate_title": "Deactivate account", + "account_deactivate_desc": "Are you sure you want to deactivate your account?", + "account_deactivate": "Deactivate Account", + "account_email_title": "Change email", + "account_email_desc": "Enter your new email address and confirm with your current password.", + "account_email_toast_sent": "Verification email sent to {{email}}. Click the link in that email to apply the change.", + "account_new_email": "New Email", + "account_current_password": "Current Password", + "account_password_title": "Change password", + "account_password_desc": "Enter your current password and choose a new one.", + "account_password_toast": "Password has been changed", + "account_username_title": "Change username", + "account_username_desc": "Enter a new username.", + "account_new_username": "New Username", + "account_username_toast": "Username changed successfully", + "tokens_subtitle": "API Tokens are used to authenticate with the OpenShock API.", + "tokens_generate": "Generate Token", + "tokens_toast_refreshed": "Tokens refreshed successfully", + "tokens_empty_title": "No API tokens", + "tokens_empty_desc": "Generate a token to authenticate with the OpenShock API.", + "tokens_created_on": "Created {{date}}", + "tokens_last_used": "Last used {{time}}", + "tokens_never_expires": "Never expires", + "tokens_load_failed": "Failed to load API tokens.", + "token_toast_edited": "Token edited successfully", + "token_name_required": "Name is required", + "token_name_too_long": "Name is too long", + "token_edit_title": "Edit API token", + "token_name_label": "Token Name", + "token_name_placeholder": "Token name...", + "token_permissions": "Permissions", + "token_perm_category_shockers": "Shockers", + "token_perm_category_devices": "Hubs", + "token_perm_category_usershares": "User Shares", + "token_perm_category_publicshares": "Public Shares", + "token_perm_use": "Use", + "token_perm_edit": "Edit", + "token_perm_pause": "Pause", + "token_perm_auth": "Authenticate", + "token_shocker_control": "Shocker Control", + "token_toast_paused": "Token paused", + "token_toast_resumed": "Token resumed", + "token_delete_title": "Delete API token", + "token_delete_desc": "Are you sure you want to delete {{name}}?", + "token_delete_permanent": "This action cannot be undone. This will permanently delete the token.", + "token_toast_deleted": "Token deleted successfully", + "token_resume": "Resume token", + "token_pause": "Pause token", + "token_mode_clamp_desc": "Clamp: requests outside the allowed range are capped to the nearest limit (the min or the max).", + "token_mode_lerp_desc": "Lerp: the full input range is linearly rescaled so it fits within your allowed min–max range.", + "token_paused_desc": "A paused token may not send shocker control messages.", + "token_intensity_range": "Intensity range", + "token_duration_range": "Duration range", + "token_new_breadcrumb": "New", + "token_redirect_not_allowed": "The provided redirect_uri is not allowed. Only loopback addresses or custom application schemes are permitted.", + "token_params_missing": "Required get parameters are missing. Make sure name, redirect_uri, and permissions are provided.", + "token_invalid_permissions": "Invalid permissions provided: {{list}}", + "token_toast_created": "Token created successfully", + "token_request_title": "API Token Request", + "token_access_granted": "Access granted", + "token_shared_redirecting": "The token has been created and shared with the application. Redirecting you back to {{uri}}.", + "token_not_redirected": "If you are not redirected automatically, use the button below.", + "token_finish": "Finish", + "token_generated_title": "API Token Generated", + "token_copy_now": "Please copy your API Token now, you will not be able to view it again later!", + "token_new_title": "New API Token", + "token_external_desc": "An external application is requesting access to your account. Review and adjust the permissions below before allowing access.", + "token_new_desc": "Configure and generate a new API token for your account.", + "token_external_requesting": "{{name}} is requesting an API Token. Your token will be shared with the application at {{uri}}.", + "token_allow": "Allow", + "token_generate": "Generate", + "token_deny": "Deny", + "sessions_subtitle": "Every active session on your account. Revoke any you do not recognize.", + "sessions_unknown_device": "Unknown device", + "sessions_toast_refreshed": "Sessions refreshed successfully", + "sessions_load_failed": "Failed to load sessions.", + "sessions_empty_title": "No active sessions", + "sessions_empty_desc": "Sessions appear here once you sign in from a browser or app.", + "sessions_last_seen": "Last seen {{time}}", + "sessions_signed_in": "Signed in {{time}}", + "session_toast_revoked": "Session revoked successfully", + "session_revoke_title": "Revoke session", + "session_revoke": "Revoke", + "session_revoke_desc": "Are you sure you want to revoke this session?", + "session_revoke_from": "Session logged in from {{ip}} using {{agent}}", + "connections_title": "OAuth Connections", + "connections_subtitle": "Link or unlink third-party accounts to sign in faster and keep your profile in sync.", + "connections_toast_linked": "Account linked.", + "connections_toast_cancelled": "Link flow cancelled.", + "connections_toast_failed": "Linking failed.", + "connections_toast_removed": "Connection removed", + "connections_refreshing": "Refreshing…", + "connections_link_new": "Link new provider", + "connections_empty_title": "No connections yet", + "connections_empty_desc": "Choose “Link new provider” above to connect available providers.", + "connections_unlink": "Unlink", + "connections_load_failed": "Failed to load OAuth connections.", + "connections_unlink_title": "Unlink {{name}}?", + "connections_unlink_title_generic": "Unlink this account?", + "connections_unlink_desc": "You'll no longer be able to sign in with this provider unless you link it again.", + "provider_starting": "Starting {{name}}...", + "provider_link": "Link {{name}}", + "audit_subtitle": "Security-relevant activity on your account. Review anything you do not recognize.", + "audit_col_time": "Time", + "audit_col_action": "Action", + "audit_col_details": "Details", + "audit_col_reason": "Reason", + "audit_col_ip": "IP address", + "audit_col_device": "Device", + "audit_action_login": "Signed in", + "audit_action_logout": "Signed out", + "audit_action_password_changed": "Password changed", + "audit_action_email_change_requested": "Email change requested", + "audit_action_email_changed": "Email changed", + "audit_action_username_changed": "Username changed", + "audit_action_api_token_created": "API token created", + "audit_action_api_token_deleted": "API token deleted", + "audit_action_oauth_connected": "Connection added", + "audit_action_oauth_disconnected": "Connection removed", + "audit_action_account_deactivated": "Account deactivated", + "audit_action_account_reactivated": "Account reactivated", + "audit_action_account_deleted": "Account deleted", + "audit_action_automation_token_created": "Automation token created", + "audit_action_automation_token_updated": "Automation token updated", + "audit_action_automation_token_rotated": "Automation token rotated", + "audit_action_automation_token_deleted": "Automation token deleted", + "audit_action_automation_token_used": "Automation token used", + "audit_meta_session": "Session {{id}}", + "audit_meta_changed": "{{old}} to {{new}}", + "audit_meta_email_requested": "Requested change to {{email}}", + "audit_meta_accounts_removed_one": "{{name}} ({{count}} account removed)", + "audit_meta_accounts_removed_other": "{{name}} ({{count}} accounts removed)", + "audit_meta_scheduled_deletion": "Scheduled for deletion", + "audit_meta_kept": "Kept for reactivation", + "common_view": "View", + "common_save": "Save", + "common_saving": "Saving...", + "common_back": "Back", + "common_shared_by": "Shared by", + "common_user_avatar": "User Avatar", + "common_toast_saved": "Changes saved successfully", + "pause_reason_shocker": "Paused at shocker level", + "pause_reason_shocker_user_share": "Paused at shocker and user share level", + "pause_reason_shocker_public_share": "Paused at shocker and public share level", + "pause_reason_user_share": "Paused at user share level", + "pause_reason_public_share": "Paused at public share level", + "public_shares_subtitle": "A link anyone can use, no account required.", + "public_shares_new": "New Share", + "public_share_never_expires": "Never expires", + "public_shares_empty_title": "No public shares yet", + "public_shares_empty_desc": "Create a link that anyone can use to control your shockers.", + "public_share_expired": "Expired", + "public_share_no_expiry": "No expiry", + "public_share_label": "Public Share", + "public_share_toast_created": "Created new public share", + "public_share_create_title": "Create public share", + "public_share_toast_deleted": "Deleted public share", + "public_share_delete_title": "Delete public share", + "public_share_delete_desc": "Are you sure you want to delete public share {{name}}?", + "public_share_edit_title": "Public Share: {{name}}", + "public_share_edit_subtitle": "Editing: changes apply when you save.", + "public_share_add_shocker": "Add Shocker", + "public_share_toast_added_one": "Added {{count}} shocker to share", + "public_share_toast_added_other": "Added {{count}} shockers to share", + "public_share_empty_shockers_title": "No shockers in this share", + "public_share_empty_shockers_desc": "Add a shocker and anyone with the link will be able to control it.", + "public_share_load_failed": "Error fetching public share details", + "public_share_paused_here": "Paused for this share", + "public_share_resume_shocker": "Resume shocker", + "public_share_pause_shocker": "Pause shocker", + "public_share_remove": "Remove from share", + "public_share_toast_removed": "Shocker removed from share", + "public_share_add_title": "Add shockers", + "public_share_add_desc": "Add shockers to this public share. You can set their limits once they are added.", + "public_share_add_placeholder": "Select shockers to share...", + "public_share_add_no_match": "No matching shockers", + "public_share_add_submit": "Add Shockers", + "public_share_view_loading": "Loading share details...", + "public_share_view_title": "Public Share Link", + "public_share_view_desc": "Enter as a guest or login with your OpenShock account", + "public_share_view_guest_name": "Guest Name", + "public_share_view_enter": "Enter", + "public_share_view_enter_guest": "Enter as Guest", + "public_share_login": "Login", + "perm_shock_on": "Shock enabled", + "perm_shock_off": "Shock disabled", + "perm_vibrate_on": "Vibrate enabled", + "perm_vibrate_off": "Vibrate disabled", + "perm_sound_on": "Sound enabled", + "perm_sound_off": "Sound disabled", + "perm_live_on": "Live enabled", + "perm_live_off": "Live disabled", + "perm_live_control": "Live Control", + "user_selector_avatar_of": "{{name}}'s avatar", + "user_selector_placeholder": "Enter user name", + "user_selector_aria": "Username to search", + "user_selector_search": "Search user", + "user_selector_found": "User found", + "common_remove": "Remove", + "user_shares_subtitle": "Direct permanent shares with other users.", + "user_shares_toast_invited": "Sent a shocker invite to {{name}}", + "user_shares_redeem": "Redeem Code", + "user_shares_new": "New Share", + "user_shares_tab_shares": "Shares", + "user_shares_tab_incoming": "Shared with Me", + "user_shares_tab_invites": "Invites", + "share_code_create_title": "New share code", + "share_code_create_desc": "Create a Share Code or Invite", + "share_code_shocker_placeholder": "Select shockers to share...", + "share_code_no_match": "No matching shockers", + "share_code_send_invite": "Send Share Invite", + "share_code_create": "Create Share Code", + "share_code_created_title": "Share code generated", + "share_code_created_desc": "Please copy share code or code link!", + "share_code_redeem_title": "Redeem share code", + "share_code_redeem_desc": "Enter the share code to redeem", + "share_code_redeem_placeholder": "Enter share code", + "share_code_redeemed": "Redeemed successfully!", + "share_code_shared_shockers": "Shared shockers", + "share_code_redeeming": "Redeeming...", + "share_code_redeem": "Redeem", + "incoming_shares_empty_title": "Nothing shared with you", + "incoming_shares_empty_desc": "No one has shared a shocker with you yet.", + "incoming_share_toast_removed": "Removed share for {{name}}", + "incoming_share_remove_title": "Remove Share", + "incoming_share_remove_desc": "Are you sure you want to remove the share for {{name}}?", + "incoming_share_toast_removed_shocker": "Removed {{shocker}} shared by {{name}}", + "incoming_share_remove_shocker_title": "Remove this shared shocker?", + "incoming_share_remove_shocker_desc": "Are you sure you want to remove the shocker share {{shocker}} by {{name}}?", + "incoming_share_manage_from": "Manage shares from", + "share_remove": "Remove share", + "invites_empty_title": "No invites yet", + "invites_empty_desc": "You have no incoming or outgoing share invites.", + "invites_outgoing": "Outgoing", + "invites_outgoing_empty_title": "No outgoing invites", + "invites_outgoing_empty_desc": "You have no outgoing share invites.", + "invites_incoming": "Incoming", + "invites_incoming_empty_title": "No incoming invites", + "invites_incoming_empty_desc": "You have no incoming share invites.", + "invite_toast_accepted": "Accepted share invite from {{name}}", + "invite_toast_declined": "Declined share invite from {{name}}", + "invite_deny_title": "Deny Invite", + "invite_deny_label": "Deny Invite", + "invite_deny": "Deny", + "invite_deny_desc": "Are you sure you want to deny the invite from {{name}}?", + "invite_accept": "Accept Invite", + "invite_toast_cancelled_for": "Cancelled invite for {{name}} ({{id}})", + "invite_toast_cancelled": "Cancelled invite {{id}}", + "invite_cancel_title": "Cancel Invite", + "invite_cancel": "Cancel", + "invite_cancel_for_desc": "Are you sure you want to cancel the invite for {{name}}?", + "invite_cancel_code_desc": "Are you sure you want to cancel the invite with code {{code}}?", + "invite_cancel_outstanding": "Cancel Outstanding Invite", + "outgoing_shares_empty_title": "No shared shockers", + "outgoing_shares_empty_desc": "You haven't shared any shockers with other users yet.", + "outgoing_share_toast_removed": "Removed shocker share {{name}}", + "outgoing_share_remove_title": "Stop sharing this shocker?", + "outgoing_share_editing_for": "Editing shares for", + "outgoing_share_limits": "Limits & Permissions", + "outgoing_share_same": "Same restrictions on every shocker", + "outgoing_share_per_desc": "Tune restrictions per shocker", + "outgoing_share_all": "All", + "outgoing_share_per": "Per shocker", + "outgoing_share_remove_desc": "Are you sure you want to stop sharing {{shocker}} with {{name}}?", + "report_breadcrumb": "Report API Tokens", + "report_toast_clipboard_failed": "Failed to read clipboard: {{error}}", + "report_title": "Report Leaked API Tokens", + "report_paste": "Paste from clipboard", + "report_warning": "This form is only for reporting accidentally leaked API tokens.", + "report_abuse_warning": "Intentional abuse will result in bans or severe endpoint restrictions.", + "report_detected": "Detected Tokens", + "report_invalid": "One or more tokens appear to be invalid. Please check for formatting issues.", + "report_acknowledge": "I confirm I understand what this feature is for and accept responsibility.", + "report_submit": "Submit Report", + "turnstile_disabled": "Turnstile disabled", + "common_internal_error": "Internal error", + "resend_toast_sent": "Activation email sent. Check your inbox and spam folder.", + "resend_toast_throttled": "Too many activation emails have been requested. Please try again later.", + "resend_toast_unavailable": "No activation email can be resent from this browser. If your account isn't activated yet, logging in sends a new link.", + "resend_button": "Didn't get the email? Resend", + "expiration_label": "Expiration", + "expiration_never": "Never", + "expiration_custom": "Custom", + "expiration_days_one": "{{count}} Day", + "expiration_days_other": "{{count}} Days", + "expiration_required": "Expire date is required", + "expiration_never_desc": "This will never expire", + "expiration_expires_at": "Expires {{time}} ({{date}})", + "date_picker_placeholder": "Pick a date", + "telemetry_toast_title": "Help improve OpenShock?", + "telemetry_toast_desc": "Send diagnostics to help us fix crashes and slow API calls. Reports include the error message, stack trace and your IP. You can change this any time in Account settings.", + "telemetry_toast_no": "No thanks", + "telemetry_toast_errors": "Errors only", + "telemetry_toast_full": "Full", + "table_show_details": "Show details", + "table_hide_details": "Hide details", + "table_no_results": "No results.", + "table_sort_asc": "Sort by {{name}}, ascending", + "table_sort_desc": "Sort by {{name}}, descending", + "table_sort_none": "Sort by {{name}}, unsorted", + "cell_na": "N/A", + "cell_not_applicable": "Not applicable", + "cell_invalid": "Invalid", + "cell_unavailable": "Unavailable", + "cell_none": "None", + "oauth_login_with": "Login with {{provider}}", + "oauth_signup_with": "Signup with {{provider}}", + "signalr_connect_failed": "Failed to connect to server!", + "signalr_disconnect_failed": "Encountered error while disconnecting from server!", + "signalr_invalid_update": "Received invalid update from server!", + "signalr_invalid_log": "Received invalid log data from server!", + "signalr_invalid_ota": "Received invalid firmware update data from server!", + "ota_toast_failed": "Hub firmware update failed: {{message}}", + "ota_toast_succeeded": "Hub firmware update completed successfully!", + "ota_toast_rolled_back": "Hub firmware rolled back to previous version", + "lcg_connect_failed": "Failed to connect to live control gateway", + "terminal_toast_bootloader_failed": "Failed to enter bootloader: {{error}}", + "terminal_toast_app_mode_failed": "Failed to enter application mode: {{error}}", + "problem_account_account_not_activated_title": "Account not activated", + "problem_account_account_not_activated_desc": "Check your inbox for the activation email.", + "problem_account_activation_not_found_title": "Activation link is invalid", + "problem_account_activation_not_found_desc": "The link may have expired or already been used.", + "problem_account_activation_resend_too_many_title": "Too many activation emails requested", + "problem_account_activation_resend_too_many_desc": "Please wait a while before trying again.", + "problem_account_activation_resend_unavailable_title": "Cannot resend activation email", + "problem_account_activation_resend_unavailable_desc": "Log in again to request a new activation link.", + "problem_account_deactivate_already_deactivated_title": "Account is already deactivated", + "problem_account_deactivate_denied_privileged_title": "Privileged accounts cannot be deactivated", + "problem_account_deactivate_unauthorized_title": "You are not allowed to do this", + "problem_account_deactivated_title": "This account has been deactivated", + "problem_account_email_already_in_use_title": "That email address is already in use", + "problem_account_email_invalid_title": "That email address is not valid", + "problem_account_email_taken_title": "That email address is already in use", + "problem_account_email_too_many_requests_title": "Too many email change requests", + "problem_account_email_too_many_requests_desc": "Please wait a while before trying again.", + "problem_account_email_unchanged_title": "That is already your email address", + "problem_account_email_verify_not_found_title": "Verification link is invalid", + "problem_account_email_verify_not_found_desc": "The link may have expired or already been used.", + "problem_account_o_auth_only_title": "This account has no password", + "problem_account_o_auth_only_desc": "Sign in with the provider you signed up with.", + "problem_account_password_not_set_title": "No password set", + "problem_account_password_not_set_desc": "This account signs in through an external provider.", + "problem_account_password_old_password_invalid_title": "Current password is incorrect", + "problem_account_username_invalid_title": "That username is not allowed", + "problem_account_username_recently_changed_title": "Username changed too recently", + "problem_account_username_recently_changed_desc": "You can change your username once every 7 days.", + "problem_account_username_taken_title": "That username is already taken", + "problem_admin_user_deactivated_title": "This user is deactivated", + "problem_admin_user_not_activated_title": "This user has not been activated yet", + "problem_api_token_can_only_delete_self_title": "An API token can only delete itself", + "problem_api_token_not_found_title": "API token not found", + "problem_api_token_paused_title": "This API token is paused", + "problem_assign_lcg_bad_schema_version_title": "Unsupported hub protocol version", + "problem_assign_lcg_bad_schema_version_desc": "Update the hub firmware to connect.", + "problem_assign_lcg_no_lcg_available_title": "No gateway available", + "problem_assign_lcg_no_lcg_available_desc": "No live control gateway is available right now. Please try again later.", + "problem_authentication_account_deactivated_title": "This account has been deactivated", + "problem_authentication_account_not_activated_title": "This account has not been activated", + "problem_authentication_cookie_missing_or_invalid_title": "You are not logged in", + "problem_authentication_cookie_missing_or_invalid_desc": "Your session may have expired. Please log in again.", + "problem_authentication_header_missing_or_invalid_title": "Invalid API token", + "problem_authentication_session_invalid_title": "Session expired", + "problem_authentication_session_invalid_desc": "Please log in again.", + "problem_authentication_token_invalid_title": "Invalid API token", + "problem_authentication_unknown_error_title": "Authentication failed", + "problem_authorization_policy_not_met_title": "You do not have permission to do this", + "problem_authorization_token_only_title": "This action requires an API token", + "problem_authorization_token_permission_missing_title": "This API token is missing a required permission", + "problem_authorization_unknown_error_title": "Authorization failed", + "problem_authorization_user_session_only_title": "This action requires a logged-in session", + "problem_automation_token_not_allowed_for_account_title": "Automation tokens cannot be used with privileged accounts", + "problem_configuration_already_exists_title": "A configuration entry with that name already exists", + "problem_configuration_invalid_name_format_title": "Invalid configuration name", + "problem_configuration_invalid_name_format_desc": "Only A to Z and underscores are allowed.", + "problem_configuration_invalid_value_format_title": "Value does not match the configuration type", + "problem_configuration_not_found_title": "Configuration entry not found", + "problem_control_stats_invalid_range_title": "The from date must not be after the to date", + "problem_control_stats_invalid_time_zone_title": "Unknown time zone", + "problem_control_stats_missing_capability_title": "Control statistics are not available on this server", + "problem_device_not_found_title": "Hub not found", + "problem_device_not_online_title": "Hub is offline", + "problem_device_too_many_hubs_title": "You have reached the maximum number of hubs", + "problem_device_too_many_shockers_title": "This hub has reached its maximum number of shockers", + "problem_endpoint_retired_title": "This feature is no longer available", + "problem_expression_error_title": "Invalid filter expression", + "problem_internal_server_error_title": "Something went wrong on our end", + "problem_login_invalid_credentials_title": "Invalid username or password", + "problem_login_invalid_domain_title": "Logging in from this address is not allowed", + "problem_o_auth_connection_already_exists_title": "Your account is already connected to this provider", + "problem_o_auth_connection_already_linked_title": "This external account is already linked to another user", + "problem_o_auth_flow_anonymous_only_title": "You are already signed in", + "problem_o_auth_flow_mismatch_title": "Sign-in attempt does not match", + "problem_o_auth_flow_mismatch_desc": "Please start over.", + "problem_o_auth_flow_missing_data_title": "The provider did not return your account details", + "problem_o_auth_flow_missing_data_desc": "Please try again.", + "problem_o_auth_flow_not_found_title": "Sign-in attempt expired", + "problem_o_auth_flow_not_found_desc": "Please start over.", + "problem_o_auth_flow_unsupported_title": "Unsupported sign-in flow", + "problem_o_auth_internal_error_title": "Something went wrong during sign-in", + "problem_o_auth_internal_error_desc": "Please try again in a moment.", + "problem_o_auth_link_authenticated_user_only_title": "You must be signed in to link an external account", + "problem_o_auth_provider_mismatch_title": "Sign-in attempt does not match the provider", + "problem_o_auth_provider_mismatch_desc": "Please start over.", + "problem_o_auth_provider_unsupported_title": "This sign-in provider is not supported", + "problem_pair_code_not_found_title": "Pair code not found", + "problem_password_reset_not_found_title": "Password reset link is invalid", + "problem_password_reset_not_found_desc": "The link may have expired or already been used.", + "problem_session_not_found_title": "Session not found", + "problem_share_get_no_shares_title": "You have no shares with this user", + "problem_share_request_create_cannot_share_with_self_title": "You cannot share with yourself", + "problem_share_request_create_shocker_not_found_title": "One or more shockers were not found", + "problem_share_request_create_shocker_not_found_desc": "They may have been removed or do not belong to you.", + "problem_share_request_not_found_title": "Share invite not found", + "problem_share_user_not_found_title": "Share not found", + "problem_share_code_already_linked_title": "Shocker is already linked to your account", + "problem_share_code_cant_link_own_share_code_title": "You cannot redeem your own share code", + "problem_share_code_not_found_title": "Share code not found", + "problem_share_link_expiry_date_in_past_title": "Expiry date cannot be in the past", + "problem_share_link_not_found_title": "Public share not found", + "problem_share_link_shocker_already_in_share_link_title": "Shocker is already in this public share", + "problem_share_link_shocker_not_in_share_link_title": "Shocker is not in this public share", + "problem_shocker_control_no_permission_title": "You do not have permission to control this shocker", + "problem_shocker_control_not_found_title": "Shocker not found", + "problem_shocker_control_paused_title": "Shocker is paused", + "problem_shocker_not_found_title": "Shocker not found", + "problem_signup_registration_disabled_title": "Registration is currently disabled", + "problem_signup_username_or_email_exists_title": "That username or email is already in use", + "problem_turnstile_invalid_title": "Verification failed", + "problem_turnstile_invalid_desc": "Please complete the challenge again and retry.", + "problem_user_not_found_title": "User not found", + "problem_user_privileged_delete_denied_title": "Privileged users cannot be deleted", + "problem_validation_error_title": "Some fields are invalid", + "problem_webhook_not_found_title": "Webhook not found", + "problem_webhook_unsupported_title": "Only Discord webhooks are supported", + "problem_webhook_unsupported_desc": "Use a discord.com URL, not canary or ptb.", + "error_too_many_requests": "Too many requests", + "error_retry_after_one": "Try again in {{count}} second.", + "error_retry_after_other": "Try again in {{count}} seconds.", + "error_unexpected_response": "Unexpected server response", + "error_internal": "Internal error occurred", + "error_network": "Network error occurred", + "dev_banner": "This is the OpenShock DEVELOPMENT environment. No data is saved, and it is regularly overwritten by production data.", + "firmware_channel_bugs_warning": "This channel might contain bugs." +} From be3407e3ea88d7fb776cebe24fd713fa4689b231 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Luc=20=E2=99=A5?= Date: Thu, 12 Nov 2026 17:43:06 +0100 Subject: [PATCH 06/27] New translations en.json (Catalan) [ci skip] --- messages/ca.json | 1055 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 1055 insertions(+) create mode 100644 messages/ca.json diff --git a/messages/ca.json b/messages/ca.json new file mode 100644 index 00000000..ef4df56c --- /dev/null +++ b/messages/ca.json @@ -0,0 +1,1055 @@ +{ + "landing_tagline": "The go-to platform for safe, reliable, real low-latency remote shocking.", + "landing_section_label": "Home", + "landing_hubs_online": "Hubs online right now: ", + "landing_learn_more": "Learn More", + "landing_wiki": "Wiki", + "landing_meta_description": "Welcome to OpenShock, a free and open-source ecosystem to control various shock collars over the internet.", + "instance_meta_description": "Welcome to {{siteName}}, an independent instance of OpenShock, a free and open-source ecosystem to control various shock collars over the internet.", + "header_sidebar_toggle": "Toggle Sidebar", + "header_avatar_alt": "{{name}}'s avatar", + "header_menu_profile": "Profile", + "header_menu_settings": "Settings", + "header_menu_logout": "Logout", + "header_login": "Login", + "header_signup": "Sign Up", + "header_github_title": "OpenShock on GitHub", + "header_discord_title": "Community Discord", + "footer_made_with": "Made with by the OpenShock Team", + "footer_connection_status_label": "Server connection status", + "footer_signalr_state": "SignalR State", + "footer_frontend_version": "Frontend Version", + "footer_frontend_commit_title": "Commit {{commit}}", + "footer_backend_version": "Backend Version", + "footer_backend_commit_title": "Commit {{commit}}", + "footer_language_label": "Language", + "sidebar_home_link_label": "OpenShock home", + "sidebar_group_general": "General", + "sidebar_home": "Home", + "sidebar_shockers": "Shockers", + "sidebar_shared_shockers": "Shared Shockers", + "sidebar_hubs": "Hubs", + "sidebar_user_shares": "User Shares", + "sidebar_public_shares": "Public Shares", + "sidebar_serial_terminal": "Serial Terminal", + "sidebar_group_admin": "Admin", + "sidebar_admin_monitoring": "Monitoring", + "sidebar_admin_online_hubs": "Online Hubs", + "sidebar_admin_online_gateways": "Online Gateways", + "sidebar_admin_management": "Management", + "sidebar_admin_users": "Users", + "sidebar_admin_blacklists": "Blacklists", + "sidebar_admin_webhooks": "Webhooks", + "sidebar_admin_mail": "Mail", + "sidebar_admin_automation_tokens": "Automation Tokens", + "sidebar_admin_configuration": "Configuration", + "sidebar_group_settings": "Settings", + "sidebar_settings_api_tokens": "API Tokens", + "sidebar_settings_sessions": "Sessions", + "sidebar_settings_audit_log": "Audit Log", + "sidebar_settings_connections": "Connections", + "sidebar_settings_account": "Account Settings", + "error_meta_title": "Service Unavailable", + "error_meta_description": "OpenShock is currently unavailable", + "error_meta_logo_alt": "OpenShock Logo", + "error_fallback_message": "Something went wrong.", + "error_not_found_message": "Page not found", + "error_not_found_description": "The page you're looking for doesn't exist.", + "error_unexpected_description": "An unexpected error occurred.", + "error_go_back": "Go back", + "auth_layout_logo_alt": "OpenShock Logo", + "auth_layout_invalid_redirect_removed": "An invalid redirect URL was removed for your safety.", + "auth_activate_breadcrumb": "Activate Account", + "auth_activate_title": "Activate Account", + "auth_activate_activating": "Activating your account...", + "auth_activate_success": "Your account has been activated", + "auth_activate_failed": "This activation link is invalid or has expired", + "auth_activate_missing_token": "Missing activation token", + "auth_activate_continue": "Continue to login", + "auth_activate_toast_success": "Account activated", + "auth_forgot_breadcrumb": "Forgot Password", + "auth_forgot_title": "Forgot Password", + "auth_forgot_description": "Enter your email to reset your password", + "auth_forgot_email_label": "Email", + "auth_forgot_email_placeholder": "Email", + "auth_forgot_submit": "Reset Password", + "auth_forgot_signin_prompt": "Remember your password? Sign in", + "auth_forgot_mail_disabled": "Password resets are unavailable on this instance because it has no mail provider configured. Please contact your administrator for help recovering your account.", + "auth_forgot_toast_sent": "Reset password request has been sent to the given email", + "auth_login_breadcrumb": "Login", + "auth_login_title": "Welcome back", + "auth_login_loading_methods": "Loading available login methods", + "auth_login_choose_method": "Login with one of these methods", + "auth_login_with_account": "Login with your OpenShock Account", + "auth_login_activation_after_signup": "Your account has been created. We've sent an activation link to your email address. Check your inbox and spam folder.", + "auth_login_activation_pending": "Your account isn't activated yet. We've sent an activation link to your email address. Check your inbox and spam folder. If nothing arrives, try logging in again later to get a new link.", + "auth_login_oauth_only": "This account has no password. Sign in with the provider you signed up with.", + "auth_login_oauth_only_with_buttons": "This account has no password. Sign in with the provider you signed up with using the buttons above.", + "auth_login_or_continue_with": "Or continue with", + "auth_login_username_label": "Username or Email", + "auth_login_password_label": "Password", + "auth_login_submit": "Login", + "auth_login_signup_prompt": "Don't have an account? Sign up", + "auth_login_legal": "By clicking Login, you agree to our Terms of Service and Privacy Policy.", + "auth_oauth_create_breadcrumb": "Sign Up With {{provider}}", + "auth_oauth_create_title": "Sign Up With {{provider}}", + "auth_oauth_create_description": "Complete your account details", + "auth_oauth_create_username_label": "Username", + "auth_oauth_create_username_placeholder": "Username", + "auth_oauth_create_email_label": "Email", + "auth_oauth_create_email_placeholder": "Email", + "auth_oauth_create_submit": "Sign Up", + "auth_oauth_create_legal": "By clicking Sign Up, you agree to our Terms of Service and Privacy Policy.", + "auth_oauth_error_breadcrumb": "Authentication Error", + "auth_oauth_error_title": "Authentication Error", + "auth_oauth_error_back": "Back to login", + "auth_reset_breadcrumb": "Reset Password", + "auth_reset_title": "Reset Password", + "auth_reset_checking": "Verifying reset link...", + "auth_reset_choose_password": "Choose a new password for your account", + "auth_reset_invalid": "This reset link is invalid or has expired", + "auth_reset_password_label": "New Password", + "auth_reset_password_placeholder": "New Password", + "auth_reset_confirm_label": "Confirm New Password", + "auth_reset_confirm_placeholder": "Confirm New Password", + "auth_reset_submit": "Reset Password", + "auth_reset_request_new": "Request a new reset link", + "auth_reset_toast_success": "Password has been reset", + "auth_signup_breadcrumb": "Sign Up", + "auth_signup_toast_created_mail": "Account created successfully. Please check your email to verify your account.", + "auth_signup_toast_created_no_mail": "Account created successfully. You can log in now.", + "auth_signup_dialog_title": "Welcome! Thank you for signing up! ❤️", + "auth_signup_dialog_created_mail": "Your account has been created. 🎉 Please check your email to verify your account.", + "auth_signup_dialog_verify_then_login": "After verifying your email, you can log in to your account.", + "auth_signup_dialog_created_no_mail": "Your account has been created and is ready to use. 🎉", + "auth_signup_dialog_login_now": "You can log in to your account now.", + "auth_signup_title": "Create your account", + "auth_signup_loading_methods": "Loading available sign-up methods", + "auth_signup_using_email": "Signing up using email", + "auth_signup_choose_method": "Choose your preferred sign-up method", + "auth_signup_back": "Back", + "auth_signup_username_label": "Username", + "auth_signup_username_placeholder": "John OpenShock", + "auth_signup_email_label": "Email", + "auth_signup_email_placeholder": "john@example.com", + "auth_signup_password_label": "Password", + "auth_signup_password_placeholder": "Password", + "auth_signup_confirm_label": "Confirm Password", + "auth_signup_confirm_placeholder": "Confirm Password", + "auth_signup_submit": "Create Account", + "auth_signup_signin_prompt": "Already have an account? Sign in", + "auth_signup_or": "Or", + "auth_signup_with_email": "Signup with Email", + "auth_signup_legal": "By clicking Create Account, you agree to our Terms of Service and Privacy Policy.", + "auth_verify_breadcrumb": "Verify Email", + "auth_verify_title": "Verify Email", + "auth_verify_verifying": "Verifying your email address...", + "auth_verify_success": "Your email has been verified", + "auth_verify_failed": "This verification link is invalid or has expired", + "auth_verify_missing_token": "Missing verification token", + "auth_verify_continue": "Continue to login", + "auth_verify_toast_success": "Email verified", + "common_cancel": "Cancel", + "common_delete": "Delete", + "common_edit": "Edit", + "common_share": "Share", + "common_copy_id": "Copy ID", + "common_id_copied": "ID copied to clipboard", + "common_open_menu": "Open menu", + "common_refresh": "Refresh", + "common_settings": "Settings", + "common_clear": "Clear", + "common_online": "Online", + "common_offline": "Offline", + "common_paused": "Paused", + "common_resume": "Resume", + "common_resuming": "Resuming...", + "common_coming_soon": "(Coming soon)", + "common_save_changes": "Save Changes", + "common_danger_zone": "Danger Zone", + "common_name": "Name", + "control_intensity": "Intensity", + "control_duration": "Duration", + "control_max_intensity": "Max Intensity", + "control_max_duration": "Max Duration", + "control_vibration": "Vibration", + "control_value": "Value", + "control_live_intensity": "Live intensity", + "control_type_stop": "Stop", + "control_type_shock": "Shock", + "control_type_vibrate": "Vibrate", + "control_type_sound": "Sound", + "live_tooltip_active": "Live via {{gateway}} ({{country}}), {{latency}}ms", + "live_tooltip_connecting": "Connecting...", + "live_tooltip_connect": "Connect to Live Control", + "live_tooltip_hub_start": "Ctrl+click to start the whole hub", + "live_tooltip_hub_stop": "Ctrl+click to stop the whole hub", + "pause_resume_shocker": "Resume shocker", + "pause_pause_shocker": "Pause shocker", + "pause_resume_all": "Resume all shockers", + "pause_pause_all": "Pause all shockers", + "shocker_label": "Shocker", + "shocker_hub": "Hub", + "shocker_select_hub": "Select hub", + "shocker_rf_id": "RF ID", + "shocker_rf_id_invalid": "RF ID must be a whole number between {{min}} and {{max}}.", + "shocker_model": "Model", + "shocker_select_model": "Select model", + "shocker_name_placeholder": "Shocker name", + "shocker_menu_view_logs": "View Logs", + "shocker_delete_title": "Delete Shocker", + "shocker_delete_desc": "Are you sure you want to delete \"{{name}}\"? This action cannot be undone.", + "shocker_toast_deleted": "Shocker \"{{name}}\" deleted", + "shocker_toast_paused": "Shocker paused", + "shocker_toast_resumed": "Shocker resumed", + "shocker_add_desc": "Register a new shocker to one of your hubs.", + "shocker_add_name_placeholder": "My Shocker", + "shockers_title": "Shockers", + "shockers_subtitle": "Every shocker paired to your hubs.", + "shockers_loading": "Loading shockers...", + "shockers_toast_refreshed": "Shockers refreshed", + "shockers_toast_need_hub": "You need to create a hub before adding shockers.", + "shockers_toast_added": "Shocker added", + "shockers_unknown_module": "Unknown module type", + "shockers_add": "Add Shocker", + "shockers_view_mode": "View mode", + "shockers_mode_classic": "Classic", + "shockers_mode_rich": "Rich", + "shockers_mode_simple": "Simple", + "shockers_mode_map": "Map", + "shockers_group_by_hub": "Group by Hub", + "shockers_global_limits": "Global Limits", + "shockers_logs_label": "Logs", + "shockers_empty_title": "No shockers yet", + "shockers_empty_no_hubs": "Create a hub first, then add shockers to it.", + "shockers_empty_has_hubs": "Add a shocker to one of your hubs to get started.", + "shockers_create_hub": "Create a Hub", + "shockers_count_one": "{{count}} shocker", + "shockers_count_other": "{{count}} shockers", + "shared_shockers_title": "Shared Shockers", + "shared_shockers_subtitle": "Shockers other users have shared with you.", + "shared_shockers_empty_title": "No shockers have been shared with you yet.", + "shared_shockers_empty_desc": "When someone shares their shockers with you, they'll appear here.", + "shocker_logs_title": "Shocker Logs", + "shocker_logs_subtitle": "Every control command sent to your shockers.", + "shocker_logs_live_title": "New logs appear in real time", + "shocker_logs_paused_title": "Live updates pause when sorting or viewing a page other than the first", + "shocker_logs_live": "Live", + "shocker_logs_col_time": "Time", + "shocker_logs_col_type": "Type", + "shocker_logs_col_by": "By", + "shocker_logs_filter_label": "Filter by shocker", + "shocker_logs_filter_placeholder": "Search shockers...", + "shocker_logs_filter_all": "All shockers", + "shocker_logs_filter_none": "No matching shockers", + "shocker_edit_title": "Edit Shocker", + "shocker_edit_subtitle": "Change this shocker's details or remove it.", + "shocker_edit_back": "Back to Shockers", + "shocker_edit_load_failed": "Failed to load shocker.", + "shocker_edit_loading": "Loading shocker...", + "shocker_edit_details_title": "Shocker Details", + "shocker_edit_details_desc": "Update the name, RF ID, and model for this shocker.", + "shocker_edit_pause_state": "Pause State", + "shocker_edit_is_paused": "Shocker is paused", + "shocker_edit_is_active": "Shocker is active", + "shocker_edit_toast_updated": "Shocker updated", + "shocker_edit_delete_desc": "Permanently delete this shocker. This action cannot be undone.", + "common_close": "Close", + "common_continue": "Continue", + "common_loading": "Loading...", + "common_previous": "Previous", + "common_next": "Next", + "common_steps": "Steps", + "common_step_label": "Step {{number}}: {{title}}", + "common_copy": "Copy", + "common_copied": "Copied", + "common_never": "Never", + "common_error": "Error: {{message}}", + "terminal_title": "Serial Terminal", + "terminal_connecting": "Connecting...", + "terminal_help_button": "I'm having trouble, help?", + "terminal_back_to_modes": "Back to mode picker", + "terminal_mode_configure": "Configure Device", + "terminal_mode_configure_desc": "Configure WiFi, authentication, and more. Includes an interactive serial console.", + "terminal_mode_flash": "Flash Firmware", + "terminal_mode_flash_desc": "Install or update firmware on a connected device.", + "terminal_mode_raw": "Serial Monitor", + "terminal_mode_raw_desc": "Just the console. Read device logs and send commands.", + "terminal_step_channel": "Select Channel", + "terminal_step_board": "Select Board", + "terminal_go_to_step": "Go to step {{number}}: {{title}}", + "terminal_erase": "Erase before flashing", + "terminal_erase_desc": "Clears all data on the device including existing configs", + "terminal_unsupported": "Your browser does not support this feature.", + "terminal_update_browser": "Please update your browser to the latest version.", + "terminal_use_browsers": "Please use one of the following browsers:", + "terminal_connect_failed_bootloader": "Could not enter bootloader mode", + "terminal_connect_failed": "Device connection failed", + "terminal_connect_failed_desc": "We couldn't establish a serial connection with the device.", + "terminal_quick_tries": "Quick things to try:", + "terminal_try_replug": "Unplug and replug the device.", + "terminal_try_cable": "Try a different USB cable or port.", + "terminal_try_driver": "Make sure the serial driver is installed.", + "terminal_open_troubleshooter": "Open troubleshooter", + "terminal_log_reset_no_device": "Host-side error during reset: no device!", + "terminal_log_reset_error": "Host-side error during reset: {{error}}", + "terminal_log_send_no_device": "Couldn't send: no device!", + "terminal_log_send_error": "Couldn't send: {{error}}", + "terminal_log_firmware_disconnected": "Firmware disconnected: {{error}}", + "terminal_log_erase_failed": "Failed to erase flash: {{error}}", + "terminal_log_hard_reset_failed": "Failed to hard reset: {{error}}", + "terminal_log_flash_complete": "Flash complete", + "terminal_log_flash_failed": "Failed to flash: {{error}}", + "terminal_log_command_failed": "Failed to write application command: {{error}}", + "terminal_help_title": "Troubleshooter", + "terminal_help_desc": "Work through these steps in order. Each one rules out a common cause.", + "terminal_help_step_cable": "USB cable", + "terminal_help_step_port": "USB port", + "terminal_help_step_driver": "Install driver", + "terminal_help_step_manual": "Manual driver update", + "terminal_help_step_discord": "Ask on Discord", + "terminal_help_cable_body": "Many USB-C and micro-USB cables are charge-only and don't carry data. Swap to a known-good data cable (one you've used to transfer files or connect other devices) and reconnect the hub.", + "terminal_help_port_body": "Plug the device directly into a USB port on your computer. Avoid USB hubs, docking stations, and front-panel ports if possible; these are common sources of power and signal issues. If you're on a desktop, try a port on the back of the machine.", + "terminal_help_driver_download": "Download the CP210x driver:", + "terminal_help_driver_extract": "Extract the contents of the zip file to a folder on your computer.", + "terminal_help_driver_run": "Open the folder and run {{installer}}. Follow the prompts to install.", + "terminal_help_driver_reconnect": "Reconnect the device.", + "terminal_help_manual_intro": "If the driver installer ran but the device still doesn't show up:", + "terminal_help_manual_open": "Open Device Manager (press Win + X and select Device Manager).", + "terminal_help_manual_ports": "Under Ports (COM & LPT), look for an entry like:", + "terminal_help_manual_missing": "If it's missing, the device isn't being detected by Windows at all; revisit the cable and port steps.", + "terminal_help_manual_update": "Right-click the device and pick Update Driver.", + "terminal_help_manual_browse": "Choose Browse my computer for drivers and select the folder you extracted the driver zip into. Make sure Include subfolders is checked.", + "terminal_help_manual_success": "On success, the entry should now read {{deviceName}}.", + "terminal_help_discord_intro": "Still stuck after all of the above? Hop into our Discord server and ask in the {{channel}} channel. Please include:", + "terminal_help_discord_os": "your operating system and browser", + "terminal_help_discord_device": "the device you're using (board model, where you got it)", + "terminal_help_discord_tried": "what you've already tried from the previous steps", + "terminal_help_discord_errors": "any error messages or relevant terminal output", + "terminal_help_discord_join": "Join our Discord server", + "terminal_risk_title": "⚠️ UNSTABLE FIRMWARE", + "terminal_risk_intro": "You are about to flash experimental firmware that is known to be unstable.", + "terminal_risk_brick": "This may permanently brick your device, require manual recovery, or render it unusable.", + "terminal_risk_no_support": "We will NOT provide support for issues caused by this firmware.", + "terminal_risk_acknowledge": "I understand this is entirely my responsibility", + "terminal_risk_abort": "Abort", + "terminal_risk_accept": "I ACCEPT FULL RESPONSIBILITY", + "firmware_channel_recommended": "This is the recommended channel.", + "firmware_channel_danger": "DO NOT USE THIS UNLESS YOU KNOW WHAT YOU ARE DOING", + "firmware_channel_stable": "Stable", + "firmware_channel_beta": "Beta", + "firmware_channel_develop": "Develop", + "terminal_board_select": "Select a board...", + "terminal_board_search": "Search boards...", + "terminal_board_none": "No board found.", + "terminal_flash_button": "Flash", + "terminal_flash_progress": "Flash Progress: {{status}}", + "terminal_flash_idle": "Idle", + "terminal_flash_no_device": "No device selected.", + "terminal_flash_resetting": "Resetting...", + "terminal_flash_downloading": "Downloading firmware...", + "terminal_flash_download_failed": "Failed to download firmware.", + "terminal_flash_flashing": "Flashing firmware...", + "terminal_flash_rebooting": "Rebooting device... (Reconnect to power manually if stuck)", + "terminal_flash_done": "Rebooted device! Flashing complete.", + "terminal_port_select": "Select Device", + "terminal_port_disconnect": "Disconnect Device", + "terminal_port_connected": "Device connected: {{id}}", + "terminal_console": "Console", + "terminal_connected_device": "Connected device", + "terminal_resize": "Resize terminal panel", + "terminal_reboot": "Reboot", + "terminal_disconnect": "Disconnect", + "terminal_fullscreen_exit_esc": "Exit fullscreen (Esc)", + "terminal_fullscreen_exit": "Exit fullscreen", + "terminal_fullscreen_fill": "Fill the window", + "terminal_command_label": "Serial command", + "terminal_command_placeholder": "Type a command...", + "terminal_command_send": "Send command", + "terminal_colors": "Colors", + "terminal_colors_menu": "Colors...", + "terminal_colors_label": "Console colors", + "terminal_colors_close": "Close colors", + "terminal_color_input": "{{name}} color", + "terminal_colors_reset": "Reset to defaults", + "terminal_color_bg": "Background", + "terminal_color_fg": "Text", + "terminal_color_ts": "Timestamp", + "terminal_color_error": "Error", + "terminal_color_warning": "Warning", + "terminal_color_info": "Info", + "terminal_color_debug": "Debug", + "terminal_color_verbose": "Verbose", + "terminal_options": "Options", + "terminal_options_label": "Console options", + "terminal_hide_system": "Hide system messages", + "terminal_stick_bottom": "Stick to bottom", + "terminal_raw_output": "Raw output", + "terminal_timestamps": "Timestamps", + "terminal_timestamp_uptime": "Uptime", + "terminal_timestamp_local": "Local", + "terminal_timestamp_ms": "Ms", + "terminal_timestamp_off": "Off", + "terminal_copy_settings": "Copy settings", + "terminal_import_settings": "Import settings", + "terminal_copy_selection": "Copy selection", + "terminal_copy_all": "Copy all output", + "terminal_toast_selection_copied": "Selection copied", + "terminal_toast_output_copied": "Console output copied", + "terminal_toast_settings_copied": "Console settings copied", + "terminal_toast_clipboard_unreadable": "Could not read the clipboard", + "terminal_toast_settings_imported": "Console settings imported", + "terminal_toast_settings_invalid": "Clipboard does not contain console settings", + "common_try_again": "Try again", + "terminal_cfg_intro": "Values are sent to the device via UART. Read the device's response in the console below. Commands without an argument act as getters; use the button next to each field to read the current value.", + "terminal_cfg_rf_title": "RF Transmitter", + "terminal_cfg_rf_desc": "Controls the shocker RF output.", + "terminal_cfg_tx_pin": "TX GPIO pin", + "terminal_cfg_example": "e.g. {{value}}", + "terminal_cfg_read_value": "Read current value", + "terminal_cfg_set": "Set", + "terminal_cfg_read": "Read", + "terminal_cfg_reading": "Reading…", + "terminal_cfg_apply": "Apply", + "terminal_cfg_keepalive": "Keepalive enabled", + "terminal_cfg_keepalive_desc": "Periodically pings paired shockers to keep them awake.", + "terminal_cfg_estop_title": "Emergency Stop", + "terminal_cfg_estop_desc": "Hardware button that halts all output.", + "terminal_cfg_estop_enabled": "EStop enabled", + "terminal_cfg_estop_pin": "EStop GPIO pin", + "terminal_cfg_estop_note": "Note: {{latching}} and {{active}} have no dedicated commands; set them via the JSON config below.", + "terminal_cfg_wifi_title": "WiFi", + "terminal_cfg_wifi_desc": "Station credentials and device hostname.", + "terminal_cfg_hostname": "Hostname", + "terminal_cfg_networks": "Networks (JSON array)", + "terminal_cfg_invalid_json_array": "Must be a valid JSON array", + "terminal_cfg_ap_note": "AP settings ({{ssid}}, {{password}}, {{disabled}}, {{staDisabled}}, {{offlineMode}}) have no dedicated commands; use the JSON config.", + "terminal_cfg_backend_title": "Backend", + "terminal_cfg_backend_desc": "OpenShock server and authentication.", + "terminal_cfg_domain": "Domain", + "terminal_cfg_domain_restart": "Setting the domain will restart the device.", + "terminal_cfg_auth_token": "Auth token", + "terminal_cfg_auth_token_placeholder": "Paste device token", + "terminal_cfg_hide": "Hide", + "terminal_cfg_show": "Show", + "terminal_cfg_serial_title": "Serial Input", + "terminal_cfg_echo": "Echo enabled", + "terminal_cfg_echo_desc": "Print typed characters back to the console.", + "terminal_cfg_advanced_title": "Advanced: full config", + "terminal_cfg_advanced_desc": "For fields without dedicated commands (captive portal, OTA, LAN, etc.), replace the entire config.", + "terminal_cfg_json_config": "JSON config", + "terminal_cfg_invalid_json": "Must be valid JSON", + "terminal_cfg_read_json": "Read current config as JSON", + "terminal_cfg_json_restart": "Applying a JSON config will restart the device.", + "terminal_cfg_raw_config": "Raw FlatBuffer config (base64)", + "terminal_cfg_invalid_base64": "Must be a valid base64 string", + "terminal_cfg_read_raw": "Read current config as base64", + "terminal_cfg_factory_reset": "Factory reset", + "terminal_cfg_factory_reset_desc": "Wipes the entire device configuration.", + "terminal_cfg_factory_reset_title": "Factory reset device?", + "terminal_cfg_factory_reset_action": "Wipe config", + "terminal_cfg_factory_reset_confirm": "This will erase all configuration on the device; WiFi networks, backend credentials, pins, and all other settings. The device will be reset to defaults.", + "terminal_cfg_read_failed_json_title": "Couldn't read the JSON config", + "terminal_cfg_read_failed_raw_title": "Couldn't read the raw config", + "terminal_cfg_read_failed_desc": "The device didn't respond after {{attempts}} attempts.", + "terminal_cfg_common_causes": "Common causes:", + "terminal_cfg_cause_busy": "The device is busy handling another command.", + "terminal_cfg_cause_disconnected": "The device disconnected or rebooted.", + "terminal_cfg_cause_unsupported": "The firmware version doesn't support this command.", + "common_status": "Status", + "common_version": "Version", + "common_created": "Created", + "common_create": "Create", + "common_done": "Done", + "common_enable": "Enable", + "common_disable": "Disable", + "common_are_you_sure": "Are you sure?", + "common_generating": "Generating...", + "hubs_title": "Hubs", + "hubs_subtitle": "Every hub registered to your account.", + "hubs_add": "Add Hub", + "hubs_load_failed": "Failed to load hubs.", + "hubs_empty_title": "No hubs yet", + "hubs_empty_desc": "A hub is the device that relays commands to your shockers. Add one to get started.", + "hubs_create_title": "Create hub", + "hubs_name_label": "Hub Name", + "hubs_name_placeholder": "My Hub", + "hub_toast_not_connected": "Not connected to the server", + "hub_toast_try_later": "Try again in a moment.", + "hub_reboot_title": "Reboot {{name}}?", + "hub_reboot_desc": "The hub will disconnect and restart. Any shockers paired to it stop responding until it comes back online.", + "hub_reboot": "Reboot", + "hub_hotspot_enable_title": "Enable Wi-Fi hotspot on {{name}}?", + "hub_hotspot_disable_title": "Disable Wi-Fi hotspot on {{name}}?", + "hub_hotspot_enable_desc": "The hub broadcasts its own setup network. It stays reachable on your Wi-Fi, but the hotspot is open to anyone in range until you turn it off.", + "hub_hotspot_disable_desc": "The setup hotspot shuts down. If the hub is not already on your Wi-Fi you will need physical access to set it up again.", + "hub_delete_desc": "You are about to delete hub {{name}}.", + "hub_delete_shockers": "This will also delete the following shockers:", + "hub_edit_title": "Edit hub", + "hub_edit_apply": "Apply", + "hub_pair_title_generate": "Generate pair code?", + "hub_pair_title_generated": "Pair code generated", + "hub_pair_title_paired": "Hub paired", + "hub_pair_consumed": "{{name}} consumed this pair code and is now paired.", + "hub_pair_used": "The code has been used and is no longer valid.", + "hub_pair_generated_for": "Pair code generated for {{name}}.", + "hub_copy_now": "The code below will not be accessible later, please copy it now and update clients with it.", + "hub_pair_generate_for": "You are about to generate a pair code for {{name}}.", + "hub_pair_valid_for": "It will be valid for 15 minutes after its creation.", + "hub_pair_one_active": "There is only one active pair code per hub, newly generated ones will override the older active ones.", + "hub_pair_complete": "Pairing complete", + "hub_pair_code_label": "Pair code:", + "hub_pair_copied_close": "Code has been copied, close", + "hub_pair_get": "Get Pair Code", + "hub_token_generated": "Token generated", + "hub_token_generated_for": "New token generated for {{name}}.", + "hub_token_regenerate_for": "You are about to regenerate the token for {{name}}.", + "hub_token_invalidate": "This action will invalidate the current token and disconnect clients using it.", + "hub_token_confirm": "Are you sure you want to do this?", + "hub_token_label": "New token:", + "hub_token_copied_close": "Token has been copied, close", + "hub_token_regenerate": "Regenerate Token", + "hub_menu_update": "Update", + "hub_menu_label": "Hub", + "hub_menu_hotspot_enable": "Enable Wi-Fi hotspot", + "hub_menu_hotspot_disable": "Disable Wi-Fi hotspot", + "hub_menu_pair": "Pair", + "hub_menu_estop": "Emergency Stop", + "hub_update_breadcrumb": "Update", + "hub_update_unknown_hub": "Unknown Hub", + "hub_update_unknown_task": "Unknown Task", + "hub_update_task_metadata": "Fetching Metadata", + "hub_update_task_preparing": "Preparing for Update", + "hub_update_task_flash_fs": "Flashing Filesystem", + "hub_update_task_verify_fs": "Verifying Filesystem", + "hub_update_task_flash_app": "Flashing Application", + "hub_update_task_bootable": "Marking Application Bootable", + "hub_update_task_rebooting": "Rebooting", + "hub_update_status_started": "Started", + "hub_update_status_running": "Running", + "hub_update_status_finished": "Finished", + "hub_update_status_error": "Error", + "hub_update_status_timeout": "Timeout", + "hub_update_confirm_title": "Confirm firmware update", + "hub_update_confirm_desc": "Update {{name}} to version {{version}}?", + "hub_update_unstable_warning": "This version may not be from the stable channel and could contain bugs.", + "hub_update_title": "Update {{name}}", + "hub_update_subtitle": "Manage firmware updates for this hub.", + "hub_update_status_title": "Hub Status", + "hub_update_firmware": "Firmware: {{version}}", + "hub_update_confirm": "Update", + "hub_update_success": "Update completed successfully", + "hub_update_rolled_back": "Device rolled back to previous version", + "hub_update_back": "Back to Hubs", + "hub_update_flash_again": "Flash Again", + "hub_update_card_title": "Firmware Update", + "hub_update_card_desc": "Select a firmware channel and version to install.", + "hub_update_to": "Update to {{version}}", + "hub_update_must_be_online": "Hub must be online to start an update.", + "hub_update_updating_to": "Updating to {{version}}...", + "hub_update_total": "Total", + "hub_update_task": "Task", + "hub_update_history": "Update History", + "hub_update_no_history": "No update history found for this hub.", + "hub_update_col_id": "ID", + "hub_update_col_started": "Started", + "hub_update_col_message": "Message", + "hub_update_loading": "Loading hub information...", + "hub_update_not_found": "Hub not found.", + "home_breadcrumb": "Home", + "home_welcome": "Welcome back", + "home_welcome_name": "Welcome back, {{name}}", + "home_subtitle": "Here's an overview of your OpenShock setup.", + "home_hubs_online": "{{count}} online", + "home_hub_status": "Hub Status", + "home_no_hubs": "No hubs", + "home_all_online": "All online", + "home_all_offline": "All offline", + "home_some_online": "{{online}}/{{total}} online", + "home_quick_links": "Quick Links", + "home_my_shockers": "My Shockers", + "home_my_shockers_desc": "Control your shockers", + "home_hubs_desc": "Manage your hubs", + "home_shared_desc": "Shockers shared with you", + "home_public_desc": "Manage share links", + "home_get_started": "Get Started", + "home_get_started_desc": "You don't have any hubs yet. Create a hub to connect your first device, then add shockers to it.", + "home_set_up_hub": "Set Up a Hub", + "home_first_shocker": "Add Your First Shocker", + "home_first_shocker_desc_one": "You have {{count}} hub set up. Add a shocker to start controlling it.", + "home_first_shocker_desc_other": "You have {{count}} hubs set up. Add a shocker to start controlling it.", + "home_go_to_shockers": "Go to Shockers", + "profile_title": "Profile", + "profile_coming_soon": "Profile is coming soon", + "profile_coming_soon_desc": "Your public profile is not available yet. Account details live under Settings.", + "common_retry": "Retry", + "common_never_used": "Never used", + "common_expires": "Expires {{time}}", + "common_search_placeholder": "Search...", + "common_unknown": "Unknown", + "settings_breadcrumb_account": "Account", + "account_subtitle": "Your sign-in details and account actions.", + "account_change_username": "Change Username", + "account_change_email": "Change Email", + "account_change_password": "Change Password", + "account_username_label": "Username", + "account_email_label": "Email", + "account_password_label": "Password", + "account_new_password_label": "New Password", + "account_confirm_password_label": "Confirm New Password", + "account_oauth_only": "Not available for OAuth-only accounts", + "account_oauth_no_password": "This account signs in via OAuth and has no password.", + "account_diagnostics": "Diagnostics", + "account_diagnostics_desc": "Help us fix crashes and slow API calls. Reports include the error message, stack trace and your IP. Off by default.", + "account_diagnostics_level": "Diagnostics level", + "account_telemetry_off": "Off", + "account_telemetry_off_desc": "Send nothing.", + "account_telemetry_errors": "Errors", + "account_telemetry_errors_desc": "Send browser error reports only.", + "account_telemetry_full": "Full", + "account_telemetry_full_desc": "Error reports plus traces of API calls (no page navigations).", + "account_toast_deactivated": "Account deactivated successfully", + "account_deactivate_title": "Deactivate account", + "account_deactivate_desc": "Are you sure you want to deactivate your account?", + "account_deactivate": "Deactivate Account", + "account_email_title": "Change email", + "account_email_desc": "Enter your new email address and confirm with your current password.", + "account_email_toast_sent": "Verification email sent to {{email}}. Click the link in that email to apply the change.", + "account_new_email": "New Email", + "account_current_password": "Current Password", + "account_password_title": "Change password", + "account_password_desc": "Enter your current password and choose a new one.", + "account_password_toast": "Password has been changed", + "account_username_title": "Change username", + "account_username_desc": "Enter a new username.", + "account_new_username": "New Username", + "account_username_toast": "Username changed successfully", + "tokens_subtitle": "API Tokens are used to authenticate with the OpenShock API.", + "tokens_generate": "Generate Token", + "tokens_toast_refreshed": "Tokens refreshed successfully", + "tokens_empty_title": "No API tokens", + "tokens_empty_desc": "Generate a token to authenticate with the OpenShock API.", + "tokens_created_on": "Created {{date}}", + "tokens_last_used": "Last used {{time}}", + "tokens_never_expires": "Never expires", + "tokens_load_failed": "Failed to load API tokens.", + "token_toast_edited": "Token edited successfully", + "token_name_required": "Name is required", + "token_name_too_long": "Name is too long", + "token_edit_title": "Edit API token", + "token_name_label": "Token Name", + "token_name_placeholder": "Token name...", + "token_permissions": "Permissions", + "token_perm_category_shockers": "Shockers", + "token_perm_category_devices": "Hubs", + "token_perm_category_usershares": "User Shares", + "token_perm_category_publicshares": "Public Shares", + "token_perm_use": "Use", + "token_perm_edit": "Edit", + "token_perm_pause": "Pause", + "token_perm_auth": "Authenticate", + "token_shocker_control": "Shocker Control", + "token_toast_paused": "Token paused", + "token_toast_resumed": "Token resumed", + "token_delete_title": "Delete API token", + "token_delete_desc": "Are you sure you want to delete {{name}}?", + "token_delete_permanent": "This action cannot be undone. This will permanently delete the token.", + "token_toast_deleted": "Token deleted successfully", + "token_resume": "Resume token", + "token_pause": "Pause token", + "token_mode_clamp_desc": "Clamp: requests outside the allowed range are capped to the nearest limit (the min or the max).", + "token_mode_lerp_desc": "Lerp: the full input range is linearly rescaled so it fits within your allowed min–max range.", + "token_paused_desc": "A paused token may not send shocker control messages.", + "token_intensity_range": "Intensity range", + "token_duration_range": "Duration range", + "token_new_breadcrumb": "New", + "token_redirect_not_allowed": "The provided redirect_uri is not allowed. Only loopback addresses or custom application schemes are permitted.", + "token_params_missing": "Required get parameters are missing. Make sure name, redirect_uri, and permissions are provided.", + "token_invalid_permissions": "Invalid permissions provided: {{list}}", + "token_toast_created": "Token created successfully", + "token_request_title": "API Token Request", + "token_access_granted": "Access granted", + "token_shared_redirecting": "The token has been created and shared with the application. Redirecting you back to {{uri}}.", + "token_not_redirected": "If you are not redirected automatically, use the button below.", + "token_finish": "Finish", + "token_generated_title": "API Token Generated", + "token_copy_now": "Please copy your API Token now, you will not be able to view it again later!", + "token_new_title": "New API Token", + "token_external_desc": "An external application is requesting access to your account. Review and adjust the permissions below before allowing access.", + "token_new_desc": "Configure and generate a new API token for your account.", + "token_external_requesting": "{{name}} is requesting an API Token. Your token will be shared with the application at {{uri}}.", + "token_allow": "Allow", + "token_generate": "Generate", + "token_deny": "Deny", + "sessions_subtitle": "Every active session on your account. Revoke any you do not recognize.", + "sessions_unknown_device": "Unknown device", + "sessions_toast_refreshed": "Sessions refreshed successfully", + "sessions_load_failed": "Failed to load sessions.", + "sessions_empty_title": "No active sessions", + "sessions_empty_desc": "Sessions appear here once you sign in from a browser or app.", + "sessions_last_seen": "Last seen {{time}}", + "sessions_signed_in": "Signed in {{time}}", + "session_toast_revoked": "Session revoked successfully", + "session_revoke_title": "Revoke session", + "session_revoke": "Revoke", + "session_revoke_desc": "Are you sure you want to revoke this session?", + "session_revoke_from": "Session logged in from {{ip}} using {{agent}}", + "connections_title": "OAuth Connections", + "connections_subtitle": "Link or unlink third-party accounts to sign in faster and keep your profile in sync.", + "connections_toast_linked": "Account linked.", + "connections_toast_cancelled": "Link flow cancelled.", + "connections_toast_failed": "Linking failed.", + "connections_toast_removed": "Connection removed", + "connections_refreshing": "Refreshing…", + "connections_link_new": "Link new provider", + "connections_empty_title": "No connections yet", + "connections_empty_desc": "Choose “Link new provider” above to connect available providers.", + "connections_unlink": "Unlink", + "connections_load_failed": "Failed to load OAuth connections.", + "connections_unlink_title": "Unlink {{name}}?", + "connections_unlink_title_generic": "Unlink this account?", + "connections_unlink_desc": "You'll no longer be able to sign in with this provider unless you link it again.", + "provider_starting": "Starting {{name}}...", + "provider_link": "Link {{name}}", + "audit_subtitle": "Security-relevant activity on your account. Review anything you do not recognize.", + "audit_col_time": "Time", + "audit_col_action": "Action", + "audit_col_details": "Details", + "audit_col_reason": "Reason", + "audit_col_ip": "IP address", + "audit_col_device": "Device", + "audit_action_login": "Signed in", + "audit_action_logout": "Signed out", + "audit_action_password_changed": "Password changed", + "audit_action_email_change_requested": "Email change requested", + "audit_action_email_changed": "Email changed", + "audit_action_username_changed": "Username changed", + "audit_action_api_token_created": "API token created", + "audit_action_api_token_deleted": "API token deleted", + "audit_action_oauth_connected": "Connection added", + "audit_action_oauth_disconnected": "Connection removed", + "audit_action_account_deactivated": "Account deactivated", + "audit_action_account_reactivated": "Account reactivated", + "audit_action_account_deleted": "Account deleted", + "audit_action_automation_token_created": "Automation token created", + "audit_action_automation_token_updated": "Automation token updated", + "audit_action_automation_token_rotated": "Automation token rotated", + "audit_action_automation_token_deleted": "Automation token deleted", + "audit_action_automation_token_used": "Automation token used", + "audit_meta_session": "Session {{id}}", + "audit_meta_changed": "{{old}} to {{new}}", + "audit_meta_email_requested": "Requested change to {{email}}", + "audit_meta_accounts_removed_one": "{{name}} ({{count}} account removed)", + "audit_meta_accounts_removed_other": "{{name}} ({{count}} accounts removed)", + "audit_meta_scheduled_deletion": "Scheduled for deletion", + "audit_meta_kept": "Kept for reactivation", + "common_view": "View", + "common_save": "Save", + "common_saving": "Saving...", + "common_back": "Back", + "common_shared_by": "Shared by", + "common_user_avatar": "User Avatar", + "common_toast_saved": "Changes saved successfully", + "pause_reason_shocker": "Paused at shocker level", + "pause_reason_shocker_user_share": "Paused at shocker and user share level", + "pause_reason_shocker_public_share": "Paused at shocker and public share level", + "pause_reason_user_share": "Paused at user share level", + "pause_reason_public_share": "Paused at public share level", + "public_shares_subtitle": "A link anyone can use, no account required.", + "public_shares_new": "New Share", + "public_share_never_expires": "Never expires", + "public_shares_empty_title": "No public shares yet", + "public_shares_empty_desc": "Create a link that anyone can use to control your shockers.", + "public_share_expired": "Expired", + "public_share_no_expiry": "No expiry", + "public_share_label": "Public Share", + "public_share_toast_created": "Created new public share", + "public_share_create_title": "Create public share", + "public_share_toast_deleted": "Deleted public share", + "public_share_delete_title": "Delete public share", + "public_share_delete_desc": "Are you sure you want to delete public share {{name}}?", + "public_share_edit_title": "Public Share: {{name}}", + "public_share_edit_subtitle": "Editing: changes apply when you save.", + "public_share_add_shocker": "Add Shocker", + "public_share_toast_added_one": "Added {{count}} shocker to share", + "public_share_toast_added_other": "Added {{count}} shockers to share", + "public_share_empty_shockers_title": "No shockers in this share", + "public_share_empty_shockers_desc": "Add a shocker and anyone with the link will be able to control it.", + "public_share_load_failed": "Error fetching public share details", + "public_share_paused_here": "Paused for this share", + "public_share_resume_shocker": "Resume shocker", + "public_share_pause_shocker": "Pause shocker", + "public_share_remove": "Remove from share", + "public_share_toast_removed": "Shocker removed from share", + "public_share_add_title": "Add shockers", + "public_share_add_desc": "Add shockers to this public share. You can set their limits once they are added.", + "public_share_add_placeholder": "Select shockers to share...", + "public_share_add_no_match": "No matching shockers", + "public_share_add_submit": "Add Shockers", + "public_share_view_loading": "Loading share details...", + "public_share_view_title": "Public Share Link", + "public_share_view_desc": "Enter as a guest or login with your OpenShock account", + "public_share_view_guest_name": "Guest Name", + "public_share_view_enter": "Enter", + "public_share_view_enter_guest": "Enter as Guest", + "public_share_login": "Login", + "perm_shock_on": "Shock enabled", + "perm_shock_off": "Shock disabled", + "perm_vibrate_on": "Vibrate enabled", + "perm_vibrate_off": "Vibrate disabled", + "perm_sound_on": "Sound enabled", + "perm_sound_off": "Sound disabled", + "perm_live_on": "Live enabled", + "perm_live_off": "Live disabled", + "perm_live_control": "Live Control", + "user_selector_avatar_of": "{{name}}'s avatar", + "user_selector_placeholder": "Enter user name", + "user_selector_aria": "Username to search", + "user_selector_search": "Search user", + "user_selector_found": "User found", + "common_remove": "Remove", + "user_shares_subtitle": "Direct permanent shares with other users.", + "user_shares_toast_invited": "Sent a shocker invite to {{name}}", + "user_shares_redeem": "Redeem Code", + "user_shares_new": "New Share", + "user_shares_tab_shares": "Shares", + "user_shares_tab_incoming": "Shared with Me", + "user_shares_tab_invites": "Invites", + "share_code_create_title": "New share code", + "share_code_create_desc": "Create a Share Code or Invite", + "share_code_shocker_placeholder": "Select shockers to share...", + "share_code_no_match": "No matching shockers", + "share_code_send_invite": "Send Share Invite", + "share_code_create": "Create Share Code", + "share_code_created_title": "Share code generated", + "share_code_created_desc": "Please copy share code or code link!", + "share_code_redeem_title": "Redeem share code", + "share_code_redeem_desc": "Enter the share code to redeem", + "share_code_redeem_placeholder": "Enter share code", + "share_code_redeemed": "Redeemed successfully!", + "share_code_shared_shockers": "Shared shockers", + "share_code_redeeming": "Redeeming...", + "share_code_redeem": "Redeem", + "incoming_shares_empty_title": "Nothing shared with you", + "incoming_shares_empty_desc": "No one has shared a shocker with you yet.", + "incoming_share_toast_removed": "Removed share for {{name}}", + "incoming_share_remove_title": "Remove Share", + "incoming_share_remove_desc": "Are you sure you want to remove the share for {{name}}?", + "incoming_share_toast_removed_shocker": "Removed {{shocker}} shared by {{name}}", + "incoming_share_remove_shocker_title": "Remove this shared shocker?", + "incoming_share_remove_shocker_desc": "Are you sure you want to remove the shocker share {{shocker}} by {{name}}?", + "incoming_share_manage_from": "Manage shares from", + "share_remove": "Remove share", + "invites_empty_title": "No invites yet", + "invites_empty_desc": "You have no incoming or outgoing share invites.", + "invites_outgoing": "Outgoing", + "invites_outgoing_empty_title": "No outgoing invites", + "invites_outgoing_empty_desc": "You have no outgoing share invites.", + "invites_incoming": "Incoming", + "invites_incoming_empty_title": "No incoming invites", + "invites_incoming_empty_desc": "You have no incoming share invites.", + "invite_toast_accepted": "Accepted share invite from {{name}}", + "invite_toast_declined": "Declined share invite from {{name}}", + "invite_deny_title": "Deny Invite", + "invite_deny_label": "Deny Invite", + "invite_deny": "Deny", + "invite_deny_desc": "Are you sure you want to deny the invite from {{name}}?", + "invite_accept": "Accept Invite", + "invite_toast_cancelled_for": "Cancelled invite for {{name}} ({{id}})", + "invite_toast_cancelled": "Cancelled invite {{id}}", + "invite_cancel_title": "Cancel Invite", + "invite_cancel": "Cancel", + "invite_cancel_for_desc": "Are you sure you want to cancel the invite for {{name}}?", + "invite_cancel_code_desc": "Are you sure you want to cancel the invite with code {{code}}?", + "invite_cancel_outstanding": "Cancel Outstanding Invite", + "outgoing_shares_empty_title": "No shared shockers", + "outgoing_shares_empty_desc": "You haven't shared any shockers with other users yet.", + "outgoing_share_toast_removed": "Removed shocker share {{name}}", + "outgoing_share_remove_title": "Stop sharing this shocker?", + "outgoing_share_editing_for": "Editing shares for", + "outgoing_share_limits": "Limits & Permissions", + "outgoing_share_same": "Same restrictions on every shocker", + "outgoing_share_per_desc": "Tune restrictions per shocker", + "outgoing_share_all": "All", + "outgoing_share_per": "Per shocker", + "outgoing_share_remove_desc": "Are you sure you want to stop sharing {{shocker}} with {{name}}?", + "report_breadcrumb": "Report API Tokens", + "report_toast_clipboard_failed": "Failed to read clipboard: {{error}}", + "report_title": "Report Leaked API Tokens", + "report_paste": "Paste from clipboard", + "report_warning": "This form is only for reporting accidentally leaked API tokens.", + "report_abuse_warning": "Intentional abuse will result in bans or severe endpoint restrictions.", + "report_detected": "Detected Tokens", + "report_invalid": "One or more tokens appear to be invalid. Please check for formatting issues.", + "report_acknowledge": "I confirm I understand what this feature is for and accept responsibility.", + "report_submit": "Submit Report", + "turnstile_disabled": "Turnstile disabled", + "common_internal_error": "Internal error", + "resend_toast_sent": "Activation email sent. Check your inbox and spam folder.", + "resend_toast_throttled": "Too many activation emails have been requested. Please try again later.", + "resend_toast_unavailable": "No activation email can be resent from this browser. If your account isn't activated yet, logging in sends a new link.", + "resend_button": "Didn't get the email? Resend", + "expiration_label": "Expiration", + "expiration_never": "Never", + "expiration_custom": "Custom", + "expiration_days_one": "{{count}} Day", + "expiration_days_other": "{{count}} Days", + "expiration_required": "Expire date is required", + "expiration_never_desc": "This will never expire", + "expiration_expires_at": "Expires {{time}} ({{date}})", + "date_picker_placeholder": "Pick a date", + "telemetry_toast_title": "Help improve OpenShock?", + "telemetry_toast_desc": "Send diagnostics to help us fix crashes and slow API calls. Reports include the error message, stack trace and your IP. You can change this any time in Account settings.", + "telemetry_toast_no": "No thanks", + "telemetry_toast_errors": "Errors only", + "telemetry_toast_full": "Full", + "table_show_details": "Show details", + "table_hide_details": "Hide details", + "table_no_results": "No results.", + "table_sort_asc": "Sort by {{name}}, ascending", + "table_sort_desc": "Sort by {{name}}, descending", + "table_sort_none": "Sort by {{name}}, unsorted", + "cell_na": "N/A", + "cell_not_applicable": "Not applicable", + "cell_invalid": "Invalid", + "cell_unavailable": "Unavailable", + "cell_none": "None", + "oauth_login_with": "Login with {{provider}}", + "oauth_signup_with": "Signup with {{provider}}", + "signalr_connect_failed": "Failed to connect to server!", + "signalr_disconnect_failed": "Encountered error while disconnecting from server!", + "signalr_invalid_update": "Received invalid update from server!", + "signalr_invalid_log": "Received invalid log data from server!", + "signalr_invalid_ota": "Received invalid firmware update data from server!", + "ota_toast_failed": "Hub firmware update failed: {{message}}", + "ota_toast_succeeded": "Hub firmware update completed successfully!", + "ota_toast_rolled_back": "Hub firmware rolled back to previous version", + "lcg_connect_failed": "Failed to connect to live control gateway", + "terminal_toast_bootloader_failed": "Failed to enter bootloader: {{error}}", + "terminal_toast_app_mode_failed": "Failed to enter application mode: {{error}}", + "problem_account_account_not_activated_title": "Account not activated", + "problem_account_account_not_activated_desc": "Check your inbox for the activation email.", + "problem_account_activation_not_found_title": "Activation link is invalid", + "problem_account_activation_not_found_desc": "The link may have expired or already been used.", + "problem_account_activation_resend_too_many_title": "Too many activation emails requested", + "problem_account_activation_resend_too_many_desc": "Please wait a while before trying again.", + "problem_account_activation_resend_unavailable_title": "Cannot resend activation email", + "problem_account_activation_resend_unavailable_desc": "Log in again to request a new activation link.", + "problem_account_deactivate_already_deactivated_title": "Account is already deactivated", + "problem_account_deactivate_denied_privileged_title": "Privileged accounts cannot be deactivated", + "problem_account_deactivate_unauthorized_title": "You are not allowed to do this", + "problem_account_deactivated_title": "This account has been deactivated", + "problem_account_email_already_in_use_title": "That email address is already in use", + "problem_account_email_invalid_title": "That email address is not valid", + "problem_account_email_taken_title": "That email address is already in use", + "problem_account_email_too_many_requests_title": "Too many email change requests", + "problem_account_email_too_many_requests_desc": "Please wait a while before trying again.", + "problem_account_email_unchanged_title": "That is already your email address", + "problem_account_email_verify_not_found_title": "Verification link is invalid", + "problem_account_email_verify_not_found_desc": "The link may have expired or already been used.", + "problem_account_o_auth_only_title": "This account has no password", + "problem_account_o_auth_only_desc": "Sign in with the provider you signed up with.", + "problem_account_password_not_set_title": "No password set", + "problem_account_password_not_set_desc": "This account signs in through an external provider.", + "problem_account_password_old_password_invalid_title": "Current password is incorrect", + "problem_account_username_invalid_title": "That username is not allowed", + "problem_account_username_recently_changed_title": "Username changed too recently", + "problem_account_username_recently_changed_desc": "You can change your username once every 7 days.", + "problem_account_username_taken_title": "That username is already taken", + "problem_admin_user_deactivated_title": "This user is deactivated", + "problem_admin_user_not_activated_title": "This user has not been activated yet", + "problem_api_token_can_only_delete_self_title": "An API token can only delete itself", + "problem_api_token_not_found_title": "API token not found", + "problem_api_token_paused_title": "This API token is paused", + "problem_assign_lcg_bad_schema_version_title": "Unsupported hub protocol version", + "problem_assign_lcg_bad_schema_version_desc": "Update the hub firmware to connect.", + "problem_assign_lcg_no_lcg_available_title": "No gateway available", + "problem_assign_lcg_no_lcg_available_desc": "No live control gateway is available right now. Please try again later.", + "problem_authentication_account_deactivated_title": "This account has been deactivated", + "problem_authentication_account_not_activated_title": "This account has not been activated", + "problem_authentication_cookie_missing_or_invalid_title": "You are not logged in", + "problem_authentication_cookie_missing_or_invalid_desc": "Your session may have expired. Please log in again.", + "problem_authentication_header_missing_or_invalid_title": "Invalid API token", + "problem_authentication_session_invalid_title": "Session expired", + "problem_authentication_session_invalid_desc": "Please log in again.", + "problem_authentication_token_invalid_title": "Invalid API token", + "problem_authentication_unknown_error_title": "Authentication failed", + "problem_authorization_policy_not_met_title": "You do not have permission to do this", + "problem_authorization_token_only_title": "This action requires an API token", + "problem_authorization_token_permission_missing_title": "This API token is missing a required permission", + "problem_authorization_unknown_error_title": "Authorization failed", + "problem_authorization_user_session_only_title": "This action requires a logged-in session", + "problem_automation_token_not_allowed_for_account_title": "Automation tokens cannot be used with privileged accounts", + "problem_configuration_already_exists_title": "A configuration entry with that name already exists", + "problem_configuration_invalid_name_format_title": "Invalid configuration name", + "problem_configuration_invalid_name_format_desc": "Only A to Z and underscores are allowed.", + "problem_configuration_invalid_value_format_title": "Value does not match the configuration type", + "problem_configuration_not_found_title": "Configuration entry not found", + "problem_control_stats_invalid_range_title": "The from date must not be after the to date", + "problem_control_stats_invalid_time_zone_title": "Unknown time zone", + "problem_control_stats_missing_capability_title": "Control statistics are not available on this server", + "problem_device_not_found_title": "Hub not found", + "problem_device_not_online_title": "Hub is offline", + "problem_device_too_many_hubs_title": "You have reached the maximum number of hubs", + "problem_device_too_many_shockers_title": "This hub has reached its maximum number of shockers", + "problem_endpoint_retired_title": "This feature is no longer available", + "problem_expression_error_title": "Invalid filter expression", + "problem_internal_server_error_title": "Something went wrong on our end", + "problem_login_invalid_credentials_title": "Invalid username or password", + "problem_login_invalid_domain_title": "Logging in from this address is not allowed", + "problem_o_auth_connection_already_exists_title": "Your account is already connected to this provider", + "problem_o_auth_connection_already_linked_title": "This external account is already linked to another user", + "problem_o_auth_flow_anonymous_only_title": "You are already signed in", + "problem_o_auth_flow_mismatch_title": "Sign-in attempt does not match", + "problem_o_auth_flow_mismatch_desc": "Please start over.", + "problem_o_auth_flow_missing_data_title": "The provider did not return your account details", + "problem_o_auth_flow_missing_data_desc": "Please try again.", + "problem_o_auth_flow_not_found_title": "Sign-in attempt expired", + "problem_o_auth_flow_not_found_desc": "Please start over.", + "problem_o_auth_flow_unsupported_title": "Unsupported sign-in flow", + "problem_o_auth_internal_error_title": "Something went wrong during sign-in", + "problem_o_auth_internal_error_desc": "Please try again in a moment.", + "problem_o_auth_link_authenticated_user_only_title": "You must be signed in to link an external account", + "problem_o_auth_provider_mismatch_title": "Sign-in attempt does not match the provider", + "problem_o_auth_provider_mismatch_desc": "Please start over.", + "problem_o_auth_provider_unsupported_title": "This sign-in provider is not supported", + "problem_pair_code_not_found_title": "Pair code not found", + "problem_password_reset_not_found_title": "Password reset link is invalid", + "problem_password_reset_not_found_desc": "The link may have expired or already been used.", + "problem_session_not_found_title": "Session not found", + "problem_share_get_no_shares_title": "You have no shares with this user", + "problem_share_request_create_cannot_share_with_self_title": "You cannot share with yourself", + "problem_share_request_create_shocker_not_found_title": "One or more shockers were not found", + "problem_share_request_create_shocker_not_found_desc": "They may have been removed or do not belong to you.", + "problem_share_request_not_found_title": "Share invite not found", + "problem_share_user_not_found_title": "Share not found", + "problem_share_code_already_linked_title": "Shocker is already linked to your account", + "problem_share_code_cant_link_own_share_code_title": "You cannot redeem your own share code", + "problem_share_code_not_found_title": "Share code not found", + "problem_share_link_expiry_date_in_past_title": "Expiry date cannot be in the past", + "problem_share_link_not_found_title": "Public share not found", + "problem_share_link_shocker_already_in_share_link_title": "Shocker is already in this public share", + "problem_share_link_shocker_not_in_share_link_title": "Shocker is not in this public share", + "problem_shocker_control_no_permission_title": "You do not have permission to control this shocker", + "problem_shocker_control_not_found_title": "Shocker not found", + "problem_shocker_control_paused_title": "Shocker is paused", + "problem_shocker_not_found_title": "Shocker not found", + "problem_signup_registration_disabled_title": "Registration is currently disabled", + "problem_signup_username_or_email_exists_title": "That username or email is already in use", + "problem_turnstile_invalid_title": "Verification failed", + "problem_turnstile_invalid_desc": "Please complete the challenge again and retry.", + "problem_user_not_found_title": "User not found", + "problem_user_privileged_delete_denied_title": "Privileged users cannot be deleted", + "problem_validation_error_title": "Some fields are invalid", + "problem_webhook_not_found_title": "Webhook not found", + "problem_webhook_unsupported_title": "Only Discord webhooks are supported", + "problem_webhook_unsupported_desc": "Use a discord.com URL, not canary or ptb.", + "error_too_many_requests": "Too many requests", + "error_retry_after_one": "Try again in {{count}} second.", + "error_retry_after_other": "Try again in {{count}} seconds.", + "error_unexpected_response": "Unexpected server response", + "error_internal": "Internal error occurred", + "error_network": "Network error occurred", + "dev_banner": "This is the OpenShock DEVELOPMENT environment. No data is saved, and it is regularly overwritten by production data.", + "firmware_channel_bugs_warning": "This channel might contain bugs." +} From 617100bcb9afdc7b30dd1b1c3ed0b1b00ccb5de4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Luc=20=E2=99=A5?= Date: Thu, 12 Nov 2026 17:43:07 +0100 Subject: [PATCH 07/27] New translations en.json (Czech) [ci skip] --- messages/cs.json | 1055 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 1055 insertions(+) create mode 100644 messages/cs.json diff --git a/messages/cs.json b/messages/cs.json new file mode 100644 index 00000000..ef4df56c --- /dev/null +++ b/messages/cs.json @@ -0,0 +1,1055 @@ +{ + "landing_tagline": "The go-to platform for safe, reliable, real low-latency remote shocking.", + "landing_section_label": "Home", + "landing_hubs_online": "Hubs online right now: ", + "landing_learn_more": "Learn More", + "landing_wiki": "Wiki", + "landing_meta_description": "Welcome to OpenShock, a free and open-source ecosystem to control various shock collars over the internet.", + "instance_meta_description": "Welcome to {{siteName}}, an independent instance of OpenShock, a free and open-source ecosystem to control various shock collars over the internet.", + "header_sidebar_toggle": "Toggle Sidebar", + "header_avatar_alt": "{{name}}'s avatar", + "header_menu_profile": "Profile", + "header_menu_settings": "Settings", + "header_menu_logout": "Logout", + "header_login": "Login", + "header_signup": "Sign Up", + "header_github_title": "OpenShock on GitHub", + "header_discord_title": "Community Discord", + "footer_made_with": "Made with by the OpenShock Team", + "footer_connection_status_label": "Server connection status", + "footer_signalr_state": "SignalR State", + "footer_frontend_version": "Frontend Version", + "footer_frontend_commit_title": "Commit {{commit}}", + "footer_backend_version": "Backend Version", + "footer_backend_commit_title": "Commit {{commit}}", + "footer_language_label": "Language", + "sidebar_home_link_label": "OpenShock home", + "sidebar_group_general": "General", + "sidebar_home": "Home", + "sidebar_shockers": "Shockers", + "sidebar_shared_shockers": "Shared Shockers", + "sidebar_hubs": "Hubs", + "sidebar_user_shares": "User Shares", + "sidebar_public_shares": "Public Shares", + "sidebar_serial_terminal": "Serial Terminal", + "sidebar_group_admin": "Admin", + "sidebar_admin_monitoring": "Monitoring", + "sidebar_admin_online_hubs": "Online Hubs", + "sidebar_admin_online_gateways": "Online Gateways", + "sidebar_admin_management": "Management", + "sidebar_admin_users": "Users", + "sidebar_admin_blacklists": "Blacklists", + "sidebar_admin_webhooks": "Webhooks", + "sidebar_admin_mail": "Mail", + "sidebar_admin_automation_tokens": "Automation Tokens", + "sidebar_admin_configuration": "Configuration", + "sidebar_group_settings": "Settings", + "sidebar_settings_api_tokens": "API Tokens", + "sidebar_settings_sessions": "Sessions", + "sidebar_settings_audit_log": "Audit Log", + "sidebar_settings_connections": "Connections", + "sidebar_settings_account": "Account Settings", + "error_meta_title": "Service Unavailable", + "error_meta_description": "OpenShock is currently unavailable", + "error_meta_logo_alt": "OpenShock Logo", + "error_fallback_message": "Something went wrong.", + "error_not_found_message": "Page not found", + "error_not_found_description": "The page you're looking for doesn't exist.", + "error_unexpected_description": "An unexpected error occurred.", + "error_go_back": "Go back", + "auth_layout_logo_alt": "OpenShock Logo", + "auth_layout_invalid_redirect_removed": "An invalid redirect URL was removed for your safety.", + "auth_activate_breadcrumb": "Activate Account", + "auth_activate_title": "Activate Account", + "auth_activate_activating": "Activating your account...", + "auth_activate_success": "Your account has been activated", + "auth_activate_failed": "This activation link is invalid or has expired", + "auth_activate_missing_token": "Missing activation token", + "auth_activate_continue": "Continue to login", + "auth_activate_toast_success": "Account activated", + "auth_forgot_breadcrumb": "Forgot Password", + "auth_forgot_title": "Forgot Password", + "auth_forgot_description": "Enter your email to reset your password", + "auth_forgot_email_label": "Email", + "auth_forgot_email_placeholder": "Email", + "auth_forgot_submit": "Reset Password", + "auth_forgot_signin_prompt": "Remember your password? Sign in", + "auth_forgot_mail_disabled": "Password resets are unavailable on this instance because it has no mail provider configured. Please contact your administrator for help recovering your account.", + "auth_forgot_toast_sent": "Reset password request has been sent to the given email", + "auth_login_breadcrumb": "Login", + "auth_login_title": "Welcome back", + "auth_login_loading_methods": "Loading available login methods", + "auth_login_choose_method": "Login with one of these methods", + "auth_login_with_account": "Login with your OpenShock Account", + "auth_login_activation_after_signup": "Your account has been created. We've sent an activation link to your email address. Check your inbox and spam folder.", + "auth_login_activation_pending": "Your account isn't activated yet. We've sent an activation link to your email address. Check your inbox and spam folder. If nothing arrives, try logging in again later to get a new link.", + "auth_login_oauth_only": "This account has no password. Sign in with the provider you signed up with.", + "auth_login_oauth_only_with_buttons": "This account has no password. Sign in with the provider you signed up with using the buttons above.", + "auth_login_or_continue_with": "Or continue with", + "auth_login_username_label": "Username or Email", + "auth_login_password_label": "Password", + "auth_login_submit": "Login", + "auth_login_signup_prompt": "Don't have an account? Sign up", + "auth_login_legal": "By clicking Login, you agree to our Terms of Service and Privacy Policy.", + "auth_oauth_create_breadcrumb": "Sign Up With {{provider}}", + "auth_oauth_create_title": "Sign Up With {{provider}}", + "auth_oauth_create_description": "Complete your account details", + "auth_oauth_create_username_label": "Username", + "auth_oauth_create_username_placeholder": "Username", + "auth_oauth_create_email_label": "Email", + "auth_oauth_create_email_placeholder": "Email", + "auth_oauth_create_submit": "Sign Up", + "auth_oauth_create_legal": "By clicking Sign Up, you agree to our Terms of Service and Privacy Policy.", + "auth_oauth_error_breadcrumb": "Authentication Error", + "auth_oauth_error_title": "Authentication Error", + "auth_oauth_error_back": "Back to login", + "auth_reset_breadcrumb": "Reset Password", + "auth_reset_title": "Reset Password", + "auth_reset_checking": "Verifying reset link...", + "auth_reset_choose_password": "Choose a new password for your account", + "auth_reset_invalid": "This reset link is invalid or has expired", + "auth_reset_password_label": "New Password", + "auth_reset_password_placeholder": "New Password", + "auth_reset_confirm_label": "Confirm New Password", + "auth_reset_confirm_placeholder": "Confirm New Password", + "auth_reset_submit": "Reset Password", + "auth_reset_request_new": "Request a new reset link", + "auth_reset_toast_success": "Password has been reset", + "auth_signup_breadcrumb": "Sign Up", + "auth_signup_toast_created_mail": "Account created successfully. Please check your email to verify your account.", + "auth_signup_toast_created_no_mail": "Account created successfully. You can log in now.", + "auth_signup_dialog_title": "Welcome! Thank you for signing up! ❤️", + "auth_signup_dialog_created_mail": "Your account has been created. 🎉 Please check your email to verify your account.", + "auth_signup_dialog_verify_then_login": "After verifying your email, you can log in to your account.", + "auth_signup_dialog_created_no_mail": "Your account has been created and is ready to use. 🎉", + "auth_signup_dialog_login_now": "You can log in to your account now.", + "auth_signup_title": "Create your account", + "auth_signup_loading_methods": "Loading available sign-up methods", + "auth_signup_using_email": "Signing up using email", + "auth_signup_choose_method": "Choose your preferred sign-up method", + "auth_signup_back": "Back", + "auth_signup_username_label": "Username", + "auth_signup_username_placeholder": "John OpenShock", + "auth_signup_email_label": "Email", + "auth_signup_email_placeholder": "john@example.com", + "auth_signup_password_label": "Password", + "auth_signup_password_placeholder": "Password", + "auth_signup_confirm_label": "Confirm Password", + "auth_signup_confirm_placeholder": "Confirm Password", + "auth_signup_submit": "Create Account", + "auth_signup_signin_prompt": "Already have an account? Sign in", + "auth_signup_or": "Or", + "auth_signup_with_email": "Signup with Email", + "auth_signup_legal": "By clicking Create Account, you agree to our Terms of Service and Privacy Policy.", + "auth_verify_breadcrumb": "Verify Email", + "auth_verify_title": "Verify Email", + "auth_verify_verifying": "Verifying your email address...", + "auth_verify_success": "Your email has been verified", + "auth_verify_failed": "This verification link is invalid or has expired", + "auth_verify_missing_token": "Missing verification token", + "auth_verify_continue": "Continue to login", + "auth_verify_toast_success": "Email verified", + "common_cancel": "Cancel", + "common_delete": "Delete", + "common_edit": "Edit", + "common_share": "Share", + "common_copy_id": "Copy ID", + "common_id_copied": "ID copied to clipboard", + "common_open_menu": "Open menu", + "common_refresh": "Refresh", + "common_settings": "Settings", + "common_clear": "Clear", + "common_online": "Online", + "common_offline": "Offline", + "common_paused": "Paused", + "common_resume": "Resume", + "common_resuming": "Resuming...", + "common_coming_soon": "(Coming soon)", + "common_save_changes": "Save Changes", + "common_danger_zone": "Danger Zone", + "common_name": "Name", + "control_intensity": "Intensity", + "control_duration": "Duration", + "control_max_intensity": "Max Intensity", + "control_max_duration": "Max Duration", + "control_vibration": "Vibration", + "control_value": "Value", + "control_live_intensity": "Live intensity", + "control_type_stop": "Stop", + "control_type_shock": "Shock", + "control_type_vibrate": "Vibrate", + "control_type_sound": "Sound", + "live_tooltip_active": "Live via {{gateway}} ({{country}}), {{latency}}ms", + "live_tooltip_connecting": "Connecting...", + "live_tooltip_connect": "Connect to Live Control", + "live_tooltip_hub_start": "Ctrl+click to start the whole hub", + "live_tooltip_hub_stop": "Ctrl+click to stop the whole hub", + "pause_resume_shocker": "Resume shocker", + "pause_pause_shocker": "Pause shocker", + "pause_resume_all": "Resume all shockers", + "pause_pause_all": "Pause all shockers", + "shocker_label": "Shocker", + "shocker_hub": "Hub", + "shocker_select_hub": "Select hub", + "shocker_rf_id": "RF ID", + "shocker_rf_id_invalid": "RF ID must be a whole number between {{min}} and {{max}}.", + "shocker_model": "Model", + "shocker_select_model": "Select model", + "shocker_name_placeholder": "Shocker name", + "shocker_menu_view_logs": "View Logs", + "shocker_delete_title": "Delete Shocker", + "shocker_delete_desc": "Are you sure you want to delete \"{{name}}\"? This action cannot be undone.", + "shocker_toast_deleted": "Shocker \"{{name}}\" deleted", + "shocker_toast_paused": "Shocker paused", + "shocker_toast_resumed": "Shocker resumed", + "shocker_add_desc": "Register a new shocker to one of your hubs.", + "shocker_add_name_placeholder": "My Shocker", + "shockers_title": "Shockers", + "shockers_subtitle": "Every shocker paired to your hubs.", + "shockers_loading": "Loading shockers...", + "shockers_toast_refreshed": "Shockers refreshed", + "shockers_toast_need_hub": "You need to create a hub before adding shockers.", + "shockers_toast_added": "Shocker added", + "shockers_unknown_module": "Unknown module type", + "shockers_add": "Add Shocker", + "shockers_view_mode": "View mode", + "shockers_mode_classic": "Classic", + "shockers_mode_rich": "Rich", + "shockers_mode_simple": "Simple", + "shockers_mode_map": "Map", + "shockers_group_by_hub": "Group by Hub", + "shockers_global_limits": "Global Limits", + "shockers_logs_label": "Logs", + "shockers_empty_title": "No shockers yet", + "shockers_empty_no_hubs": "Create a hub first, then add shockers to it.", + "shockers_empty_has_hubs": "Add a shocker to one of your hubs to get started.", + "shockers_create_hub": "Create a Hub", + "shockers_count_one": "{{count}} shocker", + "shockers_count_other": "{{count}} shockers", + "shared_shockers_title": "Shared Shockers", + "shared_shockers_subtitle": "Shockers other users have shared with you.", + "shared_shockers_empty_title": "No shockers have been shared with you yet.", + "shared_shockers_empty_desc": "When someone shares their shockers with you, they'll appear here.", + "shocker_logs_title": "Shocker Logs", + "shocker_logs_subtitle": "Every control command sent to your shockers.", + "shocker_logs_live_title": "New logs appear in real time", + "shocker_logs_paused_title": "Live updates pause when sorting or viewing a page other than the first", + "shocker_logs_live": "Live", + "shocker_logs_col_time": "Time", + "shocker_logs_col_type": "Type", + "shocker_logs_col_by": "By", + "shocker_logs_filter_label": "Filter by shocker", + "shocker_logs_filter_placeholder": "Search shockers...", + "shocker_logs_filter_all": "All shockers", + "shocker_logs_filter_none": "No matching shockers", + "shocker_edit_title": "Edit Shocker", + "shocker_edit_subtitle": "Change this shocker's details or remove it.", + "shocker_edit_back": "Back to Shockers", + "shocker_edit_load_failed": "Failed to load shocker.", + "shocker_edit_loading": "Loading shocker...", + "shocker_edit_details_title": "Shocker Details", + "shocker_edit_details_desc": "Update the name, RF ID, and model for this shocker.", + "shocker_edit_pause_state": "Pause State", + "shocker_edit_is_paused": "Shocker is paused", + "shocker_edit_is_active": "Shocker is active", + "shocker_edit_toast_updated": "Shocker updated", + "shocker_edit_delete_desc": "Permanently delete this shocker. This action cannot be undone.", + "common_close": "Close", + "common_continue": "Continue", + "common_loading": "Loading...", + "common_previous": "Previous", + "common_next": "Next", + "common_steps": "Steps", + "common_step_label": "Step {{number}}: {{title}}", + "common_copy": "Copy", + "common_copied": "Copied", + "common_never": "Never", + "common_error": "Error: {{message}}", + "terminal_title": "Serial Terminal", + "terminal_connecting": "Connecting...", + "terminal_help_button": "I'm having trouble, help?", + "terminal_back_to_modes": "Back to mode picker", + "terminal_mode_configure": "Configure Device", + "terminal_mode_configure_desc": "Configure WiFi, authentication, and more. Includes an interactive serial console.", + "terminal_mode_flash": "Flash Firmware", + "terminal_mode_flash_desc": "Install or update firmware on a connected device.", + "terminal_mode_raw": "Serial Monitor", + "terminal_mode_raw_desc": "Just the console. Read device logs and send commands.", + "terminal_step_channel": "Select Channel", + "terminal_step_board": "Select Board", + "terminal_go_to_step": "Go to step {{number}}: {{title}}", + "terminal_erase": "Erase before flashing", + "terminal_erase_desc": "Clears all data on the device including existing configs", + "terminal_unsupported": "Your browser does not support this feature.", + "terminal_update_browser": "Please update your browser to the latest version.", + "terminal_use_browsers": "Please use one of the following browsers:", + "terminal_connect_failed_bootloader": "Could not enter bootloader mode", + "terminal_connect_failed": "Device connection failed", + "terminal_connect_failed_desc": "We couldn't establish a serial connection with the device.", + "terminal_quick_tries": "Quick things to try:", + "terminal_try_replug": "Unplug and replug the device.", + "terminal_try_cable": "Try a different USB cable or port.", + "terminal_try_driver": "Make sure the serial driver is installed.", + "terminal_open_troubleshooter": "Open troubleshooter", + "terminal_log_reset_no_device": "Host-side error during reset: no device!", + "terminal_log_reset_error": "Host-side error during reset: {{error}}", + "terminal_log_send_no_device": "Couldn't send: no device!", + "terminal_log_send_error": "Couldn't send: {{error}}", + "terminal_log_firmware_disconnected": "Firmware disconnected: {{error}}", + "terminal_log_erase_failed": "Failed to erase flash: {{error}}", + "terminal_log_hard_reset_failed": "Failed to hard reset: {{error}}", + "terminal_log_flash_complete": "Flash complete", + "terminal_log_flash_failed": "Failed to flash: {{error}}", + "terminal_log_command_failed": "Failed to write application command: {{error}}", + "terminal_help_title": "Troubleshooter", + "terminal_help_desc": "Work through these steps in order. Each one rules out a common cause.", + "terminal_help_step_cable": "USB cable", + "terminal_help_step_port": "USB port", + "terminal_help_step_driver": "Install driver", + "terminal_help_step_manual": "Manual driver update", + "terminal_help_step_discord": "Ask on Discord", + "terminal_help_cable_body": "Many USB-C and micro-USB cables are charge-only and don't carry data. Swap to a known-good data cable (one you've used to transfer files or connect other devices) and reconnect the hub.", + "terminal_help_port_body": "Plug the device directly into a USB port on your computer. Avoid USB hubs, docking stations, and front-panel ports if possible; these are common sources of power and signal issues. If you're on a desktop, try a port on the back of the machine.", + "terminal_help_driver_download": "Download the CP210x driver:", + "terminal_help_driver_extract": "Extract the contents of the zip file to a folder on your computer.", + "terminal_help_driver_run": "Open the folder and run {{installer}}. Follow the prompts to install.", + "terminal_help_driver_reconnect": "Reconnect the device.", + "terminal_help_manual_intro": "If the driver installer ran but the device still doesn't show up:", + "terminal_help_manual_open": "Open Device Manager (press Win + X and select Device Manager).", + "terminal_help_manual_ports": "Under Ports (COM & LPT), look for an entry like:", + "terminal_help_manual_missing": "If it's missing, the device isn't being detected by Windows at all; revisit the cable and port steps.", + "terminal_help_manual_update": "Right-click the device and pick Update Driver.", + "terminal_help_manual_browse": "Choose Browse my computer for drivers and select the folder you extracted the driver zip into. Make sure Include subfolders is checked.", + "terminal_help_manual_success": "On success, the entry should now read {{deviceName}}.", + "terminal_help_discord_intro": "Still stuck after all of the above? Hop into our Discord server and ask in the {{channel}} channel. Please include:", + "terminal_help_discord_os": "your operating system and browser", + "terminal_help_discord_device": "the device you're using (board model, where you got it)", + "terminal_help_discord_tried": "what you've already tried from the previous steps", + "terminal_help_discord_errors": "any error messages or relevant terminal output", + "terminal_help_discord_join": "Join our Discord server", + "terminal_risk_title": "⚠️ UNSTABLE FIRMWARE", + "terminal_risk_intro": "You are about to flash experimental firmware that is known to be unstable.", + "terminal_risk_brick": "This may permanently brick your device, require manual recovery, or render it unusable.", + "terminal_risk_no_support": "We will NOT provide support for issues caused by this firmware.", + "terminal_risk_acknowledge": "I understand this is entirely my responsibility", + "terminal_risk_abort": "Abort", + "terminal_risk_accept": "I ACCEPT FULL RESPONSIBILITY", + "firmware_channel_recommended": "This is the recommended channel.", + "firmware_channel_danger": "DO NOT USE THIS UNLESS YOU KNOW WHAT YOU ARE DOING", + "firmware_channel_stable": "Stable", + "firmware_channel_beta": "Beta", + "firmware_channel_develop": "Develop", + "terminal_board_select": "Select a board...", + "terminal_board_search": "Search boards...", + "terminal_board_none": "No board found.", + "terminal_flash_button": "Flash", + "terminal_flash_progress": "Flash Progress: {{status}}", + "terminal_flash_idle": "Idle", + "terminal_flash_no_device": "No device selected.", + "terminal_flash_resetting": "Resetting...", + "terminal_flash_downloading": "Downloading firmware...", + "terminal_flash_download_failed": "Failed to download firmware.", + "terminal_flash_flashing": "Flashing firmware...", + "terminal_flash_rebooting": "Rebooting device... (Reconnect to power manually if stuck)", + "terminal_flash_done": "Rebooted device! Flashing complete.", + "terminal_port_select": "Select Device", + "terminal_port_disconnect": "Disconnect Device", + "terminal_port_connected": "Device connected: {{id}}", + "terminal_console": "Console", + "terminal_connected_device": "Connected device", + "terminal_resize": "Resize terminal panel", + "terminal_reboot": "Reboot", + "terminal_disconnect": "Disconnect", + "terminal_fullscreen_exit_esc": "Exit fullscreen (Esc)", + "terminal_fullscreen_exit": "Exit fullscreen", + "terminal_fullscreen_fill": "Fill the window", + "terminal_command_label": "Serial command", + "terminal_command_placeholder": "Type a command...", + "terminal_command_send": "Send command", + "terminal_colors": "Colors", + "terminal_colors_menu": "Colors...", + "terminal_colors_label": "Console colors", + "terminal_colors_close": "Close colors", + "terminal_color_input": "{{name}} color", + "terminal_colors_reset": "Reset to defaults", + "terminal_color_bg": "Background", + "terminal_color_fg": "Text", + "terminal_color_ts": "Timestamp", + "terminal_color_error": "Error", + "terminal_color_warning": "Warning", + "terminal_color_info": "Info", + "terminal_color_debug": "Debug", + "terminal_color_verbose": "Verbose", + "terminal_options": "Options", + "terminal_options_label": "Console options", + "terminal_hide_system": "Hide system messages", + "terminal_stick_bottom": "Stick to bottom", + "terminal_raw_output": "Raw output", + "terminal_timestamps": "Timestamps", + "terminal_timestamp_uptime": "Uptime", + "terminal_timestamp_local": "Local", + "terminal_timestamp_ms": "Ms", + "terminal_timestamp_off": "Off", + "terminal_copy_settings": "Copy settings", + "terminal_import_settings": "Import settings", + "terminal_copy_selection": "Copy selection", + "terminal_copy_all": "Copy all output", + "terminal_toast_selection_copied": "Selection copied", + "terminal_toast_output_copied": "Console output copied", + "terminal_toast_settings_copied": "Console settings copied", + "terminal_toast_clipboard_unreadable": "Could not read the clipboard", + "terminal_toast_settings_imported": "Console settings imported", + "terminal_toast_settings_invalid": "Clipboard does not contain console settings", + "common_try_again": "Try again", + "terminal_cfg_intro": "Values are sent to the device via UART. Read the device's response in the console below. Commands without an argument act as getters; use the button next to each field to read the current value.", + "terminal_cfg_rf_title": "RF Transmitter", + "terminal_cfg_rf_desc": "Controls the shocker RF output.", + "terminal_cfg_tx_pin": "TX GPIO pin", + "terminal_cfg_example": "e.g. {{value}}", + "terminal_cfg_read_value": "Read current value", + "terminal_cfg_set": "Set", + "terminal_cfg_read": "Read", + "terminal_cfg_reading": "Reading…", + "terminal_cfg_apply": "Apply", + "terminal_cfg_keepalive": "Keepalive enabled", + "terminal_cfg_keepalive_desc": "Periodically pings paired shockers to keep them awake.", + "terminal_cfg_estop_title": "Emergency Stop", + "terminal_cfg_estop_desc": "Hardware button that halts all output.", + "terminal_cfg_estop_enabled": "EStop enabled", + "terminal_cfg_estop_pin": "EStop GPIO pin", + "terminal_cfg_estop_note": "Note: {{latching}} and {{active}} have no dedicated commands; set them via the JSON config below.", + "terminal_cfg_wifi_title": "WiFi", + "terminal_cfg_wifi_desc": "Station credentials and device hostname.", + "terminal_cfg_hostname": "Hostname", + "terminal_cfg_networks": "Networks (JSON array)", + "terminal_cfg_invalid_json_array": "Must be a valid JSON array", + "terminal_cfg_ap_note": "AP settings ({{ssid}}, {{password}}, {{disabled}}, {{staDisabled}}, {{offlineMode}}) have no dedicated commands; use the JSON config.", + "terminal_cfg_backend_title": "Backend", + "terminal_cfg_backend_desc": "OpenShock server and authentication.", + "terminal_cfg_domain": "Domain", + "terminal_cfg_domain_restart": "Setting the domain will restart the device.", + "terminal_cfg_auth_token": "Auth token", + "terminal_cfg_auth_token_placeholder": "Paste device token", + "terminal_cfg_hide": "Hide", + "terminal_cfg_show": "Show", + "terminal_cfg_serial_title": "Serial Input", + "terminal_cfg_echo": "Echo enabled", + "terminal_cfg_echo_desc": "Print typed characters back to the console.", + "terminal_cfg_advanced_title": "Advanced: full config", + "terminal_cfg_advanced_desc": "For fields without dedicated commands (captive portal, OTA, LAN, etc.), replace the entire config.", + "terminal_cfg_json_config": "JSON config", + "terminal_cfg_invalid_json": "Must be valid JSON", + "terminal_cfg_read_json": "Read current config as JSON", + "terminal_cfg_json_restart": "Applying a JSON config will restart the device.", + "terminal_cfg_raw_config": "Raw FlatBuffer config (base64)", + "terminal_cfg_invalid_base64": "Must be a valid base64 string", + "terminal_cfg_read_raw": "Read current config as base64", + "terminal_cfg_factory_reset": "Factory reset", + "terminal_cfg_factory_reset_desc": "Wipes the entire device configuration.", + "terminal_cfg_factory_reset_title": "Factory reset device?", + "terminal_cfg_factory_reset_action": "Wipe config", + "terminal_cfg_factory_reset_confirm": "This will erase all configuration on the device; WiFi networks, backend credentials, pins, and all other settings. The device will be reset to defaults.", + "terminal_cfg_read_failed_json_title": "Couldn't read the JSON config", + "terminal_cfg_read_failed_raw_title": "Couldn't read the raw config", + "terminal_cfg_read_failed_desc": "The device didn't respond after {{attempts}} attempts.", + "terminal_cfg_common_causes": "Common causes:", + "terminal_cfg_cause_busy": "The device is busy handling another command.", + "terminal_cfg_cause_disconnected": "The device disconnected or rebooted.", + "terminal_cfg_cause_unsupported": "The firmware version doesn't support this command.", + "common_status": "Status", + "common_version": "Version", + "common_created": "Created", + "common_create": "Create", + "common_done": "Done", + "common_enable": "Enable", + "common_disable": "Disable", + "common_are_you_sure": "Are you sure?", + "common_generating": "Generating...", + "hubs_title": "Hubs", + "hubs_subtitle": "Every hub registered to your account.", + "hubs_add": "Add Hub", + "hubs_load_failed": "Failed to load hubs.", + "hubs_empty_title": "No hubs yet", + "hubs_empty_desc": "A hub is the device that relays commands to your shockers. Add one to get started.", + "hubs_create_title": "Create hub", + "hubs_name_label": "Hub Name", + "hubs_name_placeholder": "My Hub", + "hub_toast_not_connected": "Not connected to the server", + "hub_toast_try_later": "Try again in a moment.", + "hub_reboot_title": "Reboot {{name}}?", + "hub_reboot_desc": "The hub will disconnect and restart. Any shockers paired to it stop responding until it comes back online.", + "hub_reboot": "Reboot", + "hub_hotspot_enable_title": "Enable Wi-Fi hotspot on {{name}}?", + "hub_hotspot_disable_title": "Disable Wi-Fi hotspot on {{name}}?", + "hub_hotspot_enable_desc": "The hub broadcasts its own setup network. It stays reachable on your Wi-Fi, but the hotspot is open to anyone in range until you turn it off.", + "hub_hotspot_disable_desc": "The setup hotspot shuts down. If the hub is not already on your Wi-Fi you will need physical access to set it up again.", + "hub_delete_desc": "You are about to delete hub {{name}}.", + "hub_delete_shockers": "This will also delete the following shockers:", + "hub_edit_title": "Edit hub", + "hub_edit_apply": "Apply", + "hub_pair_title_generate": "Generate pair code?", + "hub_pair_title_generated": "Pair code generated", + "hub_pair_title_paired": "Hub paired", + "hub_pair_consumed": "{{name}} consumed this pair code and is now paired.", + "hub_pair_used": "The code has been used and is no longer valid.", + "hub_pair_generated_for": "Pair code generated for {{name}}.", + "hub_copy_now": "The code below will not be accessible later, please copy it now and update clients with it.", + "hub_pair_generate_for": "You are about to generate a pair code for {{name}}.", + "hub_pair_valid_for": "It will be valid for 15 minutes after its creation.", + "hub_pair_one_active": "There is only one active pair code per hub, newly generated ones will override the older active ones.", + "hub_pair_complete": "Pairing complete", + "hub_pair_code_label": "Pair code:", + "hub_pair_copied_close": "Code has been copied, close", + "hub_pair_get": "Get Pair Code", + "hub_token_generated": "Token generated", + "hub_token_generated_for": "New token generated for {{name}}.", + "hub_token_regenerate_for": "You are about to regenerate the token for {{name}}.", + "hub_token_invalidate": "This action will invalidate the current token and disconnect clients using it.", + "hub_token_confirm": "Are you sure you want to do this?", + "hub_token_label": "New token:", + "hub_token_copied_close": "Token has been copied, close", + "hub_token_regenerate": "Regenerate Token", + "hub_menu_update": "Update", + "hub_menu_label": "Hub", + "hub_menu_hotspot_enable": "Enable Wi-Fi hotspot", + "hub_menu_hotspot_disable": "Disable Wi-Fi hotspot", + "hub_menu_pair": "Pair", + "hub_menu_estop": "Emergency Stop", + "hub_update_breadcrumb": "Update", + "hub_update_unknown_hub": "Unknown Hub", + "hub_update_unknown_task": "Unknown Task", + "hub_update_task_metadata": "Fetching Metadata", + "hub_update_task_preparing": "Preparing for Update", + "hub_update_task_flash_fs": "Flashing Filesystem", + "hub_update_task_verify_fs": "Verifying Filesystem", + "hub_update_task_flash_app": "Flashing Application", + "hub_update_task_bootable": "Marking Application Bootable", + "hub_update_task_rebooting": "Rebooting", + "hub_update_status_started": "Started", + "hub_update_status_running": "Running", + "hub_update_status_finished": "Finished", + "hub_update_status_error": "Error", + "hub_update_status_timeout": "Timeout", + "hub_update_confirm_title": "Confirm firmware update", + "hub_update_confirm_desc": "Update {{name}} to version {{version}}?", + "hub_update_unstable_warning": "This version may not be from the stable channel and could contain bugs.", + "hub_update_title": "Update {{name}}", + "hub_update_subtitle": "Manage firmware updates for this hub.", + "hub_update_status_title": "Hub Status", + "hub_update_firmware": "Firmware: {{version}}", + "hub_update_confirm": "Update", + "hub_update_success": "Update completed successfully", + "hub_update_rolled_back": "Device rolled back to previous version", + "hub_update_back": "Back to Hubs", + "hub_update_flash_again": "Flash Again", + "hub_update_card_title": "Firmware Update", + "hub_update_card_desc": "Select a firmware channel and version to install.", + "hub_update_to": "Update to {{version}}", + "hub_update_must_be_online": "Hub must be online to start an update.", + "hub_update_updating_to": "Updating to {{version}}...", + "hub_update_total": "Total", + "hub_update_task": "Task", + "hub_update_history": "Update History", + "hub_update_no_history": "No update history found for this hub.", + "hub_update_col_id": "ID", + "hub_update_col_started": "Started", + "hub_update_col_message": "Message", + "hub_update_loading": "Loading hub information...", + "hub_update_not_found": "Hub not found.", + "home_breadcrumb": "Home", + "home_welcome": "Welcome back", + "home_welcome_name": "Welcome back, {{name}}", + "home_subtitle": "Here's an overview of your OpenShock setup.", + "home_hubs_online": "{{count}} online", + "home_hub_status": "Hub Status", + "home_no_hubs": "No hubs", + "home_all_online": "All online", + "home_all_offline": "All offline", + "home_some_online": "{{online}}/{{total}} online", + "home_quick_links": "Quick Links", + "home_my_shockers": "My Shockers", + "home_my_shockers_desc": "Control your shockers", + "home_hubs_desc": "Manage your hubs", + "home_shared_desc": "Shockers shared with you", + "home_public_desc": "Manage share links", + "home_get_started": "Get Started", + "home_get_started_desc": "You don't have any hubs yet. Create a hub to connect your first device, then add shockers to it.", + "home_set_up_hub": "Set Up a Hub", + "home_first_shocker": "Add Your First Shocker", + "home_first_shocker_desc_one": "You have {{count}} hub set up. Add a shocker to start controlling it.", + "home_first_shocker_desc_other": "You have {{count}} hubs set up. Add a shocker to start controlling it.", + "home_go_to_shockers": "Go to Shockers", + "profile_title": "Profile", + "profile_coming_soon": "Profile is coming soon", + "profile_coming_soon_desc": "Your public profile is not available yet. Account details live under Settings.", + "common_retry": "Retry", + "common_never_used": "Never used", + "common_expires": "Expires {{time}}", + "common_search_placeholder": "Search...", + "common_unknown": "Unknown", + "settings_breadcrumb_account": "Account", + "account_subtitle": "Your sign-in details and account actions.", + "account_change_username": "Change Username", + "account_change_email": "Change Email", + "account_change_password": "Change Password", + "account_username_label": "Username", + "account_email_label": "Email", + "account_password_label": "Password", + "account_new_password_label": "New Password", + "account_confirm_password_label": "Confirm New Password", + "account_oauth_only": "Not available for OAuth-only accounts", + "account_oauth_no_password": "This account signs in via OAuth and has no password.", + "account_diagnostics": "Diagnostics", + "account_diagnostics_desc": "Help us fix crashes and slow API calls. Reports include the error message, stack trace and your IP. Off by default.", + "account_diagnostics_level": "Diagnostics level", + "account_telemetry_off": "Off", + "account_telemetry_off_desc": "Send nothing.", + "account_telemetry_errors": "Errors", + "account_telemetry_errors_desc": "Send browser error reports only.", + "account_telemetry_full": "Full", + "account_telemetry_full_desc": "Error reports plus traces of API calls (no page navigations).", + "account_toast_deactivated": "Account deactivated successfully", + "account_deactivate_title": "Deactivate account", + "account_deactivate_desc": "Are you sure you want to deactivate your account?", + "account_deactivate": "Deactivate Account", + "account_email_title": "Change email", + "account_email_desc": "Enter your new email address and confirm with your current password.", + "account_email_toast_sent": "Verification email sent to {{email}}. Click the link in that email to apply the change.", + "account_new_email": "New Email", + "account_current_password": "Current Password", + "account_password_title": "Change password", + "account_password_desc": "Enter your current password and choose a new one.", + "account_password_toast": "Password has been changed", + "account_username_title": "Change username", + "account_username_desc": "Enter a new username.", + "account_new_username": "New Username", + "account_username_toast": "Username changed successfully", + "tokens_subtitle": "API Tokens are used to authenticate with the OpenShock API.", + "tokens_generate": "Generate Token", + "tokens_toast_refreshed": "Tokens refreshed successfully", + "tokens_empty_title": "No API tokens", + "tokens_empty_desc": "Generate a token to authenticate with the OpenShock API.", + "tokens_created_on": "Created {{date}}", + "tokens_last_used": "Last used {{time}}", + "tokens_never_expires": "Never expires", + "tokens_load_failed": "Failed to load API tokens.", + "token_toast_edited": "Token edited successfully", + "token_name_required": "Name is required", + "token_name_too_long": "Name is too long", + "token_edit_title": "Edit API token", + "token_name_label": "Token Name", + "token_name_placeholder": "Token name...", + "token_permissions": "Permissions", + "token_perm_category_shockers": "Shockers", + "token_perm_category_devices": "Hubs", + "token_perm_category_usershares": "User Shares", + "token_perm_category_publicshares": "Public Shares", + "token_perm_use": "Use", + "token_perm_edit": "Edit", + "token_perm_pause": "Pause", + "token_perm_auth": "Authenticate", + "token_shocker_control": "Shocker Control", + "token_toast_paused": "Token paused", + "token_toast_resumed": "Token resumed", + "token_delete_title": "Delete API token", + "token_delete_desc": "Are you sure you want to delete {{name}}?", + "token_delete_permanent": "This action cannot be undone. This will permanently delete the token.", + "token_toast_deleted": "Token deleted successfully", + "token_resume": "Resume token", + "token_pause": "Pause token", + "token_mode_clamp_desc": "Clamp: requests outside the allowed range are capped to the nearest limit (the min or the max).", + "token_mode_lerp_desc": "Lerp: the full input range is linearly rescaled so it fits within your allowed min–max range.", + "token_paused_desc": "A paused token may not send shocker control messages.", + "token_intensity_range": "Intensity range", + "token_duration_range": "Duration range", + "token_new_breadcrumb": "New", + "token_redirect_not_allowed": "The provided redirect_uri is not allowed. Only loopback addresses or custom application schemes are permitted.", + "token_params_missing": "Required get parameters are missing. Make sure name, redirect_uri, and permissions are provided.", + "token_invalid_permissions": "Invalid permissions provided: {{list}}", + "token_toast_created": "Token created successfully", + "token_request_title": "API Token Request", + "token_access_granted": "Access granted", + "token_shared_redirecting": "The token has been created and shared with the application. Redirecting you back to {{uri}}.", + "token_not_redirected": "If you are not redirected automatically, use the button below.", + "token_finish": "Finish", + "token_generated_title": "API Token Generated", + "token_copy_now": "Please copy your API Token now, you will not be able to view it again later!", + "token_new_title": "New API Token", + "token_external_desc": "An external application is requesting access to your account. Review and adjust the permissions below before allowing access.", + "token_new_desc": "Configure and generate a new API token for your account.", + "token_external_requesting": "{{name}} is requesting an API Token. Your token will be shared with the application at {{uri}}.", + "token_allow": "Allow", + "token_generate": "Generate", + "token_deny": "Deny", + "sessions_subtitle": "Every active session on your account. Revoke any you do not recognize.", + "sessions_unknown_device": "Unknown device", + "sessions_toast_refreshed": "Sessions refreshed successfully", + "sessions_load_failed": "Failed to load sessions.", + "sessions_empty_title": "No active sessions", + "sessions_empty_desc": "Sessions appear here once you sign in from a browser or app.", + "sessions_last_seen": "Last seen {{time}}", + "sessions_signed_in": "Signed in {{time}}", + "session_toast_revoked": "Session revoked successfully", + "session_revoke_title": "Revoke session", + "session_revoke": "Revoke", + "session_revoke_desc": "Are you sure you want to revoke this session?", + "session_revoke_from": "Session logged in from {{ip}} using {{agent}}", + "connections_title": "OAuth Connections", + "connections_subtitle": "Link or unlink third-party accounts to sign in faster and keep your profile in sync.", + "connections_toast_linked": "Account linked.", + "connections_toast_cancelled": "Link flow cancelled.", + "connections_toast_failed": "Linking failed.", + "connections_toast_removed": "Connection removed", + "connections_refreshing": "Refreshing…", + "connections_link_new": "Link new provider", + "connections_empty_title": "No connections yet", + "connections_empty_desc": "Choose “Link new provider” above to connect available providers.", + "connections_unlink": "Unlink", + "connections_load_failed": "Failed to load OAuth connections.", + "connections_unlink_title": "Unlink {{name}}?", + "connections_unlink_title_generic": "Unlink this account?", + "connections_unlink_desc": "You'll no longer be able to sign in with this provider unless you link it again.", + "provider_starting": "Starting {{name}}...", + "provider_link": "Link {{name}}", + "audit_subtitle": "Security-relevant activity on your account. Review anything you do not recognize.", + "audit_col_time": "Time", + "audit_col_action": "Action", + "audit_col_details": "Details", + "audit_col_reason": "Reason", + "audit_col_ip": "IP address", + "audit_col_device": "Device", + "audit_action_login": "Signed in", + "audit_action_logout": "Signed out", + "audit_action_password_changed": "Password changed", + "audit_action_email_change_requested": "Email change requested", + "audit_action_email_changed": "Email changed", + "audit_action_username_changed": "Username changed", + "audit_action_api_token_created": "API token created", + "audit_action_api_token_deleted": "API token deleted", + "audit_action_oauth_connected": "Connection added", + "audit_action_oauth_disconnected": "Connection removed", + "audit_action_account_deactivated": "Account deactivated", + "audit_action_account_reactivated": "Account reactivated", + "audit_action_account_deleted": "Account deleted", + "audit_action_automation_token_created": "Automation token created", + "audit_action_automation_token_updated": "Automation token updated", + "audit_action_automation_token_rotated": "Automation token rotated", + "audit_action_automation_token_deleted": "Automation token deleted", + "audit_action_automation_token_used": "Automation token used", + "audit_meta_session": "Session {{id}}", + "audit_meta_changed": "{{old}} to {{new}}", + "audit_meta_email_requested": "Requested change to {{email}}", + "audit_meta_accounts_removed_one": "{{name}} ({{count}} account removed)", + "audit_meta_accounts_removed_other": "{{name}} ({{count}} accounts removed)", + "audit_meta_scheduled_deletion": "Scheduled for deletion", + "audit_meta_kept": "Kept for reactivation", + "common_view": "View", + "common_save": "Save", + "common_saving": "Saving...", + "common_back": "Back", + "common_shared_by": "Shared by", + "common_user_avatar": "User Avatar", + "common_toast_saved": "Changes saved successfully", + "pause_reason_shocker": "Paused at shocker level", + "pause_reason_shocker_user_share": "Paused at shocker and user share level", + "pause_reason_shocker_public_share": "Paused at shocker and public share level", + "pause_reason_user_share": "Paused at user share level", + "pause_reason_public_share": "Paused at public share level", + "public_shares_subtitle": "A link anyone can use, no account required.", + "public_shares_new": "New Share", + "public_share_never_expires": "Never expires", + "public_shares_empty_title": "No public shares yet", + "public_shares_empty_desc": "Create a link that anyone can use to control your shockers.", + "public_share_expired": "Expired", + "public_share_no_expiry": "No expiry", + "public_share_label": "Public Share", + "public_share_toast_created": "Created new public share", + "public_share_create_title": "Create public share", + "public_share_toast_deleted": "Deleted public share", + "public_share_delete_title": "Delete public share", + "public_share_delete_desc": "Are you sure you want to delete public share {{name}}?", + "public_share_edit_title": "Public Share: {{name}}", + "public_share_edit_subtitle": "Editing: changes apply when you save.", + "public_share_add_shocker": "Add Shocker", + "public_share_toast_added_one": "Added {{count}} shocker to share", + "public_share_toast_added_other": "Added {{count}} shockers to share", + "public_share_empty_shockers_title": "No shockers in this share", + "public_share_empty_shockers_desc": "Add a shocker and anyone with the link will be able to control it.", + "public_share_load_failed": "Error fetching public share details", + "public_share_paused_here": "Paused for this share", + "public_share_resume_shocker": "Resume shocker", + "public_share_pause_shocker": "Pause shocker", + "public_share_remove": "Remove from share", + "public_share_toast_removed": "Shocker removed from share", + "public_share_add_title": "Add shockers", + "public_share_add_desc": "Add shockers to this public share. You can set their limits once they are added.", + "public_share_add_placeholder": "Select shockers to share...", + "public_share_add_no_match": "No matching shockers", + "public_share_add_submit": "Add Shockers", + "public_share_view_loading": "Loading share details...", + "public_share_view_title": "Public Share Link", + "public_share_view_desc": "Enter as a guest or login with your OpenShock account", + "public_share_view_guest_name": "Guest Name", + "public_share_view_enter": "Enter", + "public_share_view_enter_guest": "Enter as Guest", + "public_share_login": "Login", + "perm_shock_on": "Shock enabled", + "perm_shock_off": "Shock disabled", + "perm_vibrate_on": "Vibrate enabled", + "perm_vibrate_off": "Vibrate disabled", + "perm_sound_on": "Sound enabled", + "perm_sound_off": "Sound disabled", + "perm_live_on": "Live enabled", + "perm_live_off": "Live disabled", + "perm_live_control": "Live Control", + "user_selector_avatar_of": "{{name}}'s avatar", + "user_selector_placeholder": "Enter user name", + "user_selector_aria": "Username to search", + "user_selector_search": "Search user", + "user_selector_found": "User found", + "common_remove": "Remove", + "user_shares_subtitle": "Direct permanent shares with other users.", + "user_shares_toast_invited": "Sent a shocker invite to {{name}}", + "user_shares_redeem": "Redeem Code", + "user_shares_new": "New Share", + "user_shares_tab_shares": "Shares", + "user_shares_tab_incoming": "Shared with Me", + "user_shares_tab_invites": "Invites", + "share_code_create_title": "New share code", + "share_code_create_desc": "Create a Share Code or Invite", + "share_code_shocker_placeholder": "Select shockers to share...", + "share_code_no_match": "No matching shockers", + "share_code_send_invite": "Send Share Invite", + "share_code_create": "Create Share Code", + "share_code_created_title": "Share code generated", + "share_code_created_desc": "Please copy share code or code link!", + "share_code_redeem_title": "Redeem share code", + "share_code_redeem_desc": "Enter the share code to redeem", + "share_code_redeem_placeholder": "Enter share code", + "share_code_redeemed": "Redeemed successfully!", + "share_code_shared_shockers": "Shared shockers", + "share_code_redeeming": "Redeeming...", + "share_code_redeem": "Redeem", + "incoming_shares_empty_title": "Nothing shared with you", + "incoming_shares_empty_desc": "No one has shared a shocker with you yet.", + "incoming_share_toast_removed": "Removed share for {{name}}", + "incoming_share_remove_title": "Remove Share", + "incoming_share_remove_desc": "Are you sure you want to remove the share for {{name}}?", + "incoming_share_toast_removed_shocker": "Removed {{shocker}} shared by {{name}}", + "incoming_share_remove_shocker_title": "Remove this shared shocker?", + "incoming_share_remove_shocker_desc": "Are you sure you want to remove the shocker share {{shocker}} by {{name}}?", + "incoming_share_manage_from": "Manage shares from", + "share_remove": "Remove share", + "invites_empty_title": "No invites yet", + "invites_empty_desc": "You have no incoming or outgoing share invites.", + "invites_outgoing": "Outgoing", + "invites_outgoing_empty_title": "No outgoing invites", + "invites_outgoing_empty_desc": "You have no outgoing share invites.", + "invites_incoming": "Incoming", + "invites_incoming_empty_title": "No incoming invites", + "invites_incoming_empty_desc": "You have no incoming share invites.", + "invite_toast_accepted": "Accepted share invite from {{name}}", + "invite_toast_declined": "Declined share invite from {{name}}", + "invite_deny_title": "Deny Invite", + "invite_deny_label": "Deny Invite", + "invite_deny": "Deny", + "invite_deny_desc": "Are you sure you want to deny the invite from {{name}}?", + "invite_accept": "Accept Invite", + "invite_toast_cancelled_for": "Cancelled invite for {{name}} ({{id}})", + "invite_toast_cancelled": "Cancelled invite {{id}}", + "invite_cancel_title": "Cancel Invite", + "invite_cancel": "Cancel", + "invite_cancel_for_desc": "Are you sure you want to cancel the invite for {{name}}?", + "invite_cancel_code_desc": "Are you sure you want to cancel the invite with code {{code}}?", + "invite_cancel_outstanding": "Cancel Outstanding Invite", + "outgoing_shares_empty_title": "No shared shockers", + "outgoing_shares_empty_desc": "You haven't shared any shockers with other users yet.", + "outgoing_share_toast_removed": "Removed shocker share {{name}}", + "outgoing_share_remove_title": "Stop sharing this shocker?", + "outgoing_share_editing_for": "Editing shares for", + "outgoing_share_limits": "Limits & Permissions", + "outgoing_share_same": "Same restrictions on every shocker", + "outgoing_share_per_desc": "Tune restrictions per shocker", + "outgoing_share_all": "All", + "outgoing_share_per": "Per shocker", + "outgoing_share_remove_desc": "Are you sure you want to stop sharing {{shocker}} with {{name}}?", + "report_breadcrumb": "Report API Tokens", + "report_toast_clipboard_failed": "Failed to read clipboard: {{error}}", + "report_title": "Report Leaked API Tokens", + "report_paste": "Paste from clipboard", + "report_warning": "This form is only for reporting accidentally leaked API tokens.", + "report_abuse_warning": "Intentional abuse will result in bans or severe endpoint restrictions.", + "report_detected": "Detected Tokens", + "report_invalid": "One or more tokens appear to be invalid. Please check for formatting issues.", + "report_acknowledge": "I confirm I understand what this feature is for and accept responsibility.", + "report_submit": "Submit Report", + "turnstile_disabled": "Turnstile disabled", + "common_internal_error": "Internal error", + "resend_toast_sent": "Activation email sent. Check your inbox and spam folder.", + "resend_toast_throttled": "Too many activation emails have been requested. Please try again later.", + "resend_toast_unavailable": "No activation email can be resent from this browser. If your account isn't activated yet, logging in sends a new link.", + "resend_button": "Didn't get the email? Resend", + "expiration_label": "Expiration", + "expiration_never": "Never", + "expiration_custom": "Custom", + "expiration_days_one": "{{count}} Day", + "expiration_days_other": "{{count}} Days", + "expiration_required": "Expire date is required", + "expiration_never_desc": "This will never expire", + "expiration_expires_at": "Expires {{time}} ({{date}})", + "date_picker_placeholder": "Pick a date", + "telemetry_toast_title": "Help improve OpenShock?", + "telemetry_toast_desc": "Send diagnostics to help us fix crashes and slow API calls. Reports include the error message, stack trace and your IP. You can change this any time in Account settings.", + "telemetry_toast_no": "No thanks", + "telemetry_toast_errors": "Errors only", + "telemetry_toast_full": "Full", + "table_show_details": "Show details", + "table_hide_details": "Hide details", + "table_no_results": "No results.", + "table_sort_asc": "Sort by {{name}}, ascending", + "table_sort_desc": "Sort by {{name}}, descending", + "table_sort_none": "Sort by {{name}}, unsorted", + "cell_na": "N/A", + "cell_not_applicable": "Not applicable", + "cell_invalid": "Invalid", + "cell_unavailable": "Unavailable", + "cell_none": "None", + "oauth_login_with": "Login with {{provider}}", + "oauth_signup_with": "Signup with {{provider}}", + "signalr_connect_failed": "Failed to connect to server!", + "signalr_disconnect_failed": "Encountered error while disconnecting from server!", + "signalr_invalid_update": "Received invalid update from server!", + "signalr_invalid_log": "Received invalid log data from server!", + "signalr_invalid_ota": "Received invalid firmware update data from server!", + "ota_toast_failed": "Hub firmware update failed: {{message}}", + "ota_toast_succeeded": "Hub firmware update completed successfully!", + "ota_toast_rolled_back": "Hub firmware rolled back to previous version", + "lcg_connect_failed": "Failed to connect to live control gateway", + "terminal_toast_bootloader_failed": "Failed to enter bootloader: {{error}}", + "terminal_toast_app_mode_failed": "Failed to enter application mode: {{error}}", + "problem_account_account_not_activated_title": "Account not activated", + "problem_account_account_not_activated_desc": "Check your inbox for the activation email.", + "problem_account_activation_not_found_title": "Activation link is invalid", + "problem_account_activation_not_found_desc": "The link may have expired or already been used.", + "problem_account_activation_resend_too_many_title": "Too many activation emails requested", + "problem_account_activation_resend_too_many_desc": "Please wait a while before trying again.", + "problem_account_activation_resend_unavailable_title": "Cannot resend activation email", + "problem_account_activation_resend_unavailable_desc": "Log in again to request a new activation link.", + "problem_account_deactivate_already_deactivated_title": "Account is already deactivated", + "problem_account_deactivate_denied_privileged_title": "Privileged accounts cannot be deactivated", + "problem_account_deactivate_unauthorized_title": "You are not allowed to do this", + "problem_account_deactivated_title": "This account has been deactivated", + "problem_account_email_already_in_use_title": "That email address is already in use", + "problem_account_email_invalid_title": "That email address is not valid", + "problem_account_email_taken_title": "That email address is already in use", + "problem_account_email_too_many_requests_title": "Too many email change requests", + "problem_account_email_too_many_requests_desc": "Please wait a while before trying again.", + "problem_account_email_unchanged_title": "That is already your email address", + "problem_account_email_verify_not_found_title": "Verification link is invalid", + "problem_account_email_verify_not_found_desc": "The link may have expired or already been used.", + "problem_account_o_auth_only_title": "This account has no password", + "problem_account_o_auth_only_desc": "Sign in with the provider you signed up with.", + "problem_account_password_not_set_title": "No password set", + "problem_account_password_not_set_desc": "This account signs in through an external provider.", + "problem_account_password_old_password_invalid_title": "Current password is incorrect", + "problem_account_username_invalid_title": "That username is not allowed", + "problem_account_username_recently_changed_title": "Username changed too recently", + "problem_account_username_recently_changed_desc": "You can change your username once every 7 days.", + "problem_account_username_taken_title": "That username is already taken", + "problem_admin_user_deactivated_title": "This user is deactivated", + "problem_admin_user_not_activated_title": "This user has not been activated yet", + "problem_api_token_can_only_delete_self_title": "An API token can only delete itself", + "problem_api_token_not_found_title": "API token not found", + "problem_api_token_paused_title": "This API token is paused", + "problem_assign_lcg_bad_schema_version_title": "Unsupported hub protocol version", + "problem_assign_lcg_bad_schema_version_desc": "Update the hub firmware to connect.", + "problem_assign_lcg_no_lcg_available_title": "No gateway available", + "problem_assign_lcg_no_lcg_available_desc": "No live control gateway is available right now. Please try again later.", + "problem_authentication_account_deactivated_title": "This account has been deactivated", + "problem_authentication_account_not_activated_title": "This account has not been activated", + "problem_authentication_cookie_missing_or_invalid_title": "You are not logged in", + "problem_authentication_cookie_missing_or_invalid_desc": "Your session may have expired. Please log in again.", + "problem_authentication_header_missing_or_invalid_title": "Invalid API token", + "problem_authentication_session_invalid_title": "Session expired", + "problem_authentication_session_invalid_desc": "Please log in again.", + "problem_authentication_token_invalid_title": "Invalid API token", + "problem_authentication_unknown_error_title": "Authentication failed", + "problem_authorization_policy_not_met_title": "You do not have permission to do this", + "problem_authorization_token_only_title": "This action requires an API token", + "problem_authorization_token_permission_missing_title": "This API token is missing a required permission", + "problem_authorization_unknown_error_title": "Authorization failed", + "problem_authorization_user_session_only_title": "This action requires a logged-in session", + "problem_automation_token_not_allowed_for_account_title": "Automation tokens cannot be used with privileged accounts", + "problem_configuration_already_exists_title": "A configuration entry with that name already exists", + "problem_configuration_invalid_name_format_title": "Invalid configuration name", + "problem_configuration_invalid_name_format_desc": "Only A to Z and underscores are allowed.", + "problem_configuration_invalid_value_format_title": "Value does not match the configuration type", + "problem_configuration_not_found_title": "Configuration entry not found", + "problem_control_stats_invalid_range_title": "The from date must not be after the to date", + "problem_control_stats_invalid_time_zone_title": "Unknown time zone", + "problem_control_stats_missing_capability_title": "Control statistics are not available on this server", + "problem_device_not_found_title": "Hub not found", + "problem_device_not_online_title": "Hub is offline", + "problem_device_too_many_hubs_title": "You have reached the maximum number of hubs", + "problem_device_too_many_shockers_title": "This hub has reached its maximum number of shockers", + "problem_endpoint_retired_title": "This feature is no longer available", + "problem_expression_error_title": "Invalid filter expression", + "problem_internal_server_error_title": "Something went wrong on our end", + "problem_login_invalid_credentials_title": "Invalid username or password", + "problem_login_invalid_domain_title": "Logging in from this address is not allowed", + "problem_o_auth_connection_already_exists_title": "Your account is already connected to this provider", + "problem_o_auth_connection_already_linked_title": "This external account is already linked to another user", + "problem_o_auth_flow_anonymous_only_title": "You are already signed in", + "problem_o_auth_flow_mismatch_title": "Sign-in attempt does not match", + "problem_o_auth_flow_mismatch_desc": "Please start over.", + "problem_o_auth_flow_missing_data_title": "The provider did not return your account details", + "problem_o_auth_flow_missing_data_desc": "Please try again.", + "problem_o_auth_flow_not_found_title": "Sign-in attempt expired", + "problem_o_auth_flow_not_found_desc": "Please start over.", + "problem_o_auth_flow_unsupported_title": "Unsupported sign-in flow", + "problem_o_auth_internal_error_title": "Something went wrong during sign-in", + "problem_o_auth_internal_error_desc": "Please try again in a moment.", + "problem_o_auth_link_authenticated_user_only_title": "You must be signed in to link an external account", + "problem_o_auth_provider_mismatch_title": "Sign-in attempt does not match the provider", + "problem_o_auth_provider_mismatch_desc": "Please start over.", + "problem_o_auth_provider_unsupported_title": "This sign-in provider is not supported", + "problem_pair_code_not_found_title": "Pair code not found", + "problem_password_reset_not_found_title": "Password reset link is invalid", + "problem_password_reset_not_found_desc": "The link may have expired or already been used.", + "problem_session_not_found_title": "Session not found", + "problem_share_get_no_shares_title": "You have no shares with this user", + "problem_share_request_create_cannot_share_with_self_title": "You cannot share with yourself", + "problem_share_request_create_shocker_not_found_title": "One or more shockers were not found", + "problem_share_request_create_shocker_not_found_desc": "They may have been removed or do not belong to you.", + "problem_share_request_not_found_title": "Share invite not found", + "problem_share_user_not_found_title": "Share not found", + "problem_share_code_already_linked_title": "Shocker is already linked to your account", + "problem_share_code_cant_link_own_share_code_title": "You cannot redeem your own share code", + "problem_share_code_not_found_title": "Share code not found", + "problem_share_link_expiry_date_in_past_title": "Expiry date cannot be in the past", + "problem_share_link_not_found_title": "Public share not found", + "problem_share_link_shocker_already_in_share_link_title": "Shocker is already in this public share", + "problem_share_link_shocker_not_in_share_link_title": "Shocker is not in this public share", + "problem_shocker_control_no_permission_title": "You do not have permission to control this shocker", + "problem_shocker_control_not_found_title": "Shocker not found", + "problem_shocker_control_paused_title": "Shocker is paused", + "problem_shocker_not_found_title": "Shocker not found", + "problem_signup_registration_disabled_title": "Registration is currently disabled", + "problem_signup_username_or_email_exists_title": "That username or email is already in use", + "problem_turnstile_invalid_title": "Verification failed", + "problem_turnstile_invalid_desc": "Please complete the challenge again and retry.", + "problem_user_not_found_title": "User not found", + "problem_user_privileged_delete_denied_title": "Privileged users cannot be deleted", + "problem_validation_error_title": "Some fields are invalid", + "problem_webhook_not_found_title": "Webhook not found", + "problem_webhook_unsupported_title": "Only Discord webhooks are supported", + "problem_webhook_unsupported_desc": "Use a discord.com URL, not canary or ptb.", + "error_too_many_requests": "Too many requests", + "error_retry_after_one": "Try again in {{count}} second.", + "error_retry_after_other": "Try again in {{count}} seconds.", + "error_unexpected_response": "Unexpected server response", + "error_internal": "Internal error occurred", + "error_network": "Network error occurred", + "dev_banner": "This is the OpenShock DEVELOPMENT environment. No data is saved, and it is regularly overwritten by production data.", + "firmware_channel_bugs_warning": "This channel might contain bugs." +} From 998a3caf1cf9cbbfa566076fd6aa283384026809 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Luc=20=E2=99=A5?= Date: Thu, 12 Nov 2026 17:43:09 +0100 Subject: [PATCH 08/27] New translations en.json (Danish) [ci skip] --- messages/da.json | 1055 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 1055 insertions(+) create mode 100644 messages/da.json diff --git a/messages/da.json b/messages/da.json new file mode 100644 index 00000000..ef4df56c --- /dev/null +++ b/messages/da.json @@ -0,0 +1,1055 @@ +{ + "landing_tagline": "The go-to platform for safe, reliable, real low-latency remote shocking.", + "landing_section_label": "Home", + "landing_hubs_online": "Hubs online right now: ", + "landing_learn_more": "Learn More", + "landing_wiki": "Wiki", + "landing_meta_description": "Welcome to OpenShock, a free and open-source ecosystem to control various shock collars over the internet.", + "instance_meta_description": "Welcome to {{siteName}}, an independent instance of OpenShock, a free and open-source ecosystem to control various shock collars over the internet.", + "header_sidebar_toggle": "Toggle Sidebar", + "header_avatar_alt": "{{name}}'s avatar", + "header_menu_profile": "Profile", + "header_menu_settings": "Settings", + "header_menu_logout": "Logout", + "header_login": "Login", + "header_signup": "Sign Up", + "header_github_title": "OpenShock on GitHub", + "header_discord_title": "Community Discord", + "footer_made_with": "Made with by the OpenShock Team", + "footer_connection_status_label": "Server connection status", + "footer_signalr_state": "SignalR State", + "footer_frontend_version": "Frontend Version", + "footer_frontend_commit_title": "Commit {{commit}}", + "footer_backend_version": "Backend Version", + "footer_backend_commit_title": "Commit {{commit}}", + "footer_language_label": "Language", + "sidebar_home_link_label": "OpenShock home", + "sidebar_group_general": "General", + "sidebar_home": "Home", + "sidebar_shockers": "Shockers", + "sidebar_shared_shockers": "Shared Shockers", + "sidebar_hubs": "Hubs", + "sidebar_user_shares": "User Shares", + "sidebar_public_shares": "Public Shares", + "sidebar_serial_terminal": "Serial Terminal", + "sidebar_group_admin": "Admin", + "sidebar_admin_monitoring": "Monitoring", + "sidebar_admin_online_hubs": "Online Hubs", + "sidebar_admin_online_gateways": "Online Gateways", + "sidebar_admin_management": "Management", + "sidebar_admin_users": "Users", + "sidebar_admin_blacklists": "Blacklists", + "sidebar_admin_webhooks": "Webhooks", + "sidebar_admin_mail": "Mail", + "sidebar_admin_automation_tokens": "Automation Tokens", + "sidebar_admin_configuration": "Configuration", + "sidebar_group_settings": "Settings", + "sidebar_settings_api_tokens": "API Tokens", + "sidebar_settings_sessions": "Sessions", + "sidebar_settings_audit_log": "Audit Log", + "sidebar_settings_connections": "Connections", + "sidebar_settings_account": "Account Settings", + "error_meta_title": "Service Unavailable", + "error_meta_description": "OpenShock is currently unavailable", + "error_meta_logo_alt": "OpenShock Logo", + "error_fallback_message": "Something went wrong.", + "error_not_found_message": "Page not found", + "error_not_found_description": "The page you're looking for doesn't exist.", + "error_unexpected_description": "An unexpected error occurred.", + "error_go_back": "Go back", + "auth_layout_logo_alt": "OpenShock Logo", + "auth_layout_invalid_redirect_removed": "An invalid redirect URL was removed for your safety.", + "auth_activate_breadcrumb": "Activate Account", + "auth_activate_title": "Activate Account", + "auth_activate_activating": "Activating your account...", + "auth_activate_success": "Your account has been activated", + "auth_activate_failed": "This activation link is invalid or has expired", + "auth_activate_missing_token": "Missing activation token", + "auth_activate_continue": "Continue to login", + "auth_activate_toast_success": "Account activated", + "auth_forgot_breadcrumb": "Forgot Password", + "auth_forgot_title": "Forgot Password", + "auth_forgot_description": "Enter your email to reset your password", + "auth_forgot_email_label": "Email", + "auth_forgot_email_placeholder": "Email", + "auth_forgot_submit": "Reset Password", + "auth_forgot_signin_prompt": "Remember your password? Sign in", + "auth_forgot_mail_disabled": "Password resets are unavailable on this instance because it has no mail provider configured. Please contact your administrator for help recovering your account.", + "auth_forgot_toast_sent": "Reset password request has been sent to the given email", + "auth_login_breadcrumb": "Login", + "auth_login_title": "Welcome back", + "auth_login_loading_methods": "Loading available login methods", + "auth_login_choose_method": "Login with one of these methods", + "auth_login_with_account": "Login with your OpenShock Account", + "auth_login_activation_after_signup": "Your account has been created. We've sent an activation link to your email address. Check your inbox and spam folder.", + "auth_login_activation_pending": "Your account isn't activated yet. We've sent an activation link to your email address. Check your inbox and spam folder. If nothing arrives, try logging in again later to get a new link.", + "auth_login_oauth_only": "This account has no password. Sign in with the provider you signed up with.", + "auth_login_oauth_only_with_buttons": "This account has no password. Sign in with the provider you signed up with using the buttons above.", + "auth_login_or_continue_with": "Or continue with", + "auth_login_username_label": "Username or Email", + "auth_login_password_label": "Password", + "auth_login_submit": "Login", + "auth_login_signup_prompt": "Don't have an account? Sign up", + "auth_login_legal": "By clicking Login, you agree to our Terms of Service and Privacy Policy.", + "auth_oauth_create_breadcrumb": "Sign Up With {{provider}}", + "auth_oauth_create_title": "Sign Up With {{provider}}", + "auth_oauth_create_description": "Complete your account details", + "auth_oauth_create_username_label": "Username", + "auth_oauth_create_username_placeholder": "Username", + "auth_oauth_create_email_label": "Email", + "auth_oauth_create_email_placeholder": "Email", + "auth_oauth_create_submit": "Sign Up", + "auth_oauth_create_legal": "By clicking Sign Up, you agree to our Terms of Service and Privacy Policy.", + "auth_oauth_error_breadcrumb": "Authentication Error", + "auth_oauth_error_title": "Authentication Error", + "auth_oauth_error_back": "Back to login", + "auth_reset_breadcrumb": "Reset Password", + "auth_reset_title": "Reset Password", + "auth_reset_checking": "Verifying reset link...", + "auth_reset_choose_password": "Choose a new password for your account", + "auth_reset_invalid": "This reset link is invalid or has expired", + "auth_reset_password_label": "New Password", + "auth_reset_password_placeholder": "New Password", + "auth_reset_confirm_label": "Confirm New Password", + "auth_reset_confirm_placeholder": "Confirm New Password", + "auth_reset_submit": "Reset Password", + "auth_reset_request_new": "Request a new reset link", + "auth_reset_toast_success": "Password has been reset", + "auth_signup_breadcrumb": "Sign Up", + "auth_signup_toast_created_mail": "Account created successfully. Please check your email to verify your account.", + "auth_signup_toast_created_no_mail": "Account created successfully. You can log in now.", + "auth_signup_dialog_title": "Welcome! Thank you for signing up! ❤️", + "auth_signup_dialog_created_mail": "Your account has been created. 🎉 Please check your email to verify your account.", + "auth_signup_dialog_verify_then_login": "After verifying your email, you can log in to your account.", + "auth_signup_dialog_created_no_mail": "Your account has been created and is ready to use. 🎉", + "auth_signup_dialog_login_now": "You can log in to your account now.", + "auth_signup_title": "Create your account", + "auth_signup_loading_methods": "Loading available sign-up methods", + "auth_signup_using_email": "Signing up using email", + "auth_signup_choose_method": "Choose your preferred sign-up method", + "auth_signup_back": "Back", + "auth_signup_username_label": "Username", + "auth_signup_username_placeholder": "John OpenShock", + "auth_signup_email_label": "Email", + "auth_signup_email_placeholder": "john@example.com", + "auth_signup_password_label": "Password", + "auth_signup_password_placeholder": "Password", + "auth_signup_confirm_label": "Confirm Password", + "auth_signup_confirm_placeholder": "Confirm Password", + "auth_signup_submit": "Create Account", + "auth_signup_signin_prompt": "Already have an account? Sign in", + "auth_signup_or": "Or", + "auth_signup_with_email": "Signup with Email", + "auth_signup_legal": "By clicking Create Account, you agree to our Terms of Service and Privacy Policy.", + "auth_verify_breadcrumb": "Verify Email", + "auth_verify_title": "Verify Email", + "auth_verify_verifying": "Verifying your email address...", + "auth_verify_success": "Your email has been verified", + "auth_verify_failed": "This verification link is invalid or has expired", + "auth_verify_missing_token": "Missing verification token", + "auth_verify_continue": "Continue to login", + "auth_verify_toast_success": "Email verified", + "common_cancel": "Cancel", + "common_delete": "Delete", + "common_edit": "Edit", + "common_share": "Share", + "common_copy_id": "Copy ID", + "common_id_copied": "ID copied to clipboard", + "common_open_menu": "Open menu", + "common_refresh": "Refresh", + "common_settings": "Settings", + "common_clear": "Clear", + "common_online": "Online", + "common_offline": "Offline", + "common_paused": "Paused", + "common_resume": "Resume", + "common_resuming": "Resuming...", + "common_coming_soon": "(Coming soon)", + "common_save_changes": "Save Changes", + "common_danger_zone": "Danger Zone", + "common_name": "Name", + "control_intensity": "Intensity", + "control_duration": "Duration", + "control_max_intensity": "Max Intensity", + "control_max_duration": "Max Duration", + "control_vibration": "Vibration", + "control_value": "Value", + "control_live_intensity": "Live intensity", + "control_type_stop": "Stop", + "control_type_shock": "Shock", + "control_type_vibrate": "Vibrate", + "control_type_sound": "Sound", + "live_tooltip_active": "Live via {{gateway}} ({{country}}), {{latency}}ms", + "live_tooltip_connecting": "Connecting...", + "live_tooltip_connect": "Connect to Live Control", + "live_tooltip_hub_start": "Ctrl+click to start the whole hub", + "live_tooltip_hub_stop": "Ctrl+click to stop the whole hub", + "pause_resume_shocker": "Resume shocker", + "pause_pause_shocker": "Pause shocker", + "pause_resume_all": "Resume all shockers", + "pause_pause_all": "Pause all shockers", + "shocker_label": "Shocker", + "shocker_hub": "Hub", + "shocker_select_hub": "Select hub", + "shocker_rf_id": "RF ID", + "shocker_rf_id_invalid": "RF ID must be a whole number between {{min}} and {{max}}.", + "shocker_model": "Model", + "shocker_select_model": "Select model", + "shocker_name_placeholder": "Shocker name", + "shocker_menu_view_logs": "View Logs", + "shocker_delete_title": "Delete Shocker", + "shocker_delete_desc": "Are you sure you want to delete \"{{name}}\"? This action cannot be undone.", + "shocker_toast_deleted": "Shocker \"{{name}}\" deleted", + "shocker_toast_paused": "Shocker paused", + "shocker_toast_resumed": "Shocker resumed", + "shocker_add_desc": "Register a new shocker to one of your hubs.", + "shocker_add_name_placeholder": "My Shocker", + "shockers_title": "Shockers", + "shockers_subtitle": "Every shocker paired to your hubs.", + "shockers_loading": "Loading shockers...", + "shockers_toast_refreshed": "Shockers refreshed", + "shockers_toast_need_hub": "You need to create a hub before adding shockers.", + "shockers_toast_added": "Shocker added", + "shockers_unknown_module": "Unknown module type", + "shockers_add": "Add Shocker", + "shockers_view_mode": "View mode", + "shockers_mode_classic": "Classic", + "shockers_mode_rich": "Rich", + "shockers_mode_simple": "Simple", + "shockers_mode_map": "Map", + "shockers_group_by_hub": "Group by Hub", + "shockers_global_limits": "Global Limits", + "shockers_logs_label": "Logs", + "shockers_empty_title": "No shockers yet", + "shockers_empty_no_hubs": "Create a hub first, then add shockers to it.", + "shockers_empty_has_hubs": "Add a shocker to one of your hubs to get started.", + "shockers_create_hub": "Create a Hub", + "shockers_count_one": "{{count}} shocker", + "shockers_count_other": "{{count}} shockers", + "shared_shockers_title": "Shared Shockers", + "shared_shockers_subtitle": "Shockers other users have shared with you.", + "shared_shockers_empty_title": "No shockers have been shared with you yet.", + "shared_shockers_empty_desc": "When someone shares their shockers with you, they'll appear here.", + "shocker_logs_title": "Shocker Logs", + "shocker_logs_subtitle": "Every control command sent to your shockers.", + "shocker_logs_live_title": "New logs appear in real time", + "shocker_logs_paused_title": "Live updates pause when sorting or viewing a page other than the first", + "shocker_logs_live": "Live", + "shocker_logs_col_time": "Time", + "shocker_logs_col_type": "Type", + "shocker_logs_col_by": "By", + "shocker_logs_filter_label": "Filter by shocker", + "shocker_logs_filter_placeholder": "Search shockers...", + "shocker_logs_filter_all": "All shockers", + "shocker_logs_filter_none": "No matching shockers", + "shocker_edit_title": "Edit Shocker", + "shocker_edit_subtitle": "Change this shocker's details or remove it.", + "shocker_edit_back": "Back to Shockers", + "shocker_edit_load_failed": "Failed to load shocker.", + "shocker_edit_loading": "Loading shocker...", + "shocker_edit_details_title": "Shocker Details", + "shocker_edit_details_desc": "Update the name, RF ID, and model for this shocker.", + "shocker_edit_pause_state": "Pause State", + "shocker_edit_is_paused": "Shocker is paused", + "shocker_edit_is_active": "Shocker is active", + "shocker_edit_toast_updated": "Shocker updated", + "shocker_edit_delete_desc": "Permanently delete this shocker. This action cannot be undone.", + "common_close": "Close", + "common_continue": "Continue", + "common_loading": "Loading...", + "common_previous": "Previous", + "common_next": "Next", + "common_steps": "Steps", + "common_step_label": "Step {{number}}: {{title}}", + "common_copy": "Copy", + "common_copied": "Copied", + "common_never": "Never", + "common_error": "Error: {{message}}", + "terminal_title": "Serial Terminal", + "terminal_connecting": "Connecting...", + "terminal_help_button": "I'm having trouble, help?", + "terminal_back_to_modes": "Back to mode picker", + "terminal_mode_configure": "Configure Device", + "terminal_mode_configure_desc": "Configure WiFi, authentication, and more. Includes an interactive serial console.", + "terminal_mode_flash": "Flash Firmware", + "terminal_mode_flash_desc": "Install or update firmware on a connected device.", + "terminal_mode_raw": "Serial Monitor", + "terminal_mode_raw_desc": "Just the console. Read device logs and send commands.", + "terminal_step_channel": "Select Channel", + "terminal_step_board": "Select Board", + "terminal_go_to_step": "Go to step {{number}}: {{title}}", + "terminal_erase": "Erase before flashing", + "terminal_erase_desc": "Clears all data on the device including existing configs", + "terminal_unsupported": "Your browser does not support this feature.", + "terminal_update_browser": "Please update your browser to the latest version.", + "terminal_use_browsers": "Please use one of the following browsers:", + "terminal_connect_failed_bootloader": "Could not enter bootloader mode", + "terminal_connect_failed": "Device connection failed", + "terminal_connect_failed_desc": "We couldn't establish a serial connection with the device.", + "terminal_quick_tries": "Quick things to try:", + "terminal_try_replug": "Unplug and replug the device.", + "terminal_try_cable": "Try a different USB cable or port.", + "terminal_try_driver": "Make sure the serial driver is installed.", + "terminal_open_troubleshooter": "Open troubleshooter", + "terminal_log_reset_no_device": "Host-side error during reset: no device!", + "terminal_log_reset_error": "Host-side error during reset: {{error}}", + "terminal_log_send_no_device": "Couldn't send: no device!", + "terminal_log_send_error": "Couldn't send: {{error}}", + "terminal_log_firmware_disconnected": "Firmware disconnected: {{error}}", + "terminal_log_erase_failed": "Failed to erase flash: {{error}}", + "terminal_log_hard_reset_failed": "Failed to hard reset: {{error}}", + "terminal_log_flash_complete": "Flash complete", + "terminal_log_flash_failed": "Failed to flash: {{error}}", + "terminal_log_command_failed": "Failed to write application command: {{error}}", + "terminal_help_title": "Troubleshooter", + "terminal_help_desc": "Work through these steps in order. Each one rules out a common cause.", + "terminal_help_step_cable": "USB cable", + "terminal_help_step_port": "USB port", + "terminal_help_step_driver": "Install driver", + "terminal_help_step_manual": "Manual driver update", + "terminal_help_step_discord": "Ask on Discord", + "terminal_help_cable_body": "Many USB-C and micro-USB cables are charge-only and don't carry data. Swap to a known-good data cable (one you've used to transfer files or connect other devices) and reconnect the hub.", + "terminal_help_port_body": "Plug the device directly into a USB port on your computer. Avoid USB hubs, docking stations, and front-panel ports if possible; these are common sources of power and signal issues. If you're on a desktop, try a port on the back of the machine.", + "terminal_help_driver_download": "Download the CP210x driver:", + "terminal_help_driver_extract": "Extract the contents of the zip file to a folder on your computer.", + "terminal_help_driver_run": "Open the folder and run {{installer}}. Follow the prompts to install.", + "terminal_help_driver_reconnect": "Reconnect the device.", + "terminal_help_manual_intro": "If the driver installer ran but the device still doesn't show up:", + "terminal_help_manual_open": "Open Device Manager (press Win + X and select Device Manager).", + "terminal_help_manual_ports": "Under Ports (COM & LPT), look for an entry like:", + "terminal_help_manual_missing": "If it's missing, the device isn't being detected by Windows at all; revisit the cable and port steps.", + "terminal_help_manual_update": "Right-click the device and pick Update Driver.", + "terminal_help_manual_browse": "Choose Browse my computer for drivers and select the folder you extracted the driver zip into. Make sure Include subfolders is checked.", + "terminal_help_manual_success": "On success, the entry should now read {{deviceName}}.", + "terminal_help_discord_intro": "Still stuck after all of the above? Hop into our Discord server and ask in the {{channel}} channel. Please include:", + "terminal_help_discord_os": "your operating system and browser", + "terminal_help_discord_device": "the device you're using (board model, where you got it)", + "terminal_help_discord_tried": "what you've already tried from the previous steps", + "terminal_help_discord_errors": "any error messages or relevant terminal output", + "terminal_help_discord_join": "Join our Discord server", + "terminal_risk_title": "⚠️ UNSTABLE FIRMWARE", + "terminal_risk_intro": "You are about to flash experimental firmware that is known to be unstable.", + "terminal_risk_brick": "This may permanently brick your device, require manual recovery, or render it unusable.", + "terminal_risk_no_support": "We will NOT provide support for issues caused by this firmware.", + "terminal_risk_acknowledge": "I understand this is entirely my responsibility", + "terminal_risk_abort": "Abort", + "terminal_risk_accept": "I ACCEPT FULL RESPONSIBILITY", + "firmware_channel_recommended": "This is the recommended channel.", + "firmware_channel_danger": "DO NOT USE THIS UNLESS YOU KNOW WHAT YOU ARE DOING", + "firmware_channel_stable": "Stable", + "firmware_channel_beta": "Beta", + "firmware_channel_develop": "Develop", + "terminal_board_select": "Select a board...", + "terminal_board_search": "Search boards...", + "terminal_board_none": "No board found.", + "terminal_flash_button": "Flash", + "terminal_flash_progress": "Flash Progress: {{status}}", + "terminal_flash_idle": "Idle", + "terminal_flash_no_device": "No device selected.", + "terminal_flash_resetting": "Resetting...", + "terminal_flash_downloading": "Downloading firmware...", + "terminal_flash_download_failed": "Failed to download firmware.", + "terminal_flash_flashing": "Flashing firmware...", + "terminal_flash_rebooting": "Rebooting device... (Reconnect to power manually if stuck)", + "terminal_flash_done": "Rebooted device! Flashing complete.", + "terminal_port_select": "Select Device", + "terminal_port_disconnect": "Disconnect Device", + "terminal_port_connected": "Device connected: {{id}}", + "terminal_console": "Console", + "terminal_connected_device": "Connected device", + "terminal_resize": "Resize terminal panel", + "terminal_reboot": "Reboot", + "terminal_disconnect": "Disconnect", + "terminal_fullscreen_exit_esc": "Exit fullscreen (Esc)", + "terminal_fullscreen_exit": "Exit fullscreen", + "terminal_fullscreen_fill": "Fill the window", + "terminal_command_label": "Serial command", + "terminal_command_placeholder": "Type a command...", + "terminal_command_send": "Send command", + "terminal_colors": "Colors", + "terminal_colors_menu": "Colors...", + "terminal_colors_label": "Console colors", + "terminal_colors_close": "Close colors", + "terminal_color_input": "{{name}} color", + "terminal_colors_reset": "Reset to defaults", + "terminal_color_bg": "Background", + "terminal_color_fg": "Text", + "terminal_color_ts": "Timestamp", + "terminal_color_error": "Error", + "terminal_color_warning": "Warning", + "terminal_color_info": "Info", + "terminal_color_debug": "Debug", + "terminal_color_verbose": "Verbose", + "terminal_options": "Options", + "terminal_options_label": "Console options", + "terminal_hide_system": "Hide system messages", + "terminal_stick_bottom": "Stick to bottom", + "terminal_raw_output": "Raw output", + "terminal_timestamps": "Timestamps", + "terminal_timestamp_uptime": "Uptime", + "terminal_timestamp_local": "Local", + "terminal_timestamp_ms": "Ms", + "terminal_timestamp_off": "Off", + "terminal_copy_settings": "Copy settings", + "terminal_import_settings": "Import settings", + "terminal_copy_selection": "Copy selection", + "terminal_copy_all": "Copy all output", + "terminal_toast_selection_copied": "Selection copied", + "terminal_toast_output_copied": "Console output copied", + "terminal_toast_settings_copied": "Console settings copied", + "terminal_toast_clipboard_unreadable": "Could not read the clipboard", + "terminal_toast_settings_imported": "Console settings imported", + "terminal_toast_settings_invalid": "Clipboard does not contain console settings", + "common_try_again": "Try again", + "terminal_cfg_intro": "Values are sent to the device via UART. Read the device's response in the console below. Commands without an argument act as getters; use the button next to each field to read the current value.", + "terminal_cfg_rf_title": "RF Transmitter", + "terminal_cfg_rf_desc": "Controls the shocker RF output.", + "terminal_cfg_tx_pin": "TX GPIO pin", + "terminal_cfg_example": "e.g. {{value}}", + "terminal_cfg_read_value": "Read current value", + "terminal_cfg_set": "Set", + "terminal_cfg_read": "Read", + "terminal_cfg_reading": "Reading…", + "terminal_cfg_apply": "Apply", + "terminal_cfg_keepalive": "Keepalive enabled", + "terminal_cfg_keepalive_desc": "Periodically pings paired shockers to keep them awake.", + "terminal_cfg_estop_title": "Emergency Stop", + "terminal_cfg_estop_desc": "Hardware button that halts all output.", + "terminal_cfg_estop_enabled": "EStop enabled", + "terminal_cfg_estop_pin": "EStop GPIO pin", + "terminal_cfg_estop_note": "Note: {{latching}} and {{active}} have no dedicated commands; set them via the JSON config below.", + "terminal_cfg_wifi_title": "WiFi", + "terminal_cfg_wifi_desc": "Station credentials and device hostname.", + "terminal_cfg_hostname": "Hostname", + "terminal_cfg_networks": "Networks (JSON array)", + "terminal_cfg_invalid_json_array": "Must be a valid JSON array", + "terminal_cfg_ap_note": "AP settings ({{ssid}}, {{password}}, {{disabled}}, {{staDisabled}}, {{offlineMode}}) have no dedicated commands; use the JSON config.", + "terminal_cfg_backend_title": "Backend", + "terminal_cfg_backend_desc": "OpenShock server and authentication.", + "terminal_cfg_domain": "Domain", + "terminal_cfg_domain_restart": "Setting the domain will restart the device.", + "terminal_cfg_auth_token": "Auth token", + "terminal_cfg_auth_token_placeholder": "Paste device token", + "terminal_cfg_hide": "Hide", + "terminal_cfg_show": "Show", + "terminal_cfg_serial_title": "Serial Input", + "terminal_cfg_echo": "Echo enabled", + "terminal_cfg_echo_desc": "Print typed characters back to the console.", + "terminal_cfg_advanced_title": "Advanced: full config", + "terminal_cfg_advanced_desc": "For fields without dedicated commands (captive portal, OTA, LAN, etc.), replace the entire config.", + "terminal_cfg_json_config": "JSON config", + "terminal_cfg_invalid_json": "Must be valid JSON", + "terminal_cfg_read_json": "Read current config as JSON", + "terminal_cfg_json_restart": "Applying a JSON config will restart the device.", + "terminal_cfg_raw_config": "Raw FlatBuffer config (base64)", + "terminal_cfg_invalid_base64": "Must be a valid base64 string", + "terminal_cfg_read_raw": "Read current config as base64", + "terminal_cfg_factory_reset": "Factory reset", + "terminal_cfg_factory_reset_desc": "Wipes the entire device configuration.", + "terminal_cfg_factory_reset_title": "Factory reset device?", + "terminal_cfg_factory_reset_action": "Wipe config", + "terminal_cfg_factory_reset_confirm": "This will erase all configuration on the device; WiFi networks, backend credentials, pins, and all other settings. The device will be reset to defaults.", + "terminal_cfg_read_failed_json_title": "Couldn't read the JSON config", + "terminal_cfg_read_failed_raw_title": "Couldn't read the raw config", + "terminal_cfg_read_failed_desc": "The device didn't respond after {{attempts}} attempts.", + "terminal_cfg_common_causes": "Common causes:", + "terminal_cfg_cause_busy": "The device is busy handling another command.", + "terminal_cfg_cause_disconnected": "The device disconnected or rebooted.", + "terminal_cfg_cause_unsupported": "The firmware version doesn't support this command.", + "common_status": "Status", + "common_version": "Version", + "common_created": "Created", + "common_create": "Create", + "common_done": "Done", + "common_enable": "Enable", + "common_disable": "Disable", + "common_are_you_sure": "Are you sure?", + "common_generating": "Generating...", + "hubs_title": "Hubs", + "hubs_subtitle": "Every hub registered to your account.", + "hubs_add": "Add Hub", + "hubs_load_failed": "Failed to load hubs.", + "hubs_empty_title": "No hubs yet", + "hubs_empty_desc": "A hub is the device that relays commands to your shockers. Add one to get started.", + "hubs_create_title": "Create hub", + "hubs_name_label": "Hub Name", + "hubs_name_placeholder": "My Hub", + "hub_toast_not_connected": "Not connected to the server", + "hub_toast_try_later": "Try again in a moment.", + "hub_reboot_title": "Reboot {{name}}?", + "hub_reboot_desc": "The hub will disconnect and restart. Any shockers paired to it stop responding until it comes back online.", + "hub_reboot": "Reboot", + "hub_hotspot_enable_title": "Enable Wi-Fi hotspot on {{name}}?", + "hub_hotspot_disable_title": "Disable Wi-Fi hotspot on {{name}}?", + "hub_hotspot_enable_desc": "The hub broadcasts its own setup network. It stays reachable on your Wi-Fi, but the hotspot is open to anyone in range until you turn it off.", + "hub_hotspot_disable_desc": "The setup hotspot shuts down. If the hub is not already on your Wi-Fi you will need physical access to set it up again.", + "hub_delete_desc": "You are about to delete hub {{name}}.", + "hub_delete_shockers": "This will also delete the following shockers:", + "hub_edit_title": "Edit hub", + "hub_edit_apply": "Apply", + "hub_pair_title_generate": "Generate pair code?", + "hub_pair_title_generated": "Pair code generated", + "hub_pair_title_paired": "Hub paired", + "hub_pair_consumed": "{{name}} consumed this pair code and is now paired.", + "hub_pair_used": "The code has been used and is no longer valid.", + "hub_pair_generated_for": "Pair code generated for {{name}}.", + "hub_copy_now": "The code below will not be accessible later, please copy it now and update clients with it.", + "hub_pair_generate_for": "You are about to generate a pair code for {{name}}.", + "hub_pair_valid_for": "It will be valid for 15 minutes after its creation.", + "hub_pair_one_active": "There is only one active pair code per hub, newly generated ones will override the older active ones.", + "hub_pair_complete": "Pairing complete", + "hub_pair_code_label": "Pair code:", + "hub_pair_copied_close": "Code has been copied, close", + "hub_pair_get": "Get Pair Code", + "hub_token_generated": "Token generated", + "hub_token_generated_for": "New token generated for {{name}}.", + "hub_token_regenerate_for": "You are about to regenerate the token for {{name}}.", + "hub_token_invalidate": "This action will invalidate the current token and disconnect clients using it.", + "hub_token_confirm": "Are you sure you want to do this?", + "hub_token_label": "New token:", + "hub_token_copied_close": "Token has been copied, close", + "hub_token_regenerate": "Regenerate Token", + "hub_menu_update": "Update", + "hub_menu_label": "Hub", + "hub_menu_hotspot_enable": "Enable Wi-Fi hotspot", + "hub_menu_hotspot_disable": "Disable Wi-Fi hotspot", + "hub_menu_pair": "Pair", + "hub_menu_estop": "Emergency Stop", + "hub_update_breadcrumb": "Update", + "hub_update_unknown_hub": "Unknown Hub", + "hub_update_unknown_task": "Unknown Task", + "hub_update_task_metadata": "Fetching Metadata", + "hub_update_task_preparing": "Preparing for Update", + "hub_update_task_flash_fs": "Flashing Filesystem", + "hub_update_task_verify_fs": "Verifying Filesystem", + "hub_update_task_flash_app": "Flashing Application", + "hub_update_task_bootable": "Marking Application Bootable", + "hub_update_task_rebooting": "Rebooting", + "hub_update_status_started": "Started", + "hub_update_status_running": "Running", + "hub_update_status_finished": "Finished", + "hub_update_status_error": "Error", + "hub_update_status_timeout": "Timeout", + "hub_update_confirm_title": "Confirm firmware update", + "hub_update_confirm_desc": "Update {{name}} to version {{version}}?", + "hub_update_unstable_warning": "This version may not be from the stable channel and could contain bugs.", + "hub_update_title": "Update {{name}}", + "hub_update_subtitle": "Manage firmware updates for this hub.", + "hub_update_status_title": "Hub Status", + "hub_update_firmware": "Firmware: {{version}}", + "hub_update_confirm": "Update", + "hub_update_success": "Update completed successfully", + "hub_update_rolled_back": "Device rolled back to previous version", + "hub_update_back": "Back to Hubs", + "hub_update_flash_again": "Flash Again", + "hub_update_card_title": "Firmware Update", + "hub_update_card_desc": "Select a firmware channel and version to install.", + "hub_update_to": "Update to {{version}}", + "hub_update_must_be_online": "Hub must be online to start an update.", + "hub_update_updating_to": "Updating to {{version}}...", + "hub_update_total": "Total", + "hub_update_task": "Task", + "hub_update_history": "Update History", + "hub_update_no_history": "No update history found for this hub.", + "hub_update_col_id": "ID", + "hub_update_col_started": "Started", + "hub_update_col_message": "Message", + "hub_update_loading": "Loading hub information...", + "hub_update_not_found": "Hub not found.", + "home_breadcrumb": "Home", + "home_welcome": "Welcome back", + "home_welcome_name": "Welcome back, {{name}}", + "home_subtitle": "Here's an overview of your OpenShock setup.", + "home_hubs_online": "{{count}} online", + "home_hub_status": "Hub Status", + "home_no_hubs": "No hubs", + "home_all_online": "All online", + "home_all_offline": "All offline", + "home_some_online": "{{online}}/{{total}} online", + "home_quick_links": "Quick Links", + "home_my_shockers": "My Shockers", + "home_my_shockers_desc": "Control your shockers", + "home_hubs_desc": "Manage your hubs", + "home_shared_desc": "Shockers shared with you", + "home_public_desc": "Manage share links", + "home_get_started": "Get Started", + "home_get_started_desc": "You don't have any hubs yet. Create a hub to connect your first device, then add shockers to it.", + "home_set_up_hub": "Set Up a Hub", + "home_first_shocker": "Add Your First Shocker", + "home_first_shocker_desc_one": "You have {{count}} hub set up. Add a shocker to start controlling it.", + "home_first_shocker_desc_other": "You have {{count}} hubs set up. Add a shocker to start controlling it.", + "home_go_to_shockers": "Go to Shockers", + "profile_title": "Profile", + "profile_coming_soon": "Profile is coming soon", + "profile_coming_soon_desc": "Your public profile is not available yet. Account details live under Settings.", + "common_retry": "Retry", + "common_never_used": "Never used", + "common_expires": "Expires {{time}}", + "common_search_placeholder": "Search...", + "common_unknown": "Unknown", + "settings_breadcrumb_account": "Account", + "account_subtitle": "Your sign-in details and account actions.", + "account_change_username": "Change Username", + "account_change_email": "Change Email", + "account_change_password": "Change Password", + "account_username_label": "Username", + "account_email_label": "Email", + "account_password_label": "Password", + "account_new_password_label": "New Password", + "account_confirm_password_label": "Confirm New Password", + "account_oauth_only": "Not available for OAuth-only accounts", + "account_oauth_no_password": "This account signs in via OAuth and has no password.", + "account_diagnostics": "Diagnostics", + "account_diagnostics_desc": "Help us fix crashes and slow API calls. Reports include the error message, stack trace and your IP. Off by default.", + "account_diagnostics_level": "Diagnostics level", + "account_telemetry_off": "Off", + "account_telemetry_off_desc": "Send nothing.", + "account_telemetry_errors": "Errors", + "account_telemetry_errors_desc": "Send browser error reports only.", + "account_telemetry_full": "Full", + "account_telemetry_full_desc": "Error reports plus traces of API calls (no page navigations).", + "account_toast_deactivated": "Account deactivated successfully", + "account_deactivate_title": "Deactivate account", + "account_deactivate_desc": "Are you sure you want to deactivate your account?", + "account_deactivate": "Deactivate Account", + "account_email_title": "Change email", + "account_email_desc": "Enter your new email address and confirm with your current password.", + "account_email_toast_sent": "Verification email sent to {{email}}. Click the link in that email to apply the change.", + "account_new_email": "New Email", + "account_current_password": "Current Password", + "account_password_title": "Change password", + "account_password_desc": "Enter your current password and choose a new one.", + "account_password_toast": "Password has been changed", + "account_username_title": "Change username", + "account_username_desc": "Enter a new username.", + "account_new_username": "New Username", + "account_username_toast": "Username changed successfully", + "tokens_subtitle": "API Tokens are used to authenticate with the OpenShock API.", + "tokens_generate": "Generate Token", + "tokens_toast_refreshed": "Tokens refreshed successfully", + "tokens_empty_title": "No API tokens", + "tokens_empty_desc": "Generate a token to authenticate with the OpenShock API.", + "tokens_created_on": "Created {{date}}", + "tokens_last_used": "Last used {{time}}", + "tokens_never_expires": "Never expires", + "tokens_load_failed": "Failed to load API tokens.", + "token_toast_edited": "Token edited successfully", + "token_name_required": "Name is required", + "token_name_too_long": "Name is too long", + "token_edit_title": "Edit API token", + "token_name_label": "Token Name", + "token_name_placeholder": "Token name...", + "token_permissions": "Permissions", + "token_perm_category_shockers": "Shockers", + "token_perm_category_devices": "Hubs", + "token_perm_category_usershares": "User Shares", + "token_perm_category_publicshares": "Public Shares", + "token_perm_use": "Use", + "token_perm_edit": "Edit", + "token_perm_pause": "Pause", + "token_perm_auth": "Authenticate", + "token_shocker_control": "Shocker Control", + "token_toast_paused": "Token paused", + "token_toast_resumed": "Token resumed", + "token_delete_title": "Delete API token", + "token_delete_desc": "Are you sure you want to delete {{name}}?", + "token_delete_permanent": "This action cannot be undone. This will permanently delete the token.", + "token_toast_deleted": "Token deleted successfully", + "token_resume": "Resume token", + "token_pause": "Pause token", + "token_mode_clamp_desc": "Clamp: requests outside the allowed range are capped to the nearest limit (the min or the max).", + "token_mode_lerp_desc": "Lerp: the full input range is linearly rescaled so it fits within your allowed min–max range.", + "token_paused_desc": "A paused token may not send shocker control messages.", + "token_intensity_range": "Intensity range", + "token_duration_range": "Duration range", + "token_new_breadcrumb": "New", + "token_redirect_not_allowed": "The provided redirect_uri is not allowed. Only loopback addresses or custom application schemes are permitted.", + "token_params_missing": "Required get parameters are missing. Make sure name, redirect_uri, and permissions are provided.", + "token_invalid_permissions": "Invalid permissions provided: {{list}}", + "token_toast_created": "Token created successfully", + "token_request_title": "API Token Request", + "token_access_granted": "Access granted", + "token_shared_redirecting": "The token has been created and shared with the application. Redirecting you back to {{uri}}.", + "token_not_redirected": "If you are not redirected automatically, use the button below.", + "token_finish": "Finish", + "token_generated_title": "API Token Generated", + "token_copy_now": "Please copy your API Token now, you will not be able to view it again later!", + "token_new_title": "New API Token", + "token_external_desc": "An external application is requesting access to your account. Review and adjust the permissions below before allowing access.", + "token_new_desc": "Configure and generate a new API token for your account.", + "token_external_requesting": "{{name}} is requesting an API Token. Your token will be shared with the application at {{uri}}.", + "token_allow": "Allow", + "token_generate": "Generate", + "token_deny": "Deny", + "sessions_subtitle": "Every active session on your account. Revoke any you do not recognize.", + "sessions_unknown_device": "Unknown device", + "sessions_toast_refreshed": "Sessions refreshed successfully", + "sessions_load_failed": "Failed to load sessions.", + "sessions_empty_title": "No active sessions", + "sessions_empty_desc": "Sessions appear here once you sign in from a browser or app.", + "sessions_last_seen": "Last seen {{time}}", + "sessions_signed_in": "Signed in {{time}}", + "session_toast_revoked": "Session revoked successfully", + "session_revoke_title": "Revoke session", + "session_revoke": "Revoke", + "session_revoke_desc": "Are you sure you want to revoke this session?", + "session_revoke_from": "Session logged in from {{ip}} using {{agent}}", + "connections_title": "OAuth Connections", + "connections_subtitle": "Link or unlink third-party accounts to sign in faster and keep your profile in sync.", + "connections_toast_linked": "Account linked.", + "connections_toast_cancelled": "Link flow cancelled.", + "connections_toast_failed": "Linking failed.", + "connections_toast_removed": "Connection removed", + "connections_refreshing": "Refreshing…", + "connections_link_new": "Link new provider", + "connections_empty_title": "No connections yet", + "connections_empty_desc": "Choose “Link new provider” above to connect available providers.", + "connections_unlink": "Unlink", + "connections_load_failed": "Failed to load OAuth connections.", + "connections_unlink_title": "Unlink {{name}}?", + "connections_unlink_title_generic": "Unlink this account?", + "connections_unlink_desc": "You'll no longer be able to sign in with this provider unless you link it again.", + "provider_starting": "Starting {{name}}...", + "provider_link": "Link {{name}}", + "audit_subtitle": "Security-relevant activity on your account. Review anything you do not recognize.", + "audit_col_time": "Time", + "audit_col_action": "Action", + "audit_col_details": "Details", + "audit_col_reason": "Reason", + "audit_col_ip": "IP address", + "audit_col_device": "Device", + "audit_action_login": "Signed in", + "audit_action_logout": "Signed out", + "audit_action_password_changed": "Password changed", + "audit_action_email_change_requested": "Email change requested", + "audit_action_email_changed": "Email changed", + "audit_action_username_changed": "Username changed", + "audit_action_api_token_created": "API token created", + "audit_action_api_token_deleted": "API token deleted", + "audit_action_oauth_connected": "Connection added", + "audit_action_oauth_disconnected": "Connection removed", + "audit_action_account_deactivated": "Account deactivated", + "audit_action_account_reactivated": "Account reactivated", + "audit_action_account_deleted": "Account deleted", + "audit_action_automation_token_created": "Automation token created", + "audit_action_automation_token_updated": "Automation token updated", + "audit_action_automation_token_rotated": "Automation token rotated", + "audit_action_automation_token_deleted": "Automation token deleted", + "audit_action_automation_token_used": "Automation token used", + "audit_meta_session": "Session {{id}}", + "audit_meta_changed": "{{old}} to {{new}}", + "audit_meta_email_requested": "Requested change to {{email}}", + "audit_meta_accounts_removed_one": "{{name}} ({{count}} account removed)", + "audit_meta_accounts_removed_other": "{{name}} ({{count}} accounts removed)", + "audit_meta_scheduled_deletion": "Scheduled for deletion", + "audit_meta_kept": "Kept for reactivation", + "common_view": "View", + "common_save": "Save", + "common_saving": "Saving...", + "common_back": "Back", + "common_shared_by": "Shared by", + "common_user_avatar": "User Avatar", + "common_toast_saved": "Changes saved successfully", + "pause_reason_shocker": "Paused at shocker level", + "pause_reason_shocker_user_share": "Paused at shocker and user share level", + "pause_reason_shocker_public_share": "Paused at shocker and public share level", + "pause_reason_user_share": "Paused at user share level", + "pause_reason_public_share": "Paused at public share level", + "public_shares_subtitle": "A link anyone can use, no account required.", + "public_shares_new": "New Share", + "public_share_never_expires": "Never expires", + "public_shares_empty_title": "No public shares yet", + "public_shares_empty_desc": "Create a link that anyone can use to control your shockers.", + "public_share_expired": "Expired", + "public_share_no_expiry": "No expiry", + "public_share_label": "Public Share", + "public_share_toast_created": "Created new public share", + "public_share_create_title": "Create public share", + "public_share_toast_deleted": "Deleted public share", + "public_share_delete_title": "Delete public share", + "public_share_delete_desc": "Are you sure you want to delete public share {{name}}?", + "public_share_edit_title": "Public Share: {{name}}", + "public_share_edit_subtitle": "Editing: changes apply when you save.", + "public_share_add_shocker": "Add Shocker", + "public_share_toast_added_one": "Added {{count}} shocker to share", + "public_share_toast_added_other": "Added {{count}} shockers to share", + "public_share_empty_shockers_title": "No shockers in this share", + "public_share_empty_shockers_desc": "Add a shocker and anyone with the link will be able to control it.", + "public_share_load_failed": "Error fetching public share details", + "public_share_paused_here": "Paused for this share", + "public_share_resume_shocker": "Resume shocker", + "public_share_pause_shocker": "Pause shocker", + "public_share_remove": "Remove from share", + "public_share_toast_removed": "Shocker removed from share", + "public_share_add_title": "Add shockers", + "public_share_add_desc": "Add shockers to this public share. You can set their limits once they are added.", + "public_share_add_placeholder": "Select shockers to share...", + "public_share_add_no_match": "No matching shockers", + "public_share_add_submit": "Add Shockers", + "public_share_view_loading": "Loading share details...", + "public_share_view_title": "Public Share Link", + "public_share_view_desc": "Enter as a guest or login with your OpenShock account", + "public_share_view_guest_name": "Guest Name", + "public_share_view_enter": "Enter", + "public_share_view_enter_guest": "Enter as Guest", + "public_share_login": "Login", + "perm_shock_on": "Shock enabled", + "perm_shock_off": "Shock disabled", + "perm_vibrate_on": "Vibrate enabled", + "perm_vibrate_off": "Vibrate disabled", + "perm_sound_on": "Sound enabled", + "perm_sound_off": "Sound disabled", + "perm_live_on": "Live enabled", + "perm_live_off": "Live disabled", + "perm_live_control": "Live Control", + "user_selector_avatar_of": "{{name}}'s avatar", + "user_selector_placeholder": "Enter user name", + "user_selector_aria": "Username to search", + "user_selector_search": "Search user", + "user_selector_found": "User found", + "common_remove": "Remove", + "user_shares_subtitle": "Direct permanent shares with other users.", + "user_shares_toast_invited": "Sent a shocker invite to {{name}}", + "user_shares_redeem": "Redeem Code", + "user_shares_new": "New Share", + "user_shares_tab_shares": "Shares", + "user_shares_tab_incoming": "Shared with Me", + "user_shares_tab_invites": "Invites", + "share_code_create_title": "New share code", + "share_code_create_desc": "Create a Share Code or Invite", + "share_code_shocker_placeholder": "Select shockers to share...", + "share_code_no_match": "No matching shockers", + "share_code_send_invite": "Send Share Invite", + "share_code_create": "Create Share Code", + "share_code_created_title": "Share code generated", + "share_code_created_desc": "Please copy share code or code link!", + "share_code_redeem_title": "Redeem share code", + "share_code_redeem_desc": "Enter the share code to redeem", + "share_code_redeem_placeholder": "Enter share code", + "share_code_redeemed": "Redeemed successfully!", + "share_code_shared_shockers": "Shared shockers", + "share_code_redeeming": "Redeeming...", + "share_code_redeem": "Redeem", + "incoming_shares_empty_title": "Nothing shared with you", + "incoming_shares_empty_desc": "No one has shared a shocker with you yet.", + "incoming_share_toast_removed": "Removed share for {{name}}", + "incoming_share_remove_title": "Remove Share", + "incoming_share_remove_desc": "Are you sure you want to remove the share for {{name}}?", + "incoming_share_toast_removed_shocker": "Removed {{shocker}} shared by {{name}}", + "incoming_share_remove_shocker_title": "Remove this shared shocker?", + "incoming_share_remove_shocker_desc": "Are you sure you want to remove the shocker share {{shocker}} by {{name}}?", + "incoming_share_manage_from": "Manage shares from", + "share_remove": "Remove share", + "invites_empty_title": "No invites yet", + "invites_empty_desc": "You have no incoming or outgoing share invites.", + "invites_outgoing": "Outgoing", + "invites_outgoing_empty_title": "No outgoing invites", + "invites_outgoing_empty_desc": "You have no outgoing share invites.", + "invites_incoming": "Incoming", + "invites_incoming_empty_title": "No incoming invites", + "invites_incoming_empty_desc": "You have no incoming share invites.", + "invite_toast_accepted": "Accepted share invite from {{name}}", + "invite_toast_declined": "Declined share invite from {{name}}", + "invite_deny_title": "Deny Invite", + "invite_deny_label": "Deny Invite", + "invite_deny": "Deny", + "invite_deny_desc": "Are you sure you want to deny the invite from {{name}}?", + "invite_accept": "Accept Invite", + "invite_toast_cancelled_for": "Cancelled invite for {{name}} ({{id}})", + "invite_toast_cancelled": "Cancelled invite {{id}}", + "invite_cancel_title": "Cancel Invite", + "invite_cancel": "Cancel", + "invite_cancel_for_desc": "Are you sure you want to cancel the invite for {{name}}?", + "invite_cancel_code_desc": "Are you sure you want to cancel the invite with code {{code}}?", + "invite_cancel_outstanding": "Cancel Outstanding Invite", + "outgoing_shares_empty_title": "No shared shockers", + "outgoing_shares_empty_desc": "You haven't shared any shockers with other users yet.", + "outgoing_share_toast_removed": "Removed shocker share {{name}}", + "outgoing_share_remove_title": "Stop sharing this shocker?", + "outgoing_share_editing_for": "Editing shares for", + "outgoing_share_limits": "Limits & Permissions", + "outgoing_share_same": "Same restrictions on every shocker", + "outgoing_share_per_desc": "Tune restrictions per shocker", + "outgoing_share_all": "All", + "outgoing_share_per": "Per shocker", + "outgoing_share_remove_desc": "Are you sure you want to stop sharing {{shocker}} with {{name}}?", + "report_breadcrumb": "Report API Tokens", + "report_toast_clipboard_failed": "Failed to read clipboard: {{error}}", + "report_title": "Report Leaked API Tokens", + "report_paste": "Paste from clipboard", + "report_warning": "This form is only for reporting accidentally leaked API tokens.", + "report_abuse_warning": "Intentional abuse will result in bans or severe endpoint restrictions.", + "report_detected": "Detected Tokens", + "report_invalid": "One or more tokens appear to be invalid. Please check for formatting issues.", + "report_acknowledge": "I confirm I understand what this feature is for and accept responsibility.", + "report_submit": "Submit Report", + "turnstile_disabled": "Turnstile disabled", + "common_internal_error": "Internal error", + "resend_toast_sent": "Activation email sent. Check your inbox and spam folder.", + "resend_toast_throttled": "Too many activation emails have been requested. Please try again later.", + "resend_toast_unavailable": "No activation email can be resent from this browser. If your account isn't activated yet, logging in sends a new link.", + "resend_button": "Didn't get the email? Resend", + "expiration_label": "Expiration", + "expiration_never": "Never", + "expiration_custom": "Custom", + "expiration_days_one": "{{count}} Day", + "expiration_days_other": "{{count}} Days", + "expiration_required": "Expire date is required", + "expiration_never_desc": "This will never expire", + "expiration_expires_at": "Expires {{time}} ({{date}})", + "date_picker_placeholder": "Pick a date", + "telemetry_toast_title": "Help improve OpenShock?", + "telemetry_toast_desc": "Send diagnostics to help us fix crashes and slow API calls. Reports include the error message, stack trace and your IP. You can change this any time in Account settings.", + "telemetry_toast_no": "No thanks", + "telemetry_toast_errors": "Errors only", + "telemetry_toast_full": "Full", + "table_show_details": "Show details", + "table_hide_details": "Hide details", + "table_no_results": "No results.", + "table_sort_asc": "Sort by {{name}}, ascending", + "table_sort_desc": "Sort by {{name}}, descending", + "table_sort_none": "Sort by {{name}}, unsorted", + "cell_na": "N/A", + "cell_not_applicable": "Not applicable", + "cell_invalid": "Invalid", + "cell_unavailable": "Unavailable", + "cell_none": "None", + "oauth_login_with": "Login with {{provider}}", + "oauth_signup_with": "Signup with {{provider}}", + "signalr_connect_failed": "Failed to connect to server!", + "signalr_disconnect_failed": "Encountered error while disconnecting from server!", + "signalr_invalid_update": "Received invalid update from server!", + "signalr_invalid_log": "Received invalid log data from server!", + "signalr_invalid_ota": "Received invalid firmware update data from server!", + "ota_toast_failed": "Hub firmware update failed: {{message}}", + "ota_toast_succeeded": "Hub firmware update completed successfully!", + "ota_toast_rolled_back": "Hub firmware rolled back to previous version", + "lcg_connect_failed": "Failed to connect to live control gateway", + "terminal_toast_bootloader_failed": "Failed to enter bootloader: {{error}}", + "terminal_toast_app_mode_failed": "Failed to enter application mode: {{error}}", + "problem_account_account_not_activated_title": "Account not activated", + "problem_account_account_not_activated_desc": "Check your inbox for the activation email.", + "problem_account_activation_not_found_title": "Activation link is invalid", + "problem_account_activation_not_found_desc": "The link may have expired or already been used.", + "problem_account_activation_resend_too_many_title": "Too many activation emails requested", + "problem_account_activation_resend_too_many_desc": "Please wait a while before trying again.", + "problem_account_activation_resend_unavailable_title": "Cannot resend activation email", + "problem_account_activation_resend_unavailable_desc": "Log in again to request a new activation link.", + "problem_account_deactivate_already_deactivated_title": "Account is already deactivated", + "problem_account_deactivate_denied_privileged_title": "Privileged accounts cannot be deactivated", + "problem_account_deactivate_unauthorized_title": "You are not allowed to do this", + "problem_account_deactivated_title": "This account has been deactivated", + "problem_account_email_already_in_use_title": "That email address is already in use", + "problem_account_email_invalid_title": "That email address is not valid", + "problem_account_email_taken_title": "That email address is already in use", + "problem_account_email_too_many_requests_title": "Too many email change requests", + "problem_account_email_too_many_requests_desc": "Please wait a while before trying again.", + "problem_account_email_unchanged_title": "That is already your email address", + "problem_account_email_verify_not_found_title": "Verification link is invalid", + "problem_account_email_verify_not_found_desc": "The link may have expired or already been used.", + "problem_account_o_auth_only_title": "This account has no password", + "problem_account_o_auth_only_desc": "Sign in with the provider you signed up with.", + "problem_account_password_not_set_title": "No password set", + "problem_account_password_not_set_desc": "This account signs in through an external provider.", + "problem_account_password_old_password_invalid_title": "Current password is incorrect", + "problem_account_username_invalid_title": "That username is not allowed", + "problem_account_username_recently_changed_title": "Username changed too recently", + "problem_account_username_recently_changed_desc": "You can change your username once every 7 days.", + "problem_account_username_taken_title": "That username is already taken", + "problem_admin_user_deactivated_title": "This user is deactivated", + "problem_admin_user_not_activated_title": "This user has not been activated yet", + "problem_api_token_can_only_delete_self_title": "An API token can only delete itself", + "problem_api_token_not_found_title": "API token not found", + "problem_api_token_paused_title": "This API token is paused", + "problem_assign_lcg_bad_schema_version_title": "Unsupported hub protocol version", + "problem_assign_lcg_bad_schema_version_desc": "Update the hub firmware to connect.", + "problem_assign_lcg_no_lcg_available_title": "No gateway available", + "problem_assign_lcg_no_lcg_available_desc": "No live control gateway is available right now. Please try again later.", + "problem_authentication_account_deactivated_title": "This account has been deactivated", + "problem_authentication_account_not_activated_title": "This account has not been activated", + "problem_authentication_cookie_missing_or_invalid_title": "You are not logged in", + "problem_authentication_cookie_missing_or_invalid_desc": "Your session may have expired. Please log in again.", + "problem_authentication_header_missing_or_invalid_title": "Invalid API token", + "problem_authentication_session_invalid_title": "Session expired", + "problem_authentication_session_invalid_desc": "Please log in again.", + "problem_authentication_token_invalid_title": "Invalid API token", + "problem_authentication_unknown_error_title": "Authentication failed", + "problem_authorization_policy_not_met_title": "You do not have permission to do this", + "problem_authorization_token_only_title": "This action requires an API token", + "problem_authorization_token_permission_missing_title": "This API token is missing a required permission", + "problem_authorization_unknown_error_title": "Authorization failed", + "problem_authorization_user_session_only_title": "This action requires a logged-in session", + "problem_automation_token_not_allowed_for_account_title": "Automation tokens cannot be used with privileged accounts", + "problem_configuration_already_exists_title": "A configuration entry with that name already exists", + "problem_configuration_invalid_name_format_title": "Invalid configuration name", + "problem_configuration_invalid_name_format_desc": "Only A to Z and underscores are allowed.", + "problem_configuration_invalid_value_format_title": "Value does not match the configuration type", + "problem_configuration_not_found_title": "Configuration entry not found", + "problem_control_stats_invalid_range_title": "The from date must not be after the to date", + "problem_control_stats_invalid_time_zone_title": "Unknown time zone", + "problem_control_stats_missing_capability_title": "Control statistics are not available on this server", + "problem_device_not_found_title": "Hub not found", + "problem_device_not_online_title": "Hub is offline", + "problem_device_too_many_hubs_title": "You have reached the maximum number of hubs", + "problem_device_too_many_shockers_title": "This hub has reached its maximum number of shockers", + "problem_endpoint_retired_title": "This feature is no longer available", + "problem_expression_error_title": "Invalid filter expression", + "problem_internal_server_error_title": "Something went wrong on our end", + "problem_login_invalid_credentials_title": "Invalid username or password", + "problem_login_invalid_domain_title": "Logging in from this address is not allowed", + "problem_o_auth_connection_already_exists_title": "Your account is already connected to this provider", + "problem_o_auth_connection_already_linked_title": "This external account is already linked to another user", + "problem_o_auth_flow_anonymous_only_title": "You are already signed in", + "problem_o_auth_flow_mismatch_title": "Sign-in attempt does not match", + "problem_o_auth_flow_mismatch_desc": "Please start over.", + "problem_o_auth_flow_missing_data_title": "The provider did not return your account details", + "problem_o_auth_flow_missing_data_desc": "Please try again.", + "problem_o_auth_flow_not_found_title": "Sign-in attempt expired", + "problem_o_auth_flow_not_found_desc": "Please start over.", + "problem_o_auth_flow_unsupported_title": "Unsupported sign-in flow", + "problem_o_auth_internal_error_title": "Something went wrong during sign-in", + "problem_o_auth_internal_error_desc": "Please try again in a moment.", + "problem_o_auth_link_authenticated_user_only_title": "You must be signed in to link an external account", + "problem_o_auth_provider_mismatch_title": "Sign-in attempt does not match the provider", + "problem_o_auth_provider_mismatch_desc": "Please start over.", + "problem_o_auth_provider_unsupported_title": "This sign-in provider is not supported", + "problem_pair_code_not_found_title": "Pair code not found", + "problem_password_reset_not_found_title": "Password reset link is invalid", + "problem_password_reset_not_found_desc": "The link may have expired or already been used.", + "problem_session_not_found_title": "Session not found", + "problem_share_get_no_shares_title": "You have no shares with this user", + "problem_share_request_create_cannot_share_with_self_title": "You cannot share with yourself", + "problem_share_request_create_shocker_not_found_title": "One or more shockers were not found", + "problem_share_request_create_shocker_not_found_desc": "They may have been removed or do not belong to you.", + "problem_share_request_not_found_title": "Share invite not found", + "problem_share_user_not_found_title": "Share not found", + "problem_share_code_already_linked_title": "Shocker is already linked to your account", + "problem_share_code_cant_link_own_share_code_title": "You cannot redeem your own share code", + "problem_share_code_not_found_title": "Share code not found", + "problem_share_link_expiry_date_in_past_title": "Expiry date cannot be in the past", + "problem_share_link_not_found_title": "Public share not found", + "problem_share_link_shocker_already_in_share_link_title": "Shocker is already in this public share", + "problem_share_link_shocker_not_in_share_link_title": "Shocker is not in this public share", + "problem_shocker_control_no_permission_title": "You do not have permission to control this shocker", + "problem_shocker_control_not_found_title": "Shocker not found", + "problem_shocker_control_paused_title": "Shocker is paused", + "problem_shocker_not_found_title": "Shocker not found", + "problem_signup_registration_disabled_title": "Registration is currently disabled", + "problem_signup_username_or_email_exists_title": "That username or email is already in use", + "problem_turnstile_invalid_title": "Verification failed", + "problem_turnstile_invalid_desc": "Please complete the challenge again and retry.", + "problem_user_not_found_title": "User not found", + "problem_user_privileged_delete_denied_title": "Privileged users cannot be deleted", + "problem_validation_error_title": "Some fields are invalid", + "problem_webhook_not_found_title": "Webhook not found", + "problem_webhook_unsupported_title": "Only Discord webhooks are supported", + "problem_webhook_unsupported_desc": "Use a discord.com URL, not canary or ptb.", + "error_too_many_requests": "Too many requests", + "error_retry_after_one": "Try again in {{count}} second.", + "error_retry_after_other": "Try again in {{count}} seconds.", + "error_unexpected_response": "Unexpected server response", + "error_internal": "Internal error occurred", + "error_network": "Network error occurred", + "dev_banner": "This is the OpenShock DEVELOPMENT environment. No data is saved, and it is regularly overwritten by production data.", + "firmware_channel_bugs_warning": "This channel might contain bugs." +} From 17db2fc18dabe12e3eb8e674edf40cb90053ae1e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Luc=20=E2=99=A5?= Date: Thu, 12 Nov 2026 17:43:11 +0100 Subject: [PATCH 09/27] New translations en.json (German) [ci skip] --- messages/de.json | 302 ++++++++++++++++++----------------------------- 1 file changed, 117 insertions(+), 185 deletions(-) diff --git a/messages/de.json b/messages/de.json index a1f82b70..a1e8e8c3 100644 --- a/messages/de.json +++ b/messages/de.json @@ -1,15 +1,13 @@ { - "$schema": "https://inlang.com/schema/inlang-message-format", - "landing_tagline": "Die Plattform für sicheres, zuverlässiges und wirklich latenzarmes Fernsteuern von Shockern.", "landing_section_label": "Startseite", "landing_hubs_online": "Hubs jetzt online: ", "landing_learn_more": "Mehr erfahren", "landing_wiki": "Wiki", "landing_meta_description": "Willkommen bei OpenShock, einem freien Open-Source-Ökosystem, um verschiedene Shocker über das Internet zu steuern.", - "instance_meta_description": "Willkommen bei {siteName}, einer unabhängigen Instanz von OpenShock, einem freien Open-Source-Ökosystem, um verschiedene Shocker über das Internet zu steuern.", + "instance_meta_description": "Willkommen bei {{siteName}}, einer unabhängigen Instanz von OpenShock, einem freien Open-Source-Ökosystem, um verschiedene Shocker über das Internet zu steuern.", "header_sidebar_toggle": "Seitenleiste umschalten", - "header_avatar_alt": "Avatar von {name}", + "header_avatar_alt": "Avatar von {{name}}", "header_menu_profile": "Profil", "header_menu_settings": "Einstellungen", "header_menu_logout": "Abmelden", @@ -17,16 +15,14 @@ "header_signup": "Registrieren", "header_github_title": "OpenShock auf GitHub", "header_discord_title": "Community-Discord", - - "footer_made_with": "Mit {#heart/} gemacht vom {#team}OpenShock-Team{/team}", + "footer_made_with": "Mit gemacht vom OpenShock-Team", "footer_connection_status_label": "Verbindungsstatus zum Server", "footer_signalr_state": "SignalR-Status", "footer_frontend_version": "Frontend-Version", - "footer_frontend_commit_title": "Commit {commit}", + "footer_frontend_commit_title": "Commit {{commit}}", "footer_backend_version": "Backend-Version", - "footer_backend_commit_title": "Commit {commit}", + "footer_backend_commit_title": "Commit {{commit}}", "footer_language_label": "Sprache", - "sidebar_home_link_label": "OpenShock-Startseite", "sidebar_group_general": "Allgemein", "sidebar_home": "Startseite", @@ -53,7 +49,6 @@ "sidebar_settings_audit_log": "Aktivitätsprotokoll", "sidebar_settings_connections": "Verbindungen", "sidebar_settings_account": "Kontoeinstellungen", - "error_meta_title": "Dienst nicht verfügbar", "error_meta_description": "OpenShock ist derzeit nicht verfügbar", "error_meta_logo_alt": "OpenShock-Logo", @@ -62,10 +57,8 @@ "error_not_found_description": "Die gesuchte Seite existiert nicht.", "error_unexpected_description": "Ein unerwarteter Fehler ist aufgetreten.", "error_go_back": "Zurück", - "auth_layout_logo_alt": "OpenShock-Logo", "auth_layout_invalid_redirect_removed": "Eine ungültige Weiterleitungs-URL wurde zu deiner Sicherheit entfernt.", - "auth_activate_breadcrumb": "Konto aktivieren", "auth_activate_title": "Konto aktivieren", "auth_activate_activating": "Dein Konto wird aktiviert...", @@ -74,17 +67,15 @@ "auth_activate_missing_token": "Aktivierungstoken fehlt", "auth_activate_continue": "Weiter zur Anmeldung", "auth_activate_toast_success": "Konto aktiviert", - "auth_forgot_breadcrumb": "Passwort vergessen", "auth_forgot_title": "Passwort vergessen", "auth_forgot_description": "Gib deine E-Mail-Adresse ein, um dein Passwort zurückzusetzen", "auth_forgot_email_label": "E-Mail", "auth_forgot_email_placeholder": "E-Mail", "auth_forgot_submit": "Passwort zurücksetzen", - "auth_forgot_signin_prompt": "Passwort wieder eingefallen? {#signin}Anmelden{/signin}", + "auth_forgot_signin_prompt": "Passwort wieder eingefallen? Anmelden", "auth_forgot_mail_disabled": "Auf dieser Instanz ist das Zurücksetzen von Passwörtern nicht möglich, da kein E-Mail-Anbieter eingerichtet ist. Wende dich an deine Administration, um wieder Zugriff auf dein Konto zu erhalten.", "auth_forgot_toast_sent": "Die Anfrage zum Zurücksetzen des Passworts wurde an die angegebene E-Mail-Adresse gesendet", - "auth_login_breadcrumb": "Anmelden", "auth_login_title": "Willkommen zurück", "auth_login_loading_methods": "Verfügbare Anmeldemethoden werden geladen", @@ -98,23 +89,20 @@ "auth_login_username_label": "Benutzername oder E-Mail", "auth_login_password_label": "Passwort", "auth_login_submit": "Anmelden", - "auth_login_signup_prompt": "Noch kein Konto? {#signup}Registrieren{/signup}", - "auth_login_legal": "Mit einem Klick auf „Anmelden“ stimmst du unseren {#tos}Nutzungsbedingungen{/tos} und unserer {#privacy}Datenschutzerklärung{/privacy} zu.", - - "auth_oauth_create_breadcrumb": "Mit {provider} registrieren", - "auth_oauth_create_title": "Mit {#provider}{provider}{/provider} registrieren", + "auth_login_signup_prompt": "Noch kein Konto? Registrieren", + "auth_login_legal": "Mit einem Klick auf „Anmelden“ stimmst du unseren Nutzungsbedingungen und unserer Datenschutzerklärung zu.", + "auth_oauth_create_breadcrumb": "Mit {{provider}} registrieren", + "auth_oauth_create_title": "Mit {{provider}} registrieren", "auth_oauth_create_description": "Vervollständige deine Kontodaten", "auth_oauth_create_username_label": "Benutzername", "auth_oauth_create_username_placeholder": "Benutzername", "auth_oauth_create_email_label": "E-Mail", "auth_oauth_create_email_placeholder": "E-Mail", "auth_oauth_create_submit": "Registrieren", - "auth_oauth_create_legal": "Mit einem Klick auf „Registrieren“ stimmst du unseren {#tos}Nutzungsbedingungen{/tos} und unserer {#privacy}Datenschutzerklärung{/privacy} zu.", - + "auth_oauth_create_legal": "Mit einem Klick auf „Registrieren“ stimmst du unseren Nutzungsbedingungen und unserer Datenschutzerklärung zu.", "auth_oauth_error_breadcrumb": "Authentifizierungsfehler", "auth_oauth_error_title": "Authentifizierungsfehler", "auth_oauth_error_back": "Zurück zur Anmeldung", - "auth_reset_breadcrumb": "Passwort zurücksetzen", "auth_reset_title": "Passwort zurücksetzen", "auth_reset_checking": "Link zum Zurücksetzen wird geprüft...", @@ -127,7 +115,6 @@ "auth_reset_submit": "Passwort zurücksetzen", "auth_reset_request_new": "Neuen Link anfordern", "auth_reset_toast_success": "Passwort wurde zurückgesetzt", - "auth_signup_breadcrumb": "Registrieren", "auth_signup_toast_created_mail": "Konto erfolgreich erstellt. Bitte sieh in deinen E-Mails nach, um dein Konto zu bestätigen.", "auth_signup_toast_created_no_mail": "Konto erfolgreich erstellt. Du kannst dich jetzt anmelden.", @@ -150,11 +137,10 @@ "auth_signup_confirm_label": "Passwort bestätigen", "auth_signup_confirm_placeholder": "Passwort bestätigen", "auth_signup_submit": "Konto erstellen", - "auth_signup_signin_prompt": "Du hast schon ein Konto? {#signin}Anmelden{/signin}", + "auth_signup_signin_prompt": "Du hast schon ein Konto? Anmelden", "auth_signup_or": "Oder", "auth_signup_with_email": "Mit E-Mail registrieren", - "auth_signup_legal": "Mit einem Klick auf „Konto erstellen“ stimmst du unseren {#tos}Nutzungsbedingungen{/tos} und unserer {#privacy}Datenschutzerklärung{/privacy} zu.", - + "auth_signup_legal": "Mit einem Klick auf „Konto erstellen“ stimmst du unseren Nutzungsbedingungen und unserer Datenschutzerklärung zu.", "auth_verify_breadcrumb": "E-Mail bestätigen", "auth_verify_title": "E-Mail bestätigen", "auth_verify_verifying": "Deine E-Mail-Adresse wird bestätigt...", @@ -163,7 +149,6 @@ "auth_verify_missing_token": "Bestätigungstoken fehlt", "auth_verify_continue": "Weiter zur Anmeldung", "auth_verify_toast_success": "E-Mail-Adresse bestätigt", - "common_cancel": "Abbrechen", "common_delete": "Löschen", "common_edit": "Bearbeiten", @@ -194,7 +179,7 @@ "control_type_shock": "Schock", "control_type_vibrate": "Vibrieren", "control_type_sound": "Ton", - "live_tooltip_active": "Live über {gateway} ({country}), {latency} ms", + "live_tooltip_active": "Live über {{gateway}} ({{country}}), {{latency}} ms", "live_tooltip_connecting": "Verbinde...", "live_tooltip_connect": "Mit Live-Steuerung verbinden", "live_tooltip_hub_start": "Strg+Klick startet den ganzen Hub", @@ -207,14 +192,14 @@ "shocker_hub": "Hub", "shocker_select_hub": "Hub auswählen", "shocker_rf_id": "RF-ID", - "shocker_rf_id_invalid": "Die RF-ID muss eine ganze Zahl zwischen {min} und {max} sein.", + "shocker_rf_id_invalid": "Die RF-ID muss eine ganze Zahl zwischen {{min}} und {{max}} sein.", "shocker_model": "Modell", "shocker_select_model": "Modell auswählen", "shocker_name_placeholder": "Shocker-Name", "shocker_menu_view_logs": "Protokolle anzeigen", "shocker_delete_title": "Shocker löschen", - "shocker_delete_desc": "Möchtest du „{name}“ wirklich löschen? Dies kann nicht rückgängig gemacht werden.", - "shocker_toast_deleted": "Shocker „{name}“ gelöscht", + "shocker_delete_desc": "Möchtest du „{{name}}“ wirklich löschen? Dies kann nicht rückgängig gemacht werden.", + "shocker_toast_deleted": "Shocker „{{name}}“ gelöscht", "shocker_toast_paused": "Shocker pausiert", "shocker_toast_resumed": "Shocker fortgesetzt", "shocker_add_desc": "Registriere einen neuen Shocker an einem deiner Hubs.", @@ -239,13 +224,8 @@ "shockers_empty_no_hubs": "Erstelle zuerst einen Hub und füge dann Shocker hinzu.", "shockers_empty_has_hubs": "Füge einem deiner Hubs einen Shocker hinzu, um loszulegen.", "shockers_create_hub": "Hub erstellen", - "shockers_count": [ - { - "declarations": ["input count", "local countPlural = count: plural"], - "selectors": ["countPlural"], - "match": { "countPlural=one": "{count} Shocker", "countPlural=other": "{count} Shocker" } - } - ], + "shockers_count_one": "{{count}} Shocker", + "shockers_count_other": "{{count}} Shocker", "shared_shockers_title": "Geteilte Shocker", "shared_shockers_subtitle": "Shocker, die andere Nutzer mit dir geteilt haben.", "shared_shockers_empty_title": "Bisher wurden keine Shocker mit dir geteilt.", @@ -274,18 +254,17 @@ "shocker_edit_is_active": "Shocker ist aktiv", "shocker_edit_toast_updated": "Shocker aktualisiert", "shocker_edit_delete_desc": "Lösche diesen Shocker dauerhaft. Dies kann nicht rückgängig gemacht werden.", - "common_close": "Schließen", "common_continue": "Weiter", "common_loading": "Wird geladen...", "common_previous": "Zurück", "common_next": "Weiter", "common_steps": "Schritte", - "common_step_label": "Schritt {number}: {title}", + "common_step_label": "Schritt {{number}}: {{title}}", "common_copy": "Kopieren", "common_copied": "Kopiert", "common_never": "Nie", - "common_error": "Fehler: {message}", + "common_error": "Fehler: {{message}}", "terminal_title": "Serielles Terminal", "terminal_connecting": "Verbinde...", "terminal_help_button": "Probleme? Hilfe", @@ -298,7 +277,7 @@ "terminal_mode_raw_desc": "Nur die Konsole. Geräteprotokolle lesen und Befehle senden.", "terminal_step_channel": "Kanal auswählen", "terminal_step_board": "Board auswählen", - "terminal_go_to_step": "Zu Schritt {number}: {title}", + "terminal_go_to_step": "Zu Schritt {{number}}: {{title}}", "terminal_erase": "Vor dem Flashen löschen", "terminal_erase_desc": "Löscht alle Daten auf dem Gerät, einschließlich vorhandener Konfigurationen", "terminal_unsupported": "Dein Browser unterstützt diese Funktion nicht.", @@ -313,15 +292,15 @@ "terminal_try_driver": "Stelle sicher, dass der serielle Treiber installiert ist.", "terminal_open_troubleshooter": "Fehlerbehebung öffnen", "terminal_log_reset_no_device": "Hostseitiger Fehler beim Zurücksetzen: kein Gerät!", - "terminal_log_reset_error": "Hostseitiger Fehler beim Zurücksetzen: {error}", + "terminal_log_reset_error": "Hostseitiger Fehler beim Zurücksetzen: {{error}}", "terminal_log_send_no_device": "Senden fehlgeschlagen: kein Gerät!", - "terminal_log_send_error": "Senden fehlgeschlagen: {error}", - "terminal_log_firmware_disconnected": "Firmware getrennt: {error}", - "terminal_log_erase_failed": "Flash konnte nicht gelöscht werden: {error}", - "terminal_log_hard_reset_failed": "Hard-Reset fehlgeschlagen: {error}", + "terminal_log_send_error": "Senden fehlgeschlagen: {{error}}", + "terminal_log_firmware_disconnected": "Firmware getrennt: {{error}}", + "terminal_log_erase_failed": "Flash konnte nicht gelöscht werden: {{error}}", + "terminal_log_hard_reset_failed": "Hard-Reset fehlgeschlagen: {{error}}", "terminal_log_flash_complete": "Flashen abgeschlossen", - "terminal_log_flash_failed": "Flashen fehlgeschlagen: {error}", - "terminal_log_command_failed": "Befehl konnte nicht gesendet werden: {error}", + "terminal_log_flash_failed": "Flashen fehlgeschlagen: {{error}}", + "terminal_log_command_failed": "Befehl konnte nicht gesendet werden: {{error}}", "terminal_help_title": "Fehlerbehebung", "terminal_help_desc": "Gehe diese Schritte der Reihe nach durch. Jeder schließt eine häufige Ursache aus.", "terminal_help_step_cable": "USB-Kabel", @@ -333,23 +312,23 @@ "terminal_help_port_body": "Schließe das Gerät direkt an einen USB-Anschluss deines Computers an. Vermeide nach Möglichkeit USB-Hubs, Dockingstationen und Anschlüsse an der Gehäusefront; sie sind häufige Ursachen für Strom- und Signalprobleme. Bei einem Desktop-PC probiere einen Anschluss auf der Rückseite.", "terminal_help_driver_download": "Lade den CP210x-Treiber herunter:", "terminal_help_driver_extract": "Entpacke die ZIP-Datei in einen Ordner auf deinem Computer.", - "terminal_help_driver_run": "Öffne den Ordner und starte {#code}{installer}{/code}. Folge den Anweisungen zur Installation.", + "terminal_help_driver_run": "Öffne den Ordner und starte {{installer}}. Folge den Anweisungen zur Installation.", "terminal_help_driver_reconnect": "Schließe das Gerät erneut an.", "terminal_help_manual_intro": "Wenn der Treiber installiert wurde, das Gerät aber immer noch nicht erscheint:", - "terminal_help_manual_open": "Öffne den Geräte-Manager (drücke {#key}Win{/key} + {#key}X{/key} und wähle {#code}Device Manager{/code}).", - "terminal_help_manual_ports": "Suche unter {#code}Ports (COM & LPT){/code} nach einem Eintrag wie:", + "terminal_help_manual_open": "Öffne den Geräte-Manager (drücke Win + X und wähle Device Manager).", + "terminal_help_manual_ports": "Suche unter Ports (COM & LPT) nach einem Eintrag wie:", "terminal_help_manual_missing": "Fehlt er, erkennt Windows das Gerät überhaupt nicht; geh noch einmal die Schritte zu Kabel und Anschluss durch.", - "terminal_help_manual_update": "Klicke mit der rechten Maustaste auf das Gerät und wähle {#code}Update Driver{/code}.", - "terminal_help_manual_browse": "Wähle {#code}Browse my computer for drivers{/code} und dann den Ordner, in den du die Treiber-ZIP entpackt hast. Achte darauf, dass {#code}Include subfolders{/code} aktiviert ist.", - "terminal_help_manual_success": "Bei Erfolg sollte der Eintrag nun {#code}{deviceName}{/code} lauten.", - "terminal_help_discord_intro": "Kommst du trotzdem nicht weiter? Komm auf unseren Discord-Server und frag im Kanal {#code}{channel}{/code}. Gib bitte Folgendes an:", + "terminal_help_manual_update": "Klicke mit der rechten Maustaste auf das Gerät und wähle Update Driver.", + "terminal_help_manual_browse": "Wähle Browse my computer for drivers und dann den Ordner, in den du die Treiber-ZIP entpackt hast. Achte darauf, dass Include subfolders aktiviert ist.", + "terminal_help_manual_success": "Bei Erfolg sollte der Eintrag nun {{deviceName}} lauten.", + "terminal_help_discord_intro": "Kommst du trotzdem nicht weiter? Komm auf unseren Discord-Server und frag im Kanal {{channel}}. Gib bitte Folgendes an:", "terminal_help_discord_os": "dein Betriebssystem und deinen Browser", "terminal_help_discord_device": "das verwendete Gerät (Board-Modell, woher du es hast)", "terminal_help_discord_tried": "was du von den vorherigen Schritten schon probiert hast", "terminal_help_discord_errors": "Fehlermeldungen oder relevante Terminalausgaben", "terminal_help_discord_join": "Unserem Discord-Server beitreten", "terminal_risk_title": "⚠️ INSTABILE FIRMWARE", - "terminal_risk_intro": "Du bist dabei, {#strong}experimentelle Firmware{/strong} zu flashen, die {#strong}bekanntermaßen instabil{/strong} ist.", + "terminal_risk_intro": "Du bist dabei, experimentelle Firmware zu flashen, die bekanntermaßen instabil ist.", "terminal_risk_brick": "Dies kann dein Gerät dauerhaft unbrauchbar machen oder eine manuelle Wiederherstellung erfordern.", "terminal_risk_no_support": "Für Probleme, die durch diese Firmware entstehen, leisten wir KEINEN Support.", "terminal_risk_acknowledge": "Mir ist bewusst, dass ich die volle Verantwortung trage", @@ -364,7 +343,7 @@ "terminal_board_search": "Boards suchen...", "terminal_board_none": "Kein Board gefunden.", "terminal_flash_button": "Flashen", - "terminal_flash_progress": "Fortschritt: {status}", + "terminal_flash_progress": "Fortschritt: {{status}}", "terminal_flash_idle": "Bereit", "terminal_flash_no_device": "Kein Gerät ausgewählt.", "terminal_flash_resetting": "Wird zurückgesetzt...", @@ -375,7 +354,7 @@ "terminal_flash_done": "Gerät neu gestartet! Flashen abgeschlossen.", "terminal_port_select": "Gerät auswählen", "terminal_port_disconnect": "Gerät trennen", - "terminal_port_connected": "Gerät verbunden: {#strong}{id}{/strong}", + "terminal_port_connected": "Gerät verbunden: {{id}}", "terminal_console": "Konsole", "terminal_connected_device": "Verbundenes Gerät", "terminal_resize": "Terminalbereich anpassen", @@ -391,7 +370,7 @@ "terminal_colors_menu": "Farben...", "terminal_colors_label": "Konsolenfarben", "terminal_colors_close": "Farben schließen", - "terminal_color_input": "Farbe für {name}", + "terminal_color_input": "Farbe für {{name}}", "terminal_colors_reset": "Auf Standard zurücksetzen", "terminal_color_bg": "Hintergrund", "terminal_color_fg": "Text", @@ -421,13 +400,12 @@ "terminal_toast_clipboard_unreadable": "Zwischenablage konnte nicht gelesen werden", "terminal_toast_settings_imported": "Konsoleneinstellungen importiert", "terminal_toast_settings_invalid": "Die Zwischenablage enthält keine Konsoleneinstellungen", - "common_try_again": "Erneut versuchen", - "terminal_cfg_intro": "Werte werden per UART an das Gerät gesendet. Die Antwort des Geräts siehst du in der Konsole unten. Befehle ohne Argument lesen den Wert aus; nutze die {#eye/}-Schaltfläche neben jedem Feld, um den aktuellen Wert zu lesen.", + "terminal_cfg_intro": "Werte werden per UART an das Gerät gesendet. Die Antwort des Geräts siehst du in der Konsole unten. Befehle ohne Argument lesen den Wert aus; nutze die -Schaltfläche neben jedem Feld, um den aktuellen Wert zu lesen.", "terminal_cfg_rf_title": "RF-Sender", "terminal_cfg_rf_desc": "Steuert die RF-Ausgabe an die Shocker.", "terminal_cfg_tx_pin": "TX-GPIO-Pin", - "terminal_cfg_example": "z. B. {value}", + "terminal_cfg_example": "z. B. {{value}}", "terminal_cfg_read_value": "Aktuellen Wert lesen", "terminal_cfg_set": "Setzen", "terminal_cfg_read": "Lesen", @@ -439,13 +417,13 @@ "terminal_cfg_estop_desc": "Hardware-Taste, die jede Ausgabe stoppt.", "terminal_cfg_estop_enabled": "Not-Aus aktiviert", "terminal_cfg_estop_pin": "Not-Aus-GPIO-Pin", - "terminal_cfg_estop_note": "Hinweis: Für {#code}{latching}{/code} und {#code}{active}{/code} gibt es keine eigenen Befehle; setze sie über die JSON-Konfiguration unten.", + "terminal_cfg_estop_note": "Hinweis: Für {{latching}} und {{active}} gibt es keine eigenen Befehle; setze sie über die JSON-Konfiguration unten.", "terminal_cfg_wifi_title": "WLAN", "terminal_cfg_wifi_desc": "Zugangsdaten für Netzwerke und Hostname des Geräts.", "terminal_cfg_hostname": "Hostname", "terminal_cfg_networks": "Netzwerke (JSON-Array)", "terminal_cfg_invalid_json_array": "Muss ein gültiges JSON-Array sein", - "terminal_cfg_ap_note": "Für AP-Einstellungen ({#code}{ssid}{/code}, {#code}{password}{/code}, {#code}{disabled}{/code}, {#code}{staDisabled}{/code}, {#code}{offlineMode}{/code}) gibt es keine eigenen Befehle; nutze die JSON-Konfiguration.", + "terminal_cfg_ap_note": "Für AP-Einstellungen ({{ssid}}, {{password}}, {{disabled}}, {{staDisabled}}, {{offlineMode}}) gibt es keine eigenen Befehle; nutze die JSON-Konfiguration.", "terminal_cfg_backend_title": "Backend", "terminal_cfg_backend_desc": "OpenShock-Server und Authentifizierung.", "terminal_cfg_domain": "Domain", @@ -473,12 +451,11 @@ "terminal_cfg_factory_reset_confirm": "Dadurch wird die gesamte Konfiguration auf dem Gerät gelöscht: WLAN-Netzwerke, Backend-Zugangsdaten, Pins und alle anderen Einstellungen. Das Gerät wird auf die Standardwerte zurückgesetzt.", "terminal_cfg_read_failed_json_title": "JSON-Konfiguration konnte nicht gelesen werden", "terminal_cfg_read_failed_raw_title": "Rohkonfiguration konnte nicht gelesen werden", - "terminal_cfg_read_failed_desc": "Das Gerät hat nach {attempts} Versuchen nicht geantwortet.", + "terminal_cfg_read_failed_desc": "Das Gerät hat nach {{attempts}} Versuchen nicht geantwortet.", "terminal_cfg_common_causes": "Häufige Ursachen:", "terminal_cfg_cause_busy": "Das Gerät verarbeitet gerade einen anderen Befehl.", "terminal_cfg_cause_disconnected": "Das Gerät wurde getrennt oder neu gestartet.", "terminal_cfg_cause_unsupported": "Die Firmware-Version unterstützt diesen Befehl nicht.", - "common_status": "Status", "common_version": "Version", "common_created": "Erstellt", @@ -499,25 +476,25 @@ "hubs_name_placeholder": "Mein Hub", "hub_toast_not_connected": "Nicht mit dem Server verbunden", "hub_toast_try_later": "Versuche es gleich noch einmal.", - "hub_reboot_title": "{name} neu starten?", + "hub_reboot_title": "{{name}} neu starten?", "hub_reboot_desc": "Der Hub trennt die Verbindung und startet neu. Gekoppelte Shocker reagieren erst wieder, wenn er online ist.", "hub_reboot": "Neu starten", - "hub_hotspot_enable_title": "WLAN-Hotspot auf {name} aktivieren?", - "hub_hotspot_disable_title": "WLAN-Hotspot auf {name} deaktivieren?", + "hub_hotspot_enable_title": "WLAN-Hotspot auf {{name}} aktivieren?", + "hub_hotspot_disable_title": "WLAN-Hotspot auf {{name}} deaktivieren?", "hub_hotspot_enable_desc": "Der Hub sendet ein eigenes Einrichtungsnetzwerk. Er bleibt über dein WLAN erreichbar, aber der Hotspot ist für alle in Reichweite offen, bis du ihn ausschaltest.", "hub_hotspot_disable_desc": "Der Einrichtungs-Hotspot wird abgeschaltet. Ist der Hub noch nicht in deinem WLAN, brauchst du physischen Zugriff, um ihn erneut einzurichten.", - "hub_delete_desc": "Du bist dabei, den Hub {#strong}{name}{/strong} zu löschen.", + "hub_delete_desc": "Du bist dabei, den Hub {{name}} zu löschen.", "hub_delete_shockers": "Dadurch werden auch die folgenden Shocker gelöscht:", "hub_edit_title": "Hub bearbeiten", "hub_edit_apply": "Anwenden", "hub_pair_title_generate": "Kopplungscode erstellen?", "hub_pair_title_generated": "Kopplungscode erstellt", "hub_pair_title_paired": "Hub gekoppelt", - "hub_pair_consumed": "{#strong}{name}{/strong} hat diesen Kopplungscode verwendet und ist jetzt gekoppelt.", + "hub_pair_consumed": "{{name}} hat diesen Kopplungscode verwendet und ist jetzt gekoppelt.", "hub_pair_used": "Der Code wurde verwendet und ist nicht mehr gültig.", - "hub_pair_generated_for": "Kopplungscode für {#strong}{name}{/strong} erstellt.", + "hub_pair_generated_for": "Kopplungscode für {{name}} erstellt.", "hub_copy_now": "Der Code unten ist später nicht mehr abrufbar. Kopiere ihn jetzt und trage ihn in deinen Clients ein.", - "hub_pair_generate_for": "Du bist dabei, einen Kopplungscode für {#strong}{name}{/strong} zu erstellen.", + "hub_pair_generate_for": "Du bist dabei, einen Kopplungscode für {{name}} zu erstellen.", "hub_pair_valid_for": "Er ist nach der Erstellung 15 Minuten lang gültig.", "hub_pair_one_active": "Pro Hub gibt es nur einen aktiven Kopplungscode; ein neuer Code ersetzt den älteren.", "hub_pair_complete": "Kopplung abgeschlossen", @@ -525,8 +502,8 @@ "hub_pair_copied_close": "Code kopiert, schließen", "hub_pair_get": "Kopplungscode abrufen", "hub_token_generated": "Token erstellt", - "hub_token_generated_for": "Neues Token für {#strong}{name}{/strong} erstellt.", - "hub_token_regenerate_for": "Du bist dabei, das Token für {#strong}{name}{/strong} neu zu erstellen.", + "hub_token_generated_for": "Neues Token für {{name}} erstellt.", + "hub_token_regenerate_for": "Du bist dabei, das Token für {{name}} neu zu erstellen.", "hub_token_invalidate": "Dadurch wird das aktuelle Token ungültig und Clients, die es verwenden, werden getrennt.", "hub_token_confirm": "Möchtest du das wirklich tun?", "hub_token_label": "Neues Token:", @@ -554,12 +531,12 @@ "hub_update_status_error": "Fehler", "hub_update_status_timeout": "Zeitüberschreitung", "hub_update_confirm_title": "Firmware-Update bestätigen", - "hub_update_confirm_desc": "{#strong}{name}{/strong} auf Version {#strong}{version}{/strong} aktualisieren?", + "hub_update_confirm_desc": "{{name}} auf Version {{version}} aktualisieren?", "hub_update_unstable_warning": "Diese Version stammt möglicherweise nicht aus dem stabilen Kanal und kann Fehler enthalten.", - "hub_update_title": "{name} aktualisieren", + "hub_update_title": "{{name}} aktualisieren", "hub_update_subtitle": "Firmware-Updates für diesen Hub verwalten.", "hub_update_status_title": "Hub-Status", - "hub_update_firmware": "Firmware: {#mono}{version}{/mono}", + "hub_update_firmware": "Firmware: {{version}}", "hub_update_confirm": "Aktualisieren", "hub_update_success": "Update erfolgreich abgeschlossen", "hub_update_rolled_back": "Gerät wurde auf die vorherige Version zurückgesetzt", @@ -567,9 +544,9 @@ "hub_update_flash_again": "Erneut flashen", "hub_update_card_title": "Firmware-Update", "hub_update_card_desc": "Wähle einen Firmware-Kanal und eine Version zur Installation.", - "hub_update_to": "Auf {version} aktualisieren", + "hub_update_to": "Auf {{version}} aktualisieren", "hub_update_must_be_online": "Der Hub muss online sein, um ein Update zu starten.", - "hub_update_updating_to": "Aktualisierung auf {version}...", + "hub_update_updating_to": "Aktualisierung auf {{version}}...", "hub_update_total": "Gesamt", "hub_update_task": "Aufgabe", "hub_update_history": "Update-Verlauf", @@ -581,14 +558,14 @@ "hub_update_not_found": "Hub nicht gefunden.", "home_breadcrumb": "Startseite", "home_welcome": "Willkommen zurück", - "home_welcome_name": "Willkommen zurück, {name}", + "home_welcome_name": "Willkommen zurück, {{name}}", "home_subtitle": "Hier ist ein Überblick über dein OpenShock-Setup.", - "home_hubs_online": "{count} online", + "home_hubs_online": "{{count}} online", "home_hub_status": "Hub-Status", "home_no_hubs": "Keine Hubs", "home_all_online": "Alle online", "home_all_offline": "Alle offline", - "home_some_online": "{online}/{total} online", + "home_some_online": "{{online}}/{{total}} online", "home_quick_links": "Schnellzugriff", "home_my_shockers": "Meine Shocker", "home_my_shockers_desc": "Steuere deine Shocker", @@ -599,24 +576,15 @@ "home_get_started_desc": "Du hast noch keine Hubs. Erstelle einen Hub, um dein erstes Gerät zu verbinden, und füge dann Shocker hinzu.", "home_set_up_hub": "Hub einrichten", "home_first_shocker": "Füge deinen ersten Shocker hinzu", - "home_first_shocker_desc": [ - { - "declarations": ["input count", "local countPlural = count: plural"], - "selectors": ["countPlural"], - "match": { - "countPlural=one": "Du hast {count} Hub eingerichtet. Füge einen Shocker hinzu, um ihn zu steuern.", - "countPlural=other": "Du hast {count} Hubs eingerichtet. Füge einen Shocker hinzu, um ihn zu steuern." - } - } - ], + "home_first_shocker_desc_one": "Du hast {{count}} Hub eingerichtet. Füge einen Shocker hinzu, um ihn zu steuern.", + "home_first_shocker_desc_other": "Du hast {{count}} Hubs eingerichtet. Füge einen Shocker hinzu, um ihn zu steuern.", "home_go_to_shockers": "Zu den Shockern", "profile_title": "Profil", "profile_coming_soon": "Das Profil kommt bald", "profile_coming_soon_desc": "Dein öffentliches Profil ist noch nicht verfügbar. Kontodetails findest du in den Einstellungen.", - "common_retry": "Erneut versuchen", "common_never_used": "Nie verwendet", - "common_expires": "Läuft {time} ab", + "common_expires": "Läuft {{time}} ab", "common_search_placeholder": "Suchen...", "common_unknown": "Unbekannt", "settings_breadcrumb_account": "Konto", @@ -646,7 +614,7 @@ "account_deactivate": "Konto deaktivieren", "account_email_title": "E-Mail ändern", "account_email_desc": "Gib deine neue E-Mail-Adresse ein und bestätige mit deinem aktuellen Passwort.", - "account_email_toast_sent": "Bestätigungs-E-Mail an {email} gesendet. Klicke auf den Link in der E-Mail, um die Änderung zu übernehmen.", + "account_email_toast_sent": "Bestätigungs-E-Mail an {{email}} gesendet. Klicke auf den Link in der E-Mail, um die Änderung zu übernehmen.", "account_new_email": "Neue E-Mail", "account_current_password": "Aktuelles Passwort", "account_password_title": "Passwort ändern", @@ -661,8 +629,8 @@ "tokens_toast_refreshed": "Token aktualisiert", "tokens_empty_title": "Keine API-Token", "tokens_empty_desc": "Erstelle ein Token, um dich bei der OpenShock-API zu authentifizieren.", - "tokens_created_on": "Erstellt am {date}", - "tokens_last_used": "Zuletzt verwendet {time}", + "tokens_created_on": "Erstellt am {{date}}", + "tokens_last_used": "Zuletzt verwendet {{time}}", "tokens_never_expires": "Läuft nie ab", "tokens_load_failed": "API-Token konnten nicht geladen werden.", "token_toast_edited": "Token erfolgreich bearbeitet", @@ -684,7 +652,7 @@ "token_toast_paused": "Token pausiert", "token_toast_resumed": "Token fortgesetzt", "token_delete_title": "API-Token löschen", - "token_delete_desc": "Möchtest du {#strong}{name}{/strong} wirklich löschen?", + "token_delete_desc": "Möchtest du {{name}} wirklich löschen?", "token_delete_permanent": "Dies kann nicht rückgängig gemacht werden. Das Token wird dauerhaft gelöscht.", "token_toast_deleted": "Token erfolgreich gelöscht", "token_resume": "Token fortsetzen", @@ -697,11 +665,11 @@ "token_new_breadcrumb": "Neu", "token_redirect_not_allowed": "Die angegebene redirect_uri ist nicht erlaubt. Nur Loopback-Adressen oder eigene Anwendungsschemata sind zulässig.", "token_params_missing": "Erforderliche GET-Parameter fehlen. Stelle sicher, dass name, redirect_uri und permissions angegeben sind.", - "token_invalid_permissions": "Ungültige Berechtigungen angegeben: {list}", + "token_invalid_permissions": "Ungültige Berechtigungen angegeben: {{list}}", "token_toast_created": "Token erfolgreich erstellt", "token_request_title": "API-Token-Anfrage", "token_access_granted": "Zugriff gewährt", - "token_shared_redirecting": "Das Token wurde erstellt und an die Anwendung übergeben. Du wirst zurückgeleitet zu {#b}{uri}{/b}.", + "token_shared_redirecting": "Das Token wurde erstellt und an die Anwendung übergeben. Du wirst zurückgeleitet zu {{uri}}.", "token_not_redirected": "Wenn du nicht automatisch weitergeleitet wirst, nutze die Schaltfläche unten.", "token_finish": "Fertig", "token_generated_title": "API-Token erstellt", @@ -709,7 +677,7 @@ "token_new_title": "Neues API-Token", "token_external_desc": "Eine externe Anwendung möchte auf dein Konto zugreifen. Prüfe und passe die Berechtigungen unten an, bevor du den Zugriff erlaubst.", "token_new_desc": "Konfiguriere und erstelle ein neues API-Token für dein Konto.", - "token_external_requesting": "{#b}{name}{/b} fordert ein API-Token an. Dein Token wird an die Anwendung unter {#b}{uri}{/b} übergeben.", + "token_external_requesting": "{{name}} fordert ein API-Token an. Dein Token wird an die Anwendung unter {{uri}} übergeben.", "token_allow": "Erlauben", "token_generate": "Erstellen", "token_deny": "Ablehnen", @@ -719,13 +687,13 @@ "sessions_load_failed": "Sitzungen konnten nicht geladen werden.", "sessions_empty_title": "Keine aktiven Sitzungen", "sessions_empty_desc": "Sitzungen erscheinen hier, sobald du dich in einem Browser oder einer App anmeldest.", - "sessions_last_seen": "Zuletzt gesehen {time}", - "sessions_signed_in": "Angemeldet {time}", + "sessions_last_seen": "Zuletzt gesehen {{time}}", + "sessions_signed_in": "Angemeldet {{time}}", "session_toast_revoked": "Sitzung erfolgreich widerrufen", "session_revoke_title": "Sitzung widerrufen", "session_revoke": "Widerrufen", "session_revoke_desc": "Möchtest du diese Sitzung wirklich widerrufen?", - "session_revoke_from": "Sitzung angemeldet von {#strong}{ip}{/strong} mit {#strong}{agent}{/strong}", + "session_revoke_from": "Sitzung angemeldet von {{ip}} mit {{agent}}", "connections_title": "OAuth-Verbindungen", "connections_subtitle": "Verknüpfe Konten von Drittanbietern oder trenne sie, um dich schneller anzumelden und dein Profil synchron zu halten.", "connections_toast_linked": "Konto verknüpft.", @@ -738,11 +706,11 @@ "connections_empty_desc": "Wähle oben „Neuen Anbieter verknüpfen“, um verfügbare Anbieter zu verbinden.", "connections_unlink": "Trennen", "connections_load_failed": "OAuth-Verbindungen konnten nicht geladen werden.", - "connections_unlink_title": "{name} trennen?", + "connections_unlink_title": "{{name}} trennen?", "connections_unlink_title_generic": "Dieses Konto trennen?", "connections_unlink_desc": "Du kannst dich dann nicht mehr mit diesem Anbieter anmelden, bis du ihn erneut verknüpfst.", - "provider_starting": "{name} wird gestartet...", - "provider_link": "{name} verknüpfen", + "provider_starting": "{{name}} wird gestartet...", + "provider_link": "{{name}} verknüpfen", "audit_subtitle": "Sicherheitsrelevante Aktivitäten in deinem Konto. Prüfe alles, was du nicht kennst.", "audit_col_time": "Zeit", "audit_col_action": "Aktion", @@ -768,22 +736,13 @@ "audit_action_automation_token_rotated": "Automatisierungstoken rotiert", "audit_action_automation_token_deleted": "Automatisierungstoken gelöscht", "audit_action_automation_token_used": "Automatisierungstoken verwendet", - "audit_meta_session": "Sitzung {id}", - "audit_meta_changed": "{old} zu {new}", - "audit_meta_email_requested": "Änderung zu {email} angefordert", - "audit_meta_accounts_removed": [ - { - "declarations": ["input count", "local countPlural = count: plural"], - "selectors": ["countPlural"], - "match": { - "countPlural=one": "{name} ({count} Konto entfernt)", - "countPlural=other": "{name} ({count} Konten entfernt)" - } - } - ], + "audit_meta_session": "Sitzung {{id}}", + "audit_meta_changed": "{{old}} zu {{new}}", + "audit_meta_email_requested": "Änderung zu {{email}} angefordert", + "audit_meta_accounts_removed_one": "{{name}} ({{count}} Konto entfernt)", + "audit_meta_accounts_removed_other": "{{name}} ({{count}} Konten entfernt)", "audit_meta_scheduled_deletion": "Zur Löschung vorgemerkt", "audit_meta_kept": "Für Reaktivierung aufbewahrt", - "common_view": "Ansehen", "common_save": "Speichern", "common_saving": "Wird gespeichert...", @@ -808,20 +767,12 @@ "public_share_create_title": "Öffentliche Freigabe erstellen", "public_share_toast_deleted": "Öffentliche Freigabe gelöscht", "public_share_delete_title": "Öffentliche Freigabe löschen", - "public_share_delete_desc": "Möchtest du die öffentliche Freigabe {#strong}{name}{/strong} wirklich löschen?", - "public_share_edit_title": "Öffentliche Freigabe: {name}", + "public_share_delete_desc": "Möchtest du die öffentliche Freigabe {{name}} wirklich löschen?", + "public_share_edit_title": "Öffentliche Freigabe: {{name}}", "public_share_edit_subtitle": "Bearbeitung: Änderungen gelten erst nach dem Speichern.", "public_share_add_shocker": "Shocker hinzufügen", - "public_share_toast_added": [ - { - "declarations": ["input count", "local countPlural = count: plural"], - "selectors": ["countPlural"], - "match": { - "countPlural=one": "{count} Shocker zur Freigabe hinzugefügt", - "countPlural=other": "{count} Shocker zur Freigabe hinzugefügt" - } - } - ], + "public_share_toast_added_one": "{{count}} Shocker zur Freigabe hinzugefügt", + "public_share_toast_added_other": "{{count}} Shocker zur Freigabe hinzugefügt", "public_share_empty_shockers_title": "Keine Shocker in dieser Freigabe", "public_share_empty_shockers_desc": "Füge einen Shocker hinzu, dann kann ihn jeder mit dem Link steuern.", "public_share_load_failed": "Fehler beim Laden der Freigabedetails", @@ -851,15 +802,14 @@ "perm_live_on": "Live aktiviert", "perm_live_off": "Live deaktiviert", "perm_live_control": "Live-Steuerung", - "user_selector_avatar_of": "Profilbild von {name}", + "user_selector_avatar_of": "Profilbild von {{name}}", "user_selector_placeholder": "Benutzernamen eingeben", "user_selector_aria": "Zu suchender Benutzername", "user_selector_search": "Benutzer suchen", "user_selector_found": "Benutzer gefunden", - "common_remove": "Entfernen", "user_shares_subtitle": "Direkte, dauerhafte Freigaben mit anderen Benutzern.", - "user_shares_toast_invited": "Shocker-Einladung an {name} gesendet", + "user_shares_toast_invited": "Shocker-Einladung an {{name}} gesendet", "user_shares_redeem": "Code einlösen", "user_shares_new": "Neue Freigabe", "user_shares_tab_shares": "Freigaben", @@ -882,12 +832,12 @@ "share_code_redeem": "Einlösen", "incoming_shares_empty_title": "Nichts mit dir geteilt", "incoming_shares_empty_desc": "Bisher hat niemand einen Shocker mit dir geteilt.", - "incoming_share_toast_removed": "Freigabe von {name} entfernt", + "incoming_share_toast_removed": "Freigabe von {{name}} entfernt", "incoming_share_remove_title": "Freigabe entfernen", - "incoming_share_remove_desc": "Möchtest du die Freigabe von {#strong}{name}{/strong} wirklich entfernen?", - "incoming_share_toast_removed_shocker": "{shocker} von {name} entfernt", + "incoming_share_remove_desc": "Möchtest du die Freigabe von {{name}} wirklich entfernen?", + "incoming_share_toast_removed_shocker": "{{shocker}} von {{name}} entfernt", "incoming_share_remove_shocker_title": "Diesen geteilten Shocker entfernen?", - "incoming_share_remove_shocker_desc": "Möchtest du den geteilten Shocker {#strong}{shocker}{/strong} von {#strong}{name}{/strong} wirklich entfernen?", + "incoming_share_remove_shocker_desc": "Möchtest du den geteilten Shocker {{shocker}} von {{name}} wirklich entfernen?", "incoming_share_manage_from": "Freigaben verwalten von", "share_remove": "Freigabe entfernen", "invites_empty_title": "Noch keine Einladungen", @@ -898,23 +848,23 @@ "invites_incoming": "Eingehend", "invites_incoming_empty_title": "Keine eingehenden Einladungen", "invites_incoming_empty_desc": "Du hast keine eingehenden Einladungen.", - "invite_toast_accepted": "Einladung von {name} angenommen", - "invite_toast_declined": "Einladung von {name} abgelehnt", + "invite_toast_accepted": "Einladung von {{name}} angenommen", + "invite_toast_declined": "Einladung von {{name}} abgelehnt", "invite_deny_title": "Einladung ablehnen", "invite_deny_label": "Einladung ablehnen", "invite_deny": "Ablehnen", - "invite_deny_desc": "Möchtest du die Einladung von {#strong}{name}{/strong} wirklich ablehnen?", + "invite_deny_desc": "Möchtest du die Einladung von {{name}} wirklich ablehnen?", "invite_accept": "Einladung annehmen", - "invite_toast_cancelled_for": "Einladung für {name} zurückgezogen ({id})", - "invite_toast_cancelled": "Einladung {id} zurückgezogen", + "invite_toast_cancelled_for": "Einladung für {{name}} zurückgezogen ({{id}})", + "invite_toast_cancelled": "Einladung {{id}} zurückgezogen", "invite_cancel_title": "Einladung zurückziehen", "invite_cancel": "Zurückziehen", - "invite_cancel_for_desc": "Möchtest du die Einladung für {#strong}{name}{/strong} wirklich zurückziehen?", - "invite_cancel_code_desc": "Möchtest du die Einladung mit dem Code {#strong}{code}{/strong} wirklich zurückziehen?", + "invite_cancel_for_desc": "Möchtest du die Einladung für {{name}} wirklich zurückziehen?", + "invite_cancel_code_desc": "Möchtest du die Einladung mit dem Code {{code}} wirklich zurückziehen?", "invite_cancel_outstanding": "Offene Einladung zurückziehen", "outgoing_shares_empty_title": "Keine geteilten Shocker", "outgoing_shares_empty_desc": "Du hast noch keine Shocker mit anderen Benutzern geteilt.", - "outgoing_share_toast_removed": "Geteilten Shocker {name} entfernt", + "outgoing_share_toast_removed": "Geteilten Shocker {{name}} entfernt", "outgoing_share_remove_title": "Diesen Shocker nicht mehr teilen?", "outgoing_share_editing_for": "Freigaben bearbeiten für", "outgoing_share_limits": "Grenzen & Berechtigungen", @@ -922,11 +872,9 @@ "outgoing_share_per_desc": "Einschränkungen je Shocker anpassen", "outgoing_share_all": "Alle", "outgoing_share_per": "Je Shocker", - - "outgoing_share_remove_desc": "Möchtest du {#strong}{shocker}{/strong} wirklich nicht mehr mit {#strong}{name}{/strong} teilen?", - + "outgoing_share_remove_desc": "Möchtest du {{shocker}} wirklich nicht mehr mit {{name}} teilen?", "report_breadcrumb": "API-Token melden", - "report_toast_clipboard_failed": "Zwischenablage konnte nicht gelesen werden: {error}", + "report_toast_clipboard_failed": "Zwischenablage konnte nicht gelesen werden: {{error}}", "report_title": "Geleakte API-Token melden", "report_paste": "Aus Zwischenablage einfügen", "report_warning": "Dieses Formular dient nur zum Melden versehentlich geleakter API-Token.", @@ -944,16 +892,11 @@ "expiration_label": "Ablauf", "expiration_never": "Nie", "expiration_custom": "Benutzerdefiniert", - "expiration_days": [ - { - "declarations": ["input count", "local countPlural = count: plural"], - "selectors": ["countPlural"], - "match": { "countPlural=one": "{count} Tag", "countPlural=other": "{count} Tage" } - } - ], + "expiration_days_one": "{{count}} Tag", + "expiration_days_other": "{{count}} Tage", "expiration_required": "Ablaufdatum ist erforderlich", "expiration_never_desc": "Läuft nie ab", - "expiration_expires_at": "Läuft {time} ab ({date})", + "expiration_expires_at": "Läuft {{time}} ab ({{date}})", "date_picker_placeholder": "Datum wählen", "telemetry_toast_title": "OpenShock verbessern helfen?", "telemetry_toast_desc": "Sende Diagnosedaten, damit wir Abstürze und langsame API-Aufrufe beheben können. Berichte enthalten die Fehlermeldung, den Stacktrace und deine IP. Du kannst das jederzeit in den Kontoeinstellungen ändern.", @@ -963,28 +906,27 @@ "table_show_details": "Details anzeigen", "table_hide_details": "Details ausblenden", "table_no_results": "Keine Ergebnisse.", - "table_sort_asc": "Nach {name} sortieren, aufsteigend", - "table_sort_desc": "Nach {name} sortieren, absteigend", - "table_sort_none": "Nach {name} sortieren, unsortiert", + "table_sort_asc": "Nach {{name}} sortieren, aufsteigend", + "table_sort_desc": "Nach {{name}} sortieren, absteigend", + "table_sort_none": "Nach {{name}} sortieren, unsortiert", "cell_na": "k. A.", "cell_not_applicable": "Nicht anwendbar", "cell_invalid": "Ungültig", "cell_unavailable": "Nicht verfügbar", "cell_none": "Keine", - "oauth_login_with": "Mit {provider} anmelden", - "oauth_signup_with": "Mit {provider} registrieren", + "oauth_login_with": "Mit {{provider}} anmelden", + "oauth_signup_with": "Mit {{provider}} registrieren", "signalr_connect_failed": "Verbindung zum Server fehlgeschlagen!", "signalr_disconnect_failed": "Fehler beim Trennen vom Server!", "signalr_invalid_update": "Ungültiges Update vom Server erhalten!", "signalr_invalid_log": "Ungültige Protokolldaten vom Server erhalten!", "signalr_invalid_ota": "Ungültige Firmware-Update-Daten vom Server erhalten!", - "ota_toast_failed": "Firmware-Update des Hubs fehlgeschlagen: {message}", + "ota_toast_failed": "Firmware-Update des Hubs fehlgeschlagen: {{message}}", "ota_toast_succeeded": "Firmware-Update des Hubs erfolgreich abgeschlossen!", "ota_toast_rolled_back": "Hub-Firmware auf die vorherige Version zurückgesetzt", "lcg_connect_failed": "Verbindung zum Live-Control-Gateway fehlgeschlagen", - "terminal_toast_bootloader_failed": "Bootloader konnte nicht gestartet werden: {error}", - "terminal_toast_app_mode_failed": "Anwendungsmodus konnte nicht gestartet werden: {error}", - + "terminal_toast_bootloader_failed": "Bootloader konnte nicht gestartet werden: {{error}}", + "terminal_toast_app_mode_failed": "Anwendungsmodus konnte nicht gestartet werden: {{error}}", "problem_account_account_not_activated_title": "Konto nicht aktiviert", "problem_account_account_not_activated_desc": "Sieh in deinem Posteingang nach der Aktivierungs-E-Mail.", "problem_account_activation_not_found_title": "Der Aktivierungslink ist ungültig", @@ -1102,22 +1044,12 @@ "problem_webhook_not_found_title": "Webhook nicht gefunden", "problem_webhook_unsupported_title": "Nur Discord-Webhooks werden unterstützt", "problem_webhook_unsupported_desc": "Verwende eine discord.com-URL, nicht canary oder ptb.", - "error_too_many_requests": "Zu viele Anfragen", - "error_retry_after": [ - { - "declarations": ["input seconds", "local secondsPlural = seconds: plural"], - "selectors": ["secondsPlural"], - "match": { - "secondsPlural=one": "Versuche es in {seconds} Sekunde erneut.", - "secondsPlural=other": "Versuche es in {seconds} Sekunden erneut." - } - } - ], + "error_retry_after_one": "Versuche es in {{count}} Sekunde erneut.", + "error_retry_after_other": "Versuche es in {{count}} Sekunden erneut.", "error_unexpected_response": "Unerwartete Serverantwort", "error_internal": "Ein interner Fehler ist aufgetreten", "error_network": "Ein Netzwerkfehler ist aufgetreten", - - "dev_banner": "Dies ist die {#b}ENTWICKLUNGS{/b}-Umgebung von OpenShock. {#u}Es werden keine Daten gespeichert{/u}, und sie wird regelmäßig mit Produktionsdaten überschrieben.", + "dev_banner": "Dies ist die ENTWICKLUNGS-Umgebung von OpenShock. Es werden keine Daten gespeichert, und sie wird regelmäßig mit Produktionsdaten überschrieben.", "firmware_channel_bugs_warning": "Dieser Kanal kann Fehler enthalten." } From 470953bbab870e67780557b793f4153d3c99a105 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Luc=20=E2=99=A5?= Date: Thu, 12 Nov 2026 17:43:12 +0100 Subject: [PATCH 10/27] New translations en.json (Greek) [ci skip] --- messages/el.json | 1055 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 1055 insertions(+) create mode 100644 messages/el.json diff --git a/messages/el.json b/messages/el.json new file mode 100644 index 00000000..ef4df56c --- /dev/null +++ b/messages/el.json @@ -0,0 +1,1055 @@ +{ + "landing_tagline": "The go-to platform for safe, reliable, real low-latency remote shocking.", + "landing_section_label": "Home", + "landing_hubs_online": "Hubs online right now: ", + "landing_learn_more": "Learn More", + "landing_wiki": "Wiki", + "landing_meta_description": "Welcome to OpenShock, a free and open-source ecosystem to control various shock collars over the internet.", + "instance_meta_description": "Welcome to {{siteName}}, an independent instance of OpenShock, a free and open-source ecosystem to control various shock collars over the internet.", + "header_sidebar_toggle": "Toggle Sidebar", + "header_avatar_alt": "{{name}}'s avatar", + "header_menu_profile": "Profile", + "header_menu_settings": "Settings", + "header_menu_logout": "Logout", + "header_login": "Login", + "header_signup": "Sign Up", + "header_github_title": "OpenShock on GitHub", + "header_discord_title": "Community Discord", + "footer_made_with": "Made with by the OpenShock Team", + "footer_connection_status_label": "Server connection status", + "footer_signalr_state": "SignalR State", + "footer_frontend_version": "Frontend Version", + "footer_frontend_commit_title": "Commit {{commit}}", + "footer_backend_version": "Backend Version", + "footer_backend_commit_title": "Commit {{commit}}", + "footer_language_label": "Language", + "sidebar_home_link_label": "OpenShock home", + "sidebar_group_general": "General", + "sidebar_home": "Home", + "sidebar_shockers": "Shockers", + "sidebar_shared_shockers": "Shared Shockers", + "sidebar_hubs": "Hubs", + "sidebar_user_shares": "User Shares", + "sidebar_public_shares": "Public Shares", + "sidebar_serial_terminal": "Serial Terminal", + "sidebar_group_admin": "Admin", + "sidebar_admin_monitoring": "Monitoring", + "sidebar_admin_online_hubs": "Online Hubs", + "sidebar_admin_online_gateways": "Online Gateways", + "sidebar_admin_management": "Management", + "sidebar_admin_users": "Users", + "sidebar_admin_blacklists": "Blacklists", + "sidebar_admin_webhooks": "Webhooks", + "sidebar_admin_mail": "Mail", + "sidebar_admin_automation_tokens": "Automation Tokens", + "sidebar_admin_configuration": "Configuration", + "sidebar_group_settings": "Settings", + "sidebar_settings_api_tokens": "API Tokens", + "sidebar_settings_sessions": "Sessions", + "sidebar_settings_audit_log": "Audit Log", + "sidebar_settings_connections": "Connections", + "sidebar_settings_account": "Account Settings", + "error_meta_title": "Service Unavailable", + "error_meta_description": "OpenShock is currently unavailable", + "error_meta_logo_alt": "OpenShock Logo", + "error_fallback_message": "Something went wrong.", + "error_not_found_message": "Page not found", + "error_not_found_description": "The page you're looking for doesn't exist.", + "error_unexpected_description": "An unexpected error occurred.", + "error_go_back": "Go back", + "auth_layout_logo_alt": "OpenShock Logo", + "auth_layout_invalid_redirect_removed": "An invalid redirect URL was removed for your safety.", + "auth_activate_breadcrumb": "Activate Account", + "auth_activate_title": "Activate Account", + "auth_activate_activating": "Activating your account...", + "auth_activate_success": "Your account has been activated", + "auth_activate_failed": "This activation link is invalid or has expired", + "auth_activate_missing_token": "Missing activation token", + "auth_activate_continue": "Continue to login", + "auth_activate_toast_success": "Account activated", + "auth_forgot_breadcrumb": "Forgot Password", + "auth_forgot_title": "Forgot Password", + "auth_forgot_description": "Enter your email to reset your password", + "auth_forgot_email_label": "Email", + "auth_forgot_email_placeholder": "Email", + "auth_forgot_submit": "Reset Password", + "auth_forgot_signin_prompt": "Remember your password? Sign in", + "auth_forgot_mail_disabled": "Password resets are unavailable on this instance because it has no mail provider configured. Please contact your administrator for help recovering your account.", + "auth_forgot_toast_sent": "Reset password request has been sent to the given email", + "auth_login_breadcrumb": "Login", + "auth_login_title": "Welcome back", + "auth_login_loading_methods": "Loading available login methods", + "auth_login_choose_method": "Login with one of these methods", + "auth_login_with_account": "Login with your OpenShock Account", + "auth_login_activation_after_signup": "Your account has been created. We've sent an activation link to your email address. Check your inbox and spam folder.", + "auth_login_activation_pending": "Your account isn't activated yet. We've sent an activation link to your email address. Check your inbox and spam folder. If nothing arrives, try logging in again later to get a new link.", + "auth_login_oauth_only": "This account has no password. Sign in with the provider you signed up with.", + "auth_login_oauth_only_with_buttons": "This account has no password. Sign in with the provider you signed up with using the buttons above.", + "auth_login_or_continue_with": "Or continue with", + "auth_login_username_label": "Username or Email", + "auth_login_password_label": "Password", + "auth_login_submit": "Login", + "auth_login_signup_prompt": "Don't have an account? Sign up", + "auth_login_legal": "By clicking Login, you agree to our Terms of Service and Privacy Policy.", + "auth_oauth_create_breadcrumb": "Sign Up With {{provider}}", + "auth_oauth_create_title": "Sign Up With {{provider}}", + "auth_oauth_create_description": "Complete your account details", + "auth_oauth_create_username_label": "Username", + "auth_oauth_create_username_placeholder": "Username", + "auth_oauth_create_email_label": "Email", + "auth_oauth_create_email_placeholder": "Email", + "auth_oauth_create_submit": "Sign Up", + "auth_oauth_create_legal": "By clicking Sign Up, you agree to our Terms of Service and Privacy Policy.", + "auth_oauth_error_breadcrumb": "Authentication Error", + "auth_oauth_error_title": "Authentication Error", + "auth_oauth_error_back": "Back to login", + "auth_reset_breadcrumb": "Reset Password", + "auth_reset_title": "Reset Password", + "auth_reset_checking": "Verifying reset link...", + "auth_reset_choose_password": "Choose a new password for your account", + "auth_reset_invalid": "This reset link is invalid or has expired", + "auth_reset_password_label": "New Password", + "auth_reset_password_placeholder": "New Password", + "auth_reset_confirm_label": "Confirm New Password", + "auth_reset_confirm_placeholder": "Confirm New Password", + "auth_reset_submit": "Reset Password", + "auth_reset_request_new": "Request a new reset link", + "auth_reset_toast_success": "Password has been reset", + "auth_signup_breadcrumb": "Sign Up", + "auth_signup_toast_created_mail": "Account created successfully. Please check your email to verify your account.", + "auth_signup_toast_created_no_mail": "Account created successfully. You can log in now.", + "auth_signup_dialog_title": "Welcome! Thank you for signing up! ❤️", + "auth_signup_dialog_created_mail": "Your account has been created. 🎉 Please check your email to verify your account.", + "auth_signup_dialog_verify_then_login": "After verifying your email, you can log in to your account.", + "auth_signup_dialog_created_no_mail": "Your account has been created and is ready to use. 🎉", + "auth_signup_dialog_login_now": "You can log in to your account now.", + "auth_signup_title": "Create your account", + "auth_signup_loading_methods": "Loading available sign-up methods", + "auth_signup_using_email": "Signing up using email", + "auth_signup_choose_method": "Choose your preferred sign-up method", + "auth_signup_back": "Back", + "auth_signup_username_label": "Username", + "auth_signup_username_placeholder": "John OpenShock", + "auth_signup_email_label": "Email", + "auth_signup_email_placeholder": "john@example.com", + "auth_signup_password_label": "Password", + "auth_signup_password_placeholder": "Password", + "auth_signup_confirm_label": "Confirm Password", + "auth_signup_confirm_placeholder": "Confirm Password", + "auth_signup_submit": "Create Account", + "auth_signup_signin_prompt": "Already have an account? Sign in", + "auth_signup_or": "Or", + "auth_signup_with_email": "Signup with Email", + "auth_signup_legal": "By clicking Create Account, you agree to our Terms of Service and Privacy Policy.", + "auth_verify_breadcrumb": "Verify Email", + "auth_verify_title": "Verify Email", + "auth_verify_verifying": "Verifying your email address...", + "auth_verify_success": "Your email has been verified", + "auth_verify_failed": "This verification link is invalid or has expired", + "auth_verify_missing_token": "Missing verification token", + "auth_verify_continue": "Continue to login", + "auth_verify_toast_success": "Email verified", + "common_cancel": "Cancel", + "common_delete": "Delete", + "common_edit": "Edit", + "common_share": "Share", + "common_copy_id": "Copy ID", + "common_id_copied": "ID copied to clipboard", + "common_open_menu": "Open menu", + "common_refresh": "Refresh", + "common_settings": "Settings", + "common_clear": "Clear", + "common_online": "Online", + "common_offline": "Offline", + "common_paused": "Paused", + "common_resume": "Resume", + "common_resuming": "Resuming...", + "common_coming_soon": "(Coming soon)", + "common_save_changes": "Save Changes", + "common_danger_zone": "Danger Zone", + "common_name": "Name", + "control_intensity": "Intensity", + "control_duration": "Duration", + "control_max_intensity": "Max Intensity", + "control_max_duration": "Max Duration", + "control_vibration": "Vibration", + "control_value": "Value", + "control_live_intensity": "Live intensity", + "control_type_stop": "Stop", + "control_type_shock": "Shock", + "control_type_vibrate": "Vibrate", + "control_type_sound": "Sound", + "live_tooltip_active": "Live via {{gateway}} ({{country}}), {{latency}}ms", + "live_tooltip_connecting": "Connecting...", + "live_tooltip_connect": "Connect to Live Control", + "live_tooltip_hub_start": "Ctrl+click to start the whole hub", + "live_tooltip_hub_stop": "Ctrl+click to stop the whole hub", + "pause_resume_shocker": "Resume shocker", + "pause_pause_shocker": "Pause shocker", + "pause_resume_all": "Resume all shockers", + "pause_pause_all": "Pause all shockers", + "shocker_label": "Shocker", + "shocker_hub": "Hub", + "shocker_select_hub": "Select hub", + "shocker_rf_id": "RF ID", + "shocker_rf_id_invalid": "RF ID must be a whole number between {{min}} and {{max}}.", + "shocker_model": "Model", + "shocker_select_model": "Select model", + "shocker_name_placeholder": "Shocker name", + "shocker_menu_view_logs": "View Logs", + "shocker_delete_title": "Delete Shocker", + "shocker_delete_desc": "Are you sure you want to delete \"{{name}}\"? This action cannot be undone.", + "shocker_toast_deleted": "Shocker \"{{name}}\" deleted", + "shocker_toast_paused": "Shocker paused", + "shocker_toast_resumed": "Shocker resumed", + "shocker_add_desc": "Register a new shocker to one of your hubs.", + "shocker_add_name_placeholder": "My Shocker", + "shockers_title": "Shockers", + "shockers_subtitle": "Every shocker paired to your hubs.", + "shockers_loading": "Loading shockers...", + "shockers_toast_refreshed": "Shockers refreshed", + "shockers_toast_need_hub": "You need to create a hub before adding shockers.", + "shockers_toast_added": "Shocker added", + "shockers_unknown_module": "Unknown module type", + "shockers_add": "Add Shocker", + "shockers_view_mode": "View mode", + "shockers_mode_classic": "Classic", + "shockers_mode_rich": "Rich", + "shockers_mode_simple": "Simple", + "shockers_mode_map": "Map", + "shockers_group_by_hub": "Group by Hub", + "shockers_global_limits": "Global Limits", + "shockers_logs_label": "Logs", + "shockers_empty_title": "No shockers yet", + "shockers_empty_no_hubs": "Create a hub first, then add shockers to it.", + "shockers_empty_has_hubs": "Add a shocker to one of your hubs to get started.", + "shockers_create_hub": "Create a Hub", + "shockers_count_one": "{{count}} shocker", + "shockers_count_other": "{{count}} shockers", + "shared_shockers_title": "Shared Shockers", + "shared_shockers_subtitle": "Shockers other users have shared with you.", + "shared_shockers_empty_title": "No shockers have been shared with you yet.", + "shared_shockers_empty_desc": "When someone shares their shockers with you, they'll appear here.", + "shocker_logs_title": "Shocker Logs", + "shocker_logs_subtitle": "Every control command sent to your shockers.", + "shocker_logs_live_title": "New logs appear in real time", + "shocker_logs_paused_title": "Live updates pause when sorting or viewing a page other than the first", + "shocker_logs_live": "Live", + "shocker_logs_col_time": "Time", + "shocker_logs_col_type": "Type", + "shocker_logs_col_by": "By", + "shocker_logs_filter_label": "Filter by shocker", + "shocker_logs_filter_placeholder": "Search shockers...", + "shocker_logs_filter_all": "All shockers", + "shocker_logs_filter_none": "No matching shockers", + "shocker_edit_title": "Edit Shocker", + "shocker_edit_subtitle": "Change this shocker's details or remove it.", + "shocker_edit_back": "Back to Shockers", + "shocker_edit_load_failed": "Failed to load shocker.", + "shocker_edit_loading": "Loading shocker...", + "shocker_edit_details_title": "Shocker Details", + "shocker_edit_details_desc": "Update the name, RF ID, and model for this shocker.", + "shocker_edit_pause_state": "Pause State", + "shocker_edit_is_paused": "Shocker is paused", + "shocker_edit_is_active": "Shocker is active", + "shocker_edit_toast_updated": "Shocker updated", + "shocker_edit_delete_desc": "Permanently delete this shocker. This action cannot be undone.", + "common_close": "Close", + "common_continue": "Continue", + "common_loading": "Loading...", + "common_previous": "Previous", + "common_next": "Next", + "common_steps": "Steps", + "common_step_label": "Step {{number}}: {{title}}", + "common_copy": "Copy", + "common_copied": "Copied", + "common_never": "Never", + "common_error": "Error: {{message}}", + "terminal_title": "Serial Terminal", + "terminal_connecting": "Connecting...", + "terminal_help_button": "I'm having trouble, help?", + "terminal_back_to_modes": "Back to mode picker", + "terminal_mode_configure": "Configure Device", + "terminal_mode_configure_desc": "Configure WiFi, authentication, and more. Includes an interactive serial console.", + "terminal_mode_flash": "Flash Firmware", + "terminal_mode_flash_desc": "Install or update firmware on a connected device.", + "terminal_mode_raw": "Serial Monitor", + "terminal_mode_raw_desc": "Just the console. Read device logs and send commands.", + "terminal_step_channel": "Select Channel", + "terminal_step_board": "Select Board", + "terminal_go_to_step": "Go to step {{number}}: {{title}}", + "terminal_erase": "Erase before flashing", + "terminal_erase_desc": "Clears all data on the device including existing configs", + "terminal_unsupported": "Your browser does not support this feature.", + "terminal_update_browser": "Please update your browser to the latest version.", + "terminal_use_browsers": "Please use one of the following browsers:", + "terminal_connect_failed_bootloader": "Could not enter bootloader mode", + "terminal_connect_failed": "Device connection failed", + "terminal_connect_failed_desc": "We couldn't establish a serial connection with the device.", + "terminal_quick_tries": "Quick things to try:", + "terminal_try_replug": "Unplug and replug the device.", + "terminal_try_cable": "Try a different USB cable or port.", + "terminal_try_driver": "Make sure the serial driver is installed.", + "terminal_open_troubleshooter": "Open troubleshooter", + "terminal_log_reset_no_device": "Host-side error during reset: no device!", + "terminal_log_reset_error": "Host-side error during reset: {{error}}", + "terminal_log_send_no_device": "Couldn't send: no device!", + "terminal_log_send_error": "Couldn't send: {{error}}", + "terminal_log_firmware_disconnected": "Firmware disconnected: {{error}}", + "terminal_log_erase_failed": "Failed to erase flash: {{error}}", + "terminal_log_hard_reset_failed": "Failed to hard reset: {{error}}", + "terminal_log_flash_complete": "Flash complete", + "terminal_log_flash_failed": "Failed to flash: {{error}}", + "terminal_log_command_failed": "Failed to write application command: {{error}}", + "terminal_help_title": "Troubleshooter", + "terminal_help_desc": "Work through these steps in order. Each one rules out a common cause.", + "terminal_help_step_cable": "USB cable", + "terminal_help_step_port": "USB port", + "terminal_help_step_driver": "Install driver", + "terminal_help_step_manual": "Manual driver update", + "terminal_help_step_discord": "Ask on Discord", + "terminal_help_cable_body": "Many USB-C and micro-USB cables are charge-only and don't carry data. Swap to a known-good data cable (one you've used to transfer files or connect other devices) and reconnect the hub.", + "terminal_help_port_body": "Plug the device directly into a USB port on your computer. Avoid USB hubs, docking stations, and front-panel ports if possible; these are common sources of power and signal issues. If you're on a desktop, try a port on the back of the machine.", + "terminal_help_driver_download": "Download the CP210x driver:", + "terminal_help_driver_extract": "Extract the contents of the zip file to a folder on your computer.", + "terminal_help_driver_run": "Open the folder and run {{installer}}. Follow the prompts to install.", + "terminal_help_driver_reconnect": "Reconnect the device.", + "terminal_help_manual_intro": "If the driver installer ran but the device still doesn't show up:", + "terminal_help_manual_open": "Open Device Manager (press Win + X and select Device Manager).", + "terminal_help_manual_ports": "Under Ports (COM & LPT), look for an entry like:", + "terminal_help_manual_missing": "If it's missing, the device isn't being detected by Windows at all; revisit the cable and port steps.", + "terminal_help_manual_update": "Right-click the device and pick Update Driver.", + "terminal_help_manual_browse": "Choose Browse my computer for drivers and select the folder you extracted the driver zip into. Make sure Include subfolders is checked.", + "terminal_help_manual_success": "On success, the entry should now read {{deviceName}}.", + "terminal_help_discord_intro": "Still stuck after all of the above? Hop into our Discord server and ask in the {{channel}} channel. Please include:", + "terminal_help_discord_os": "your operating system and browser", + "terminal_help_discord_device": "the device you're using (board model, where you got it)", + "terminal_help_discord_tried": "what you've already tried from the previous steps", + "terminal_help_discord_errors": "any error messages or relevant terminal output", + "terminal_help_discord_join": "Join our Discord server", + "terminal_risk_title": "⚠️ UNSTABLE FIRMWARE", + "terminal_risk_intro": "You are about to flash experimental firmware that is known to be unstable.", + "terminal_risk_brick": "This may permanently brick your device, require manual recovery, or render it unusable.", + "terminal_risk_no_support": "We will NOT provide support for issues caused by this firmware.", + "terminal_risk_acknowledge": "I understand this is entirely my responsibility", + "terminal_risk_abort": "Abort", + "terminal_risk_accept": "I ACCEPT FULL RESPONSIBILITY", + "firmware_channel_recommended": "This is the recommended channel.", + "firmware_channel_danger": "DO NOT USE THIS UNLESS YOU KNOW WHAT YOU ARE DOING", + "firmware_channel_stable": "Stable", + "firmware_channel_beta": "Beta", + "firmware_channel_develop": "Develop", + "terminal_board_select": "Select a board...", + "terminal_board_search": "Search boards...", + "terminal_board_none": "No board found.", + "terminal_flash_button": "Flash", + "terminal_flash_progress": "Flash Progress: {{status}}", + "terminal_flash_idle": "Idle", + "terminal_flash_no_device": "No device selected.", + "terminal_flash_resetting": "Resetting...", + "terminal_flash_downloading": "Downloading firmware...", + "terminal_flash_download_failed": "Failed to download firmware.", + "terminal_flash_flashing": "Flashing firmware...", + "terminal_flash_rebooting": "Rebooting device... (Reconnect to power manually if stuck)", + "terminal_flash_done": "Rebooted device! Flashing complete.", + "terminal_port_select": "Select Device", + "terminal_port_disconnect": "Disconnect Device", + "terminal_port_connected": "Device connected: {{id}}", + "terminal_console": "Console", + "terminal_connected_device": "Connected device", + "terminal_resize": "Resize terminal panel", + "terminal_reboot": "Reboot", + "terminal_disconnect": "Disconnect", + "terminal_fullscreen_exit_esc": "Exit fullscreen (Esc)", + "terminal_fullscreen_exit": "Exit fullscreen", + "terminal_fullscreen_fill": "Fill the window", + "terminal_command_label": "Serial command", + "terminal_command_placeholder": "Type a command...", + "terminal_command_send": "Send command", + "terminal_colors": "Colors", + "terminal_colors_menu": "Colors...", + "terminal_colors_label": "Console colors", + "terminal_colors_close": "Close colors", + "terminal_color_input": "{{name}} color", + "terminal_colors_reset": "Reset to defaults", + "terminal_color_bg": "Background", + "terminal_color_fg": "Text", + "terminal_color_ts": "Timestamp", + "terminal_color_error": "Error", + "terminal_color_warning": "Warning", + "terminal_color_info": "Info", + "terminal_color_debug": "Debug", + "terminal_color_verbose": "Verbose", + "terminal_options": "Options", + "terminal_options_label": "Console options", + "terminal_hide_system": "Hide system messages", + "terminal_stick_bottom": "Stick to bottom", + "terminal_raw_output": "Raw output", + "terminal_timestamps": "Timestamps", + "terminal_timestamp_uptime": "Uptime", + "terminal_timestamp_local": "Local", + "terminal_timestamp_ms": "Ms", + "terminal_timestamp_off": "Off", + "terminal_copy_settings": "Copy settings", + "terminal_import_settings": "Import settings", + "terminal_copy_selection": "Copy selection", + "terminal_copy_all": "Copy all output", + "terminal_toast_selection_copied": "Selection copied", + "terminal_toast_output_copied": "Console output copied", + "terminal_toast_settings_copied": "Console settings copied", + "terminal_toast_clipboard_unreadable": "Could not read the clipboard", + "terminal_toast_settings_imported": "Console settings imported", + "terminal_toast_settings_invalid": "Clipboard does not contain console settings", + "common_try_again": "Try again", + "terminal_cfg_intro": "Values are sent to the device via UART. Read the device's response in the console below. Commands without an argument act as getters; use the button next to each field to read the current value.", + "terminal_cfg_rf_title": "RF Transmitter", + "terminal_cfg_rf_desc": "Controls the shocker RF output.", + "terminal_cfg_tx_pin": "TX GPIO pin", + "terminal_cfg_example": "e.g. {{value}}", + "terminal_cfg_read_value": "Read current value", + "terminal_cfg_set": "Set", + "terminal_cfg_read": "Read", + "terminal_cfg_reading": "Reading…", + "terminal_cfg_apply": "Apply", + "terminal_cfg_keepalive": "Keepalive enabled", + "terminal_cfg_keepalive_desc": "Periodically pings paired shockers to keep them awake.", + "terminal_cfg_estop_title": "Emergency Stop", + "terminal_cfg_estop_desc": "Hardware button that halts all output.", + "terminal_cfg_estop_enabled": "EStop enabled", + "terminal_cfg_estop_pin": "EStop GPIO pin", + "terminal_cfg_estop_note": "Note: {{latching}} and {{active}} have no dedicated commands; set them via the JSON config below.", + "terminal_cfg_wifi_title": "WiFi", + "terminal_cfg_wifi_desc": "Station credentials and device hostname.", + "terminal_cfg_hostname": "Hostname", + "terminal_cfg_networks": "Networks (JSON array)", + "terminal_cfg_invalid_json_array": "Must be a valid JSON array", + "terminal_cfg_ap_note": "AP settings ({{ssid}}, {{password}}, {{disabled}}, {{staDisabled}}, {{offlineMode}}) have no dedicated commands; use the JSON config.", + "terminal_cfg_backend_title": "Backend", + "terminal_cfg_backend_desc": "OpenShock server and authentication.", + "terminal_cfg_domain": "Domain", + "terminal_cfg_domain_restart": "Setting the domain will restart the device.", + "terminal_cfg_auth_token": "Auth token", + "terminal_cfg_auth_token_placeholder": "Paste device token", + "terminal_cfg_hide": "Hide", + "terminal_cfg_show": "Show", + "terminal_cfg_serial_title": "Serial Input", + "terminal_cfg_echo": "Echo enabled", + "terminal_cfg_echo_desc": "Print typed characters back to the console.", + "terminal_cfg_advanced_title": "Advanced: full config", + "terminal_cfg_advanced_desc": "For fields without dedicated commands (captive portal, OTA, LAN, etc.), replace the entire config.", + "terminal_cfg_json_config": "JSON config", + "terminal_cfg_invalid_json": "Must be valid JSON", + "terminal_cfg_read_json": "Read current config as JSON", + "terminal_cfg_json_restart": "Applying a JSON config will restart the device.", + "terminal_cfg_raw_config": "Raw FlatBuffer config (base64)", + "terminal_cfg_invalid_base64": "Must be a valid base64 string", + "terminal_cfg_read_raw": "Read current config as base64", + "terminal_cfg_factory_reset": "Factory reset", + "terminal_cfg_factory_reset_desc": "Wipes the entire device configuration.", + "terminal_cfg_factory_reset_title": "Factory reset device?", + "terminal_cfg_factory_reset_action": "Wipe config", + "terminal_cfg_factory_reset_confirm": "This will erase all configuration on the device; WiFi networks, backend credentials, pins, and all other settings. The device will be reset to defaults.", + "terminal_cfg_read_failed_json_title": "Couldn't read the JSON config", + "terminal_cfg_read_failed_raw_title": "Couldn't read the raw config", + "terminal_cfg_read_failed_desc": "The device didn't respond after {{attempts}} attempts.", + "terminal_cfg_common_causes": "Common causes:", + "terminal_cfg_cause_busy": "The device is busy handling another command.", + "terminal_cfg_cause_disconnected": "The device disconnected or rebooted.", + "terminal_cfg_cause_unsupported": "The firmware version doesn't support this command.", + "common_status": "Status", + "common_version": "Version", + "common_created": "Created", + "common_create": "Create", + "common_done": "Done", + "common_enable": "Enable", + "common_disable": "Disable", + "common_are_you_sure": "Are you sure?", + "common_generating": "Generating...", + "hubs_title": "Hubs", + "hubs_subtitle": "Every hub registered to your account.", + "hubs_add": "Add Hub", + "hubs_load_failed": "Failed to load hubs.", + "hubs_empty_title": "No hubs yet", + "hubs_empty_desc": "A hub is the device that relays commands to your shockers. Add one to get started.", + "hubs_create_title": "Create hub", + "hubs_name_label": "Hub Name", + "hubs_name_placeholder": "My Hub", + "hub_toast_not_connected": "Not connected to the server", + "hub_toast_try_later": "Try again in a moment.", + "hub_reboot_title": "Reboot {{name}}?", + "hub_reboot_desc": "The hub will disconnect and restart. Any shockers paired to it stop responding until it comes back online.", + "hub_reboot": "Reboot", + "hub_hotspot_enable_title": "Enable Wi-Fi hotspot on {{name}}?", + "hub_hotspot_disable_title": "Disable Wi-Fi hotspot on {{name}}?", + "hub_hotspot_enable_desc": "The hub broadcasts its own setup network. It stays reachable on your Wi-Fi, but the hotspot is open to anyone in range until you turn it off.", + "hub_hotspot_disable_desc": "The setup hotspot shuts down. If the hub is not already on your Wi-Fi you will need physical access to set it up again.", + "hub_delete_desc": "You are about to delete hub {{name}}.", + "hub_delete_shockers": "This will also delete the following shockers:", + "hub_edit_title": "Edit hub", + "hub_edit_apply": "Apply", + "hub_pair_title_generate": "Generate pair code?", + "hub_pair_title_generated": "Pair code generated", + "hub_pair_title_paired": "Hub paired", + "hub_pair_consumed": "{{name}} consumed this pair code and is now paired.", + "hub_pair_used": "The code has been used and is no longer valid.", + "hub_pair_generated_for": "Pair code generated for {{name}}.", + "hub_copy_now": "The code below will not be accessible later, please copy it now and update clients with it.", + "hub_pair_generate_for": "You are about to generate a pair code for {{name}}.", + "hub_pair_valid_for": "It will be valid for 15 minutes after its creation.", + "hub_pair_one_active": "There is only one active pair code per hub, newly generated ones will override the older active ones.", + "hub_pair_complete": "Pairing complete", + "hub_pair_code_label": "Pair code:", + "hub_pair_copied_close": "Code has been copied, close", + "hub_pair_get": "Get Pair Code", + "hub_token_generated": "Token generated", + "hub_token_generated_for": "New token generated for {{name}}.", + "hub_token_regenerate_for": "You are about to regenerate the token for {{name}}.", + "hub_token_invalidate": "This action will invalidate the current token and disconnect clients using it.", + "hub_token_confirm": "Are you sure you want to do this?", + "hub_token_label": "New token:", + "hub_token_copied_close": "Token has been copied, close", + "hub_token_regenerate": "Regenerate Token", + "hub_menu_update": "Update", + "hub_menu_label": "Hub", + "hub_menu_hotspot_enable": "Enable Wi-Fi hotspot", + "hub_menu_hotspot_disable": "Disable Wi-Fi hotspot", + "hub_menu_pair": "Pair", + "hub_menu_estop": "Emergency Stop", + "hub_update_breadcrumb": "Update", + "hub_update_unknown_hub": "Unknown Hub", + "hub_update_unknown_task": "Unknown Task", + "hub_update_task_metadata": "Fetching Metadata", + "hub_update_task_preparing": "Preparing for Update", + "hub_update_task_flash_fs": "Flashing Filesystem", + "hub_update_task_verify_fs": "Verifying Filesystem", + "hub_update_task_flash_app": "Flashing Application", + "hub_update_task_bootable": "Marking Application Bootable", + "hub_update_task_rebooting": "Rebooting", + "hub_update_status_started": "Started", + "hub_update_status_running": "Running", + "hub_update_status_finished": "Finished", + "hub_update_status_error": "Error", + "hub_update_status_timeout": "Timeout", + "hub_update_confirm_title": "Confirm firmware update", + "hub_update_confirm_desc": "Update {{name}} to version {{version}}?", + "hub_update_unstable_warning": "This version may not be from the stable channel and could contain bugs.", + "hub_update_title": "Update {{name}}", + "hub_update_subtitle": "Manage firmware updates for this hub.", + "hub_update_status_title": "Hub Status", + "hub_update_firmware": "Firmware: {{version}}", + "hub_update_confirm": "Update", + "hub_update_success": "Update completed successfully", + "hub_update_rolled_back": "Device rolled back to previous version", + "hub_update_back": "Back to Hubs", + "hub_update_flash_again": "Flash Again", + "hub_update_card_title": "Firmware Update", + "hub_update_card_desc": "Select a firmware channel and version to install.", + "hub_update_to": "Update to {{version}}", + "hub_update_must_be_online": "Hub must be online to start an update.", + "hub_update_updating_to": "Updating to {{version}}...", + "hub_update_total": "Total", + "hub_update_task": "Task", + "hub_update_history": "Update History", + "hub_update_no_history": "No update history found for this hub.", + "hub_update_col_id": "ID", + "hub_update_col_started": "Started", + "hub_update_col_message": "Message", + "hub_update_loading": "Loading hub information...", + "hub_update_not_found": "Hub not found.", + "home_breadcrumb": "Home", + "home_welcome": "Welcome back", + "home_welcome_name": "Welcome back, {{name}}", + "home_subtitle": "Here's an overview of your OpenShock setup.", + "home_hubs_online": "{{count}} online", + "home_hub_status": "Hub Status", + "home_no_hubs": "No hubs", + "home_all_online": "All online", + "home_all_offline": "All offline", + "home_some_online": "{{online}}/{{total}} online", + "home_quick_links": "Quick Links", + "home_my_shockers": "My Shockers", + "home_my_shockers_desc": "Control your shockers", + "home_hubs_desc": "Manage your hubs", + "home_shared_desc": "Shockers shared with you", + "home_public_desc": "Manage share links", + "home_get_started": "Get Started", + "home_get_started_desc": "You don't have any hubs yet. Create a hub to connect your first device, then add shockers to it.", + "home_set_up_hub": "Set Up a Hub", + "home_first_shocker": "Add Your First Shocker", + "home_first_shocker_desc_one": "You have {{count}} hub set up. Add a shocker to start controlling it.", + "home_first_shocker_desc_other": "You have {{count}} hubs set up. Add a shocker to start controlling it.", + "home_go_to_shockers": "Go to Shockers", + "profile_title": "Profile", + "profile_coming_soon": "Profile is coming soon", + "profile_coming_soon_desc": "Your public profile is not available yet. Account details live under Settings.", + "common_retry": "Retry", + "common_never_used": "Never used", + "common_expires": "Expires {{time}}", + "common_search_placeholder": "Search...", + "common_unknown": "Unknown", + "settings_breadcrumb_account": "Account", + "account_subtitle": "Your sign-in details and account actions.", + "account_change_username": "Change Username", + "account_change_email": "Change Email", + "account_change_password": "Change Password", + "account_username_label": "Username", + "account_email_label": "Email", + "account_password_label": "Password", + "account_new_password_label": "New Password", + "account_confirm_password_label": "Confirm New Password", + "account_oauth_only": "Not available for OAuth-only accounts", + "account_oauth_no_password": "This account signs in via OAuth and has no password.", + "account_diagnostics": "Diagnostics", + "account_diagnostics_desc": "Help us fix crashes and slow API calls. Reports include the error message, stack trace and your IP. Off by default.", + "account_diagnostics_level": "Diagnostics level", + "account_telemetry_off": "Off", + "account_telemetry_off_desc": "Send nothing.", + "account_telemetry_errors": "Errors", + "account_telemetry_errors_desc": "Send browser error reports only.", + "account_telemetry_full": "Full", + "account_telemetry_full_desc": "Error reports plus traces of API calls (no page navigations).", + "account_toast_deactivated": "Account deactivated successfully", + "account_deactivate_title": "Deactivate account", + "account_deactivate_desc": "Are you sure you want to deactivate your account?", + "account_deactivate": "Deactivate Account", + "account_email_title": "Change email", + "account_email_desc": "Enter your new email address and confirm with your current password.", + "account_email_toast_sent": "Verification email sent to {{email}}. Click the link in that email to apply the change.", + "account_new_email": "New Email", + "account_current_password": "Current Password", + "account_password_title": "Change password", + "account_password_desc": "Enter your current password and choose a new one.", + "account_password_toast": "Password has been changed", + "account_username_title": "Change username", + "account_username_desc": "Enter a new username.", + "account_new_username": "New Username", + "account_username_toast": "Username changed successfully", + "tokens_subtitle": "API Tokens are used to authenticate with the OpenShock API.", + "tokens_generate": "Generate Token", + "tokens_toast_refreshed": "Tokens refreshed successfully", + "tokens_empty_title": "No API tokens", + "tokens_empty_desc": "Generate a token to authenticate with the OpenShock API.", + "tokens_created_on": "Created {{date}}", + "tokens_last_used": "Last used {{time}}", + "tokens_never_expires": "Never expires", + "tokens_load_failed": "Failed to load API tokens.", + "token_toast_edited": "Token edited successfully", + "token_name_required": "Name is required", + "token_name_too_long": "Name is too long", + "token_edit_title": "Edit API token", + "token_name_label": "Token Name", + "token_name_placeholder": "Token name...", + "token_permissions": "Permissions", + "token_perm_category_shockers": "Shockers", + "token_perm_category_devices": "Hubs", + "token_perm_category_usershares": "User Shares", + "token_perm_category_publicshares": "Public Shares", + "token_perm_use": "Use", + "token_perm_edit": "Edit", + "token_perm_pause": "Pause", + "token_perm_auth": "Authenticate", + "token_shocker_control": "Shocker Control", + "token_toast_paused": "Token paused", + "token_toast_resumed": "Token resumed", + "token_delete_title": "Delete API token", + "token_delete_desc": "Are you sure you want to delete {{name}}?", + "token_delete_permanent": "This action cannot be undone. This will permanently delete the token.", + "token_toast_deleted": "Token deleted successfully", + "token_resume": "Resume token", + "token_pause": "Pause token", + "token_mode_clamp_desc": "Clamp: requests outside the allowed range are capped to the nearest limit (the min or the max).", + "token_mode_lerp_desc": "Lerp: the full input range is linearly rescaled so it fits within your allowed min–max range.", + "token_paused_desc": "A paused token may not send shocker control messages.", + "token_intensity_range": "Intensity range", + "token_duration_range": "Duration range", + "token_new_breadcrumb": "New", + "token_redirect_not_allowed": "The provided redirect_uri is not allowed. Only loopback addresses or custom application schemes are permitted.", + "token_params_missing": "Required get parameters are missing. Make sure name, redirect_uri, and permissions are provided.", + "token_invalid_permissions": "Invalid permissions provided: {{list}}", + "token_toast_created": "Token created successfully", + "token_request_title": "API Token Request", + "token_access_granted": "Access granted", + "token_shared_redirecting": "The token has been created and shared with the application. Redirecting you back to {{uri}}.", + "token_not_redirected": "If you are not redirected automatically, use the button below.", + "token_finish": "Finish", + "token_generated_title": "API Token Generated", + "token_copy_now": "Please copy your API Token now, you will not be able to view it again later!", + "token_new_title": "New API Token", + "token_external_desc": "An external application is requesting access to your account. Review and adjust the permissions below before allowing access.", + "token_new_desc": "Configure and generate a new API token for your account.", + "token_external_requesting": "{{name}} is requesting an API Token. Your token will be shared with the application at {{uri}}.", + "token_allow": "Allow", + "token_generate": "Generate", + "token_deny": "Deny", + "sessions_subtitle": "Every active session on your account. Revoke any you do not recognize.", + "sessions_unknown_device": "Unknown device", + "sessions_toast_refreshed": "Sessions refreshed successfully", + "sessions_load_failed": "Failed to load sessions.", + "sessions_empty_title": "No active sessions", + "sessions_empty_desc": "Sessions appear here once you sign in from a browser or app.", + "sessions_last_seen": "Last seen {{time}}", + "sessions_signed_in": "Signed in {{time}}", + "session_toast_revoked": "Session revoked successfully", + "session_revoke_title": "Revoke session", + "session_revoke": "Revoke", + "session_revoke_desc": "Are you sure you want to revoke this session?", + "session_revoke_from": "Session logged in from {{ip}} using {{agent}}", + "connections_title": "OAuth Connections", + "connections_subtitle": "Link or unlink third-party accounts to sign in faster and keep your profile in sync.", + "connections_toast_linked": "Account linked.", + "connections_toast_cancelled": "Link flow cancelled.", + "connections_toast_failed": "Linking failed.", + "connections_toast_removed": "Connection removed", + "connections_refreshing": "Refreshing…", + "connections_link_new": "Link new provider", + "connections_empty_title": "No connections yet", + "connections_empty_desc": "Choose “Link new provider” above to connect available providers.", + "connections_unlink": "Unlink", + "connections_load_failed": "Failed to load OAuth connections.", + "connections_unlink_title": "Unlink {{name}}?", + "connections_unlink_title_generic": "Unlink this account?", + "connections_unlink_desc": "You'll no longer be able to sign in with this provider unless you link it again.", + "provider_starting": "Starting {{name}}...", + "provider_link": "Link {{name}}", + "audit_subtitle": "Security-relevant activity on your account. Review anything you do not recognize.", + "audit_col_time": "Time", + "audit_col_action": "Action", + "audit_col_details": "Details", + "audit_col_reason": "Reason", + "audit_col_ip": "IP address", + "audit_col_device": "Device", + "audit_action_login": "Signed in", + "audit_action_logout": "Signed out", + "audit_action_password_changed": "Password changed", + "audit_action_email_change_requested": "Email change requested", + "audit_action_email_changed": "Email changed", + "audit_action_username_changed": "Username changed", + "audit_action_api_token_created": "API token created", + "audit_action_api_token_deleted": "API token deleted", + "audit_action_oauth_connected": "Connection added", + "audit_action_oauth_disconnected": "Connection removed", + "audit_action_account_deactivated": "Account deactivated", + "audit_action_account_reactivated": "Account reactivated", + "audit_action_account_deleted": "Account deleted", + "audit_action_automation_token_created": "Automation token created", + "audit_action_automation_token_updated": "Automation token updated", + "audit_action_automation_token_rotated": "Automation token rotated", + "audit_action_automation_token_deleted": "Automation token deleted", + "audit_action_automation_token_used": "Automation token used", + "audit_meta_session": "Session {{id}}", + "audit_meta_changed": "{{old}} to {{new}}", + "audit_meta_email_requested": "Requested change to {{email}}", + "audit_meta_accounts_removed_one": "{{name}} ({{count}} account removed)", + "audit_meta_accounts_removed_other": "{{name}} ({{count}} accounts removed)", + "audit_meta_scheduled_deletion": "Scheduled for deletion", + "audit_meta_kept": "Kept for reactivation", + "common_view": "View", + "common_save": "Save", + "common_saving": "Saving...", + "common_back": "Back", + "common_shared_by": "Shared by", + "common_user_avatar": "User Avatar", + "common_toast_saved": "Changes saved successfully", + "pause_reason_shocker": "Paused at shocker level", + "pause_reason_shocker_user_share": "Paused at shocker and user share level", + "pause_reason_shocker_public_share": "Paused at shocker and public share level", + "pause_reason_user_share": "Paused at user share level", + "pause_reason_public_share": "Paused at public share level", + "public_shares_subtitle": "A link anyone can use, no account required.", + "public_shares_new": "New Share", + "public_share_never_expires": "Never expires", + "public_shares_empty_title": "No public shares yet", + "public_shares_empty_desc": "Create a link that anyone can use to control your shockers.", + "public_share_expired": "Expired", + "public_share_no_expiry": "No expiry", + "public_share_label": "Public Share", + "public_share_toast_created": "Created new public share", + "public_share_create_title": "Create public share", + "public_share_toast_deleted": "Deleted public share", + "public_share_delete_title": "Delete public share", + "public_share_delete_desc": "Are you sure you want to delete public share {{name}}?", + "public_share_edit_title": "Public Share: {{name}}", + "public_share_edit_subtitle": "Editing: changes apply when you save.", + "public_share_add_shocker": "Add Shocker", + "public_share_toast_added_one": "Added {{count}} shocker to share", + "public_share_toast_added_other": "Added {{count}} shockers to share", + "public_share_empty_shockers_title": "No shockers in this share", + "public_share_empty_shockers_desc": "Add a shocker and anyone with the link will be able to control it.", + "public_share_load_failed": "Error fetching public share details", + "public_share_paused_here": "Paused for this share", + "public_share_resume_shocker": "Resume shocker", + "public_share_pause_shocker": "Pause shocker", + "public_share_remove": "Remove from share", + "public_share_toast_removed": "Shocker removed from share", + "public_share_add_title": "Add shockers", + "public_share_add_desc": "Add shockers to this public share. You can set their limits once they are added.", + "public_share_add_placeholder": "Select shockers to share...", + "public_share_add_no_match": "No matching shockers", + "public_share_add_submit": "Add Shockers", + "public_share_view_loading": "Loading share details...", + "public_share_view_title": "Public Share Link", + "public_share_view_desc": "Enter as a guest or login with your OpenShock account", + "public_share_view_guest_name": "Guest Name", + "public_share_view_enter": "Enter", + "public_share_view_enter_guest": "Enter as Guest", + "public_share_login": "Login", + "perm_shock_on": "Shock enabled", + "perm_shock_off": "Shock disabled", + "perm_vibrate_on": "Vibrate enabled", + "perm_vibrate_off": "Vibrate disabled", + "perm_sound_on": "Sound enabled", + "perm_sound_off": "Sound disabled", + "perm_live_on": "Live enabled", + "perm_live_off": "Live disabled", + "perm_live_control": "Live Control", + "user_selector_avatar_of": "{{name}}'s avatar", + "user_selector_placeholder": "Enter user name", + "user_selector_aria": "Username to search", + "user_selector_search": "Search user", + "user_selector_found": "User found", + "common_remove": "Remove", + "user_shares_subtitle": "Direct permanent shares with other users.", + "user_shares_toast_invited": "Sent a shocker invite to {{name}}", + "user_shares_redeem": "Redeem Code", + "user_shares_new": "New Share", + "user_shares_tab_shares": "Shares", + "user_shares_tab_incoming": "Shared with Me", + "user_shares_tab_invites": "Invites", + "share_code_create_title": "New share code", + "share_code_create_desc": "Create a Share Code or Invite", + "share_code_shocker_placeholder": "Select shockers to share...", + "share_code_no_match": "No matching shockers", + "share_code_send_invite": "Send Share Invite", + "share_code_create": "Create Share Code", + "share_code_created_title": "Share code generated", + "share_code_created_desc": "Please copy share code or code link!", + "share_code_redeem_title": "Redeem share code", + "share_code_redeem_desc": "Enter the share code to redeem", + "share_code_redeem_placeholder": "Enter share code", + "share_code_redeemed": "Redeemed successfully!", + "share_code_shared_shockers": "Shared shockers", + "share_code_redeeming": "Redeeming...", + "share_code_redeem": "Redeem", + "incoming_shares_empty_title": "Nothing shared with you", + "incoming_shares_empty_desc": "No one has shared a shocker with you yet.", + "incoming_share_toast_removed": "Removed share for {{name}}", + "incoming_share_remove_title": "Remove Share", + "incoming_share_remove_desc": "Are you sure you want to remove the share for {{name}}?", + "incoming_share_toast_removed_shocker": "Removed {{shocker}} shared by {{name}}", + "incoming_share_remove_shocker_title": "Remove this shared shocker?", + "incoming_share_remove_shocker_desc": "Are you sure you want to remove the shocker share {{shocker}} by {{name}}?", + "incoming_share_manage_from": "Manage shares from", + "share_remove": "Remove share", + "invites_empty_title": "No invites yet", + "invites_empty_desc": "You have no incoming or outgoing share invites.", + "invites_outgoing": "Outgoing", + "invites_outgoing_empty_title": "No outgoing invites", + "invites_outgoing_empty_desc": "You have no outgoing share invites.", + "invites_incoming": "Incoming", + "invites_incoming_empty_title": "No incoming invites", + "invites_incoming_empty_desc": "You have no incoming share invites.", + "invite_toast_accepted": "Accepted share invite from {{name}}", + "invite_toast_declined": "Declined share invite from {{name}}", + "invite_deny_title": "Deny Invite", + "invite_deny_label": "Deny Invite", + "invite_deny": "Deny", + "invite_deny_desc": "Are you sure you want to deny the invite from {{name}}?", + "invite_accept": "Accept Invite", + "invite_toast_cancelled_for": "Cancelled invite for {{name}} ({{id}})", + "invite_toast_cancelled": "Cancelled invite {{id}}", + "invite_cancel_title": "Cancel Invite", + "invite_cancel": "Cancel", + "invite_cancel_for_desc": "Are you sure you want to cancel the invite for {{name}}?", + "invite_cancel_code_desc": "Are you sure you want to cancel the invite with code {{code}}?", + "invite_cancel_outstanding": "Cancel Outstanding Invite", + "outgoing_shares_empty_title": "No shared shockers", + "outgoing_shares_empty_desc": "You haven't shared any shockers with other users yet.", + "outgoing_share_toast_removed": "Removed shocker share {{name}}", + "outgoing_share_remove_title": "Stop sharing this shocker?", + "outgoing_share_editing_for": "Editing shares for", + "outgoing_share_limits": "Limits & Permissions", + "outgoing_share_same": "Same restrictions on every shocker", + "outgoing_share_per_desc": "Tune restrictions per shocker", + "outgoing_share_all": "All", + "outgoing_share_per": "Per shocker", + "outgoing_share_remove_desc": "Are you sure you want to stop sharing {{shocker}} with {{name}}?", + "report_breadcrumb": "Report API Tokens", + "report_toast_clipboard_failed": "Failed to read clipboard: {{error}}", + "report_title": "Report Leaked API Tokens", + "report_paste": "Paste from clipboard", + "report_warning": "This form is only for reporting accidentally leaked API tokens.", + "report_abuse_warning": "Intentional abuse will result in bans or severe endpoint restrictions.", + "report_detected": "Detected Tokens", + "report_invalid": "One or more tokens appear to be invalid. Please check for formatting issues.", + "report_acknowledge": "I confirm I understand what this feature is for and accept responsibility.", + "report_submit": "Submit Report", + "turnstile_disabled": "Turnstile disabled", + "common_internal_error": "Internal error", + "resend_toast_sent": "Activation email sent. Check your inbox and spam folder.", + "resend_toast_throttled": "Too many activation emails have been requested. Please try again later.", + "resend_toast_unavailable": "No activation email can be resent from this browser. If your account isn't activated yet, logging in sends a new link.", + "resend_button": "Didn't get the email? Resend", + "expiration_label": "Expiration", + "expiration_never": "Never", + "expiration_custom": "Custom", + "expiration_days_one": "{{count}} Day", + "expiration_days_other": "{{count}} Days", + "expiration_required": "Expire date is required", + "expiration_never_desc": "This will never expire", + "expiration_expires_at": "Expires {{time}} ({{date}})", + "date_picker_placeholder": "Pick a date", + "telemetry_toast_title": "Help improve OpenShock?", + "telemetry_toast_desc": "Send diagnostics to help us fix crashes and slow API calls. Reports include the error message, stack trace and your IP. You can change this any time in Account settings.", + "telemetry_toast_no": "No thanks", + "telemetry_toast_errors": "Errors only", + "telemetry_toast_full": "Full", + "table_show_details": "Show details", + "table_hide_details": "Hide details", + "table_no_results": "No results.", + "table_sort_asc": "Sort by {{name}}, ascending", + "table_sort_desc": "Sort by {{name}}, descending", + "table_sort_none": "Sort by {{name}}, unsorted", + "cell_na": "N/A", + "cell_not_applicable": "Not applicable", + "cell_invalid": "Invalid", + "cell_unavailable": "Unavailable", + "cell_none": "None", + "oauth_login_with": "Login with {{provider}}", + "oauth_signup_with": "Signup with {{provider}}", + "signalr_connect_failed": "Failed to connect to server!", + "signalr_disconnect_failed": "Encountered error while disconnecting from server!", + "signalr_invalid_update": "Received invalid update from server!", + "signalr_invalid_log": "Received invalid log data from server!", + "signalr_invalid_ota": "Received invalid firmware update data from server!", + "ota_toast_failed": "Hub firmware update failed: {{message}}", + "ota_toast_succeeded": "Hub firmware update completed successfully!", + "ota_toast_rolled_back": "Hub firmware rolled back to previous version", + "lcg_connect_failed": "Failed to connect to live control gateway", + "terminal_toast_bootloader_failed": "Failed to enter bootloader: {{error}}", + "terminal_toast_app_mode_failed": "Failed to enter application mode: {{error}}", + "problem_account_account_not_activated_title": "Account not activated", + "problem_account_account_not_activated_desc": "Check your inbox for the activation email.", + "problem_account_activation_not_found_title": "Activation link is invalid", + "problem_account_activation_not_found_desc": "The link may have expired or already been used.", + "problem_account_activation_resend_too_many_title": "Too many activation emails requested", + "problem_account_activation_resend_too_many_desc": "Please wait a while before trying again.", + "problem_account_activation_resend_unavailable_title": "Cannot resend activation email", + "problem_account_activation_resend_unavailable_desc": "Log in again to request a new activation link.", + "problem_account_deactivate_already_deactivated_title": "Account is already deactivated", + "problem_account_deactivate_denied_privileged_title": "Privileged accounts cannot be deactivated", + "problem_account_deactivate_unauthorized_title": "You are not allowed to do this", + "problem_account_deactivated_title": "This account has been deactivated", + "problem_account_email_already_in_use_title": "That email address is already in use", + "problem_account_email_invalid_title": "That email address is not valid", + "problem_account_email_taken_title": "That email address is already in use", + "problem_account_email_too_many_requests_title": "Too many email change requests", + "problem_account_email_too_many_requests_desc": "Please wait a while before trying again.", + "problem_account_email_unchanged_title": "That is already your email address", + "problem_account_email_verify_not_found_title": "Verification link is invalid", + "problem_account_email_verify_not_found_desc": "The link may have expired or already been used.", + "problem_account_o_auth_only_title": "This account has no password", + "problem_account_o_auth_only_desc": "Sign in with the provider you signed up with.", + "problem_account_password_not_set_title": "No password set", + "problem_account_password_not_set_desc": "This account signs in through an external provider.", + "problem_account_password_old_password_invalid_title": "Current password is incorrect", + "problem_account_username_invalid_title": "That username is not allowed", + "problem_account_username_recently_changed_title": "Username changed too recently", + "problem_account_username_recently_changed_desc": "You can change your username once every 7 days.", + "problem_account_username_taken_title": "That username is already taken", + "problem_admin_user_deactivated_title": "This user is deactivated", + "problem_admin_user_not_activated_title": "This user has not been activated yet", + "problem_api_token_can_only_delete_self_title": "An API token can only delete itself", + "problem_api_token_not_found_title": "API token not found", + "problem_api_token_paused_title": "This API token is paused", + "problem_assign_lcg_bad_schema_version_title": "Unsupported hub protocol version", + "problem_assign_lcg_bad_schema_version_desc": "Update the hub firmware to connect.", + "problem_assign_lcg_no_lcg_available_title": "No gateway available", + "problem_assign_lcg_no_lcg_available_desc": "No live control gateway is available right now. Please try again later.", + "problem_authentication_account_deactivated_title": "This account has been deactivated", + "problem_authentication_account_not_activated_title": "This account has not been activated", + "problem_authentication_cookie_missing_or_invalid_title": "You are not logged in", + "problem_authentication_cookie_missing_or_invalid_desc": "Your session may have expired. Please log in again.", + "problem_authentication_header_missing_or_invalid_title": "Invalid API token", + "problem_authentication_session_invalid_title": "Session expired", + "problem_authentication_session_invalid_desc": "Please log in again.", + "problem_authentication_token_invalid_title": "Invalid API token", + "problem_authentication_unknown_error_title": "Authentication failed", + "problem_authorization_policy_not_met_title": "You do not have permission to do this", + "problem_authorization_token_only_title": "This action requires an API token", + "problem_authorization_token_permission_missing_title": "This API token is missing a required permission", + "problem_authorization_unknown_error_title": "Authorization failed", + "problem_authorization_user_session_only_title": "This action requires a logged-in session", + "problem_automation_token_not_allowed_for_account_title": "Automation tokens cannot be used with privileged accounts", + "problem_configuration_already_exists_title": "A configuration entry with that name already exists", + "problem_configuration_invalid_name_format_title": "Invalid configuration name", + "problem_configuration_invalid_name_format_desc": "Only A to Z and underscores are allowed.", + "problem_configuration_invalid_value_format_title": "Value does not match the configuration type", + "problem_configuration_not_found_title": "Configuration entry not found", + "problem_control_stats_invalid_range_title": "The from date must not be after the to date", + "problem_control_stats_invalid_time_zone_title": "Unknown time zone", + "problem_control_stats_missing_capability_title": "Control statistics are not available on this server", + "problem_device_not_found_title": "Hub not found", + "problem_device_not_online_title": "Hub is offline", + "problem_device_too_many_hubs_title": "You have reached the maximum number of hubs", + "problem_device_too_many_shockers_title": "This hub has reached its maximum number of shockers", + "problem_endpoint_retired_title": "This feature is no longer available", + "problem_expression_error_title": "Invalid filter expression", + "problem_internal_server_error_title": "Something went wrong on our end", + "problem_login_invalid_credentials_title": "Invalid username or password", + "problem_login_invalid_domain_title": "Logging in from this address is not allowed", + "problem_o_auth_connection_already_exists_title": "Your account is already connected to this provider", + "problem_o_auth_connection_already_linked_title": "This external account is already linked to another user", + "problem_o_auth_flow_anonymous_only_title": "You are already signed in", + "problem_o_auth_flow_mismatch_title": "Sign-in attempt does not match", + "problem_o_auth_flow_mismatch_desc": "Please start over.", + "problem_o_auth_flow_missing_data_title": "The provider did not return your account details", + "problem_o_auth_flow_missing_data_desc": "Please try again.", + "problem_o_auth_flow_not_found_title": "Sign-in attempt expired", + "problem_o_auth_flow_not_found_desc": "Please start over.", + "problem_o_auth_flow_unsupported_title": "Unsupported sign-in flow", + "problem_o_auth_internal_error_title": "Something went wrong during sign-in", + "problem_o_auth_internal_error_desc": "Please try again in a moment.", + "problem_o_auth_link_authenticated_user_only_title": "You must be signed in to link an external account", + "problem_o_auth_provider_mismatch_title": "Sign-in attempt does not match the provider", + "problem_o_auth_provider_mismatch_desc": "Please start over.", + "problem_o_auth_provider_unsupported_title": "This sign-in provider is not supported", + "problem_pair_code_not_found_title": "Pair code not found", + "problem_password_reset_not_found_title": "Password reset link is invalid", + "problem_password_reset_not_found_desc": "The link may have expired or already been used.", + "problem_session_not_found_title": "Session not found", + "problem_share_get_no_shares_title": "You have no shares with this user", + "problem_share_request_create_cannot_share_with_self_title": "You cannot share with yourself", + "problem_share_request_create_shocker_not_found_title": "One or more shockers were not found", + "problem_share_request_create_shocker_not_found_desc": "They may have been removed or do not belong to you.", + "problem_share_request_not_found_title": "Share invite not found", + "problem_share_user_not_found_title": "Share not found", + "problem_share_code_already_linked_title": "Shocker is already linked to your account", + "problem_share_code_cant_link_own_share_code_title": "You cannot redeem your own share code", + "problem_share_code_not_found_title": "Share code not found", + "problem_share_link_expiry_date_in_past_title": "Expiry date cannot be in the past", + "problem_share_link_not_found_title": "Public share not found", + "problem_share_link_shocker_already_in_share_link_title": "Shocker is already in this public share", + "problem_share_link_shocker_not_in_share_link_title": "Shocker is not in this public share", + "problem_shocker_control_no_permission_title": "You do not have permission to control this shocker", + "problem_shocker_control_not_found_title": "Shocker not found", + "problem_shocker_control_paused_title": "Shocker is paused", + "problem_shocker_not_found_title": "Shocker not found", + "problem_signup_registration_disabled_title": "Registration is currently disabled", + "problem_signup_username_or_email_exists_title": "That username or email is already in use", + "problem_turnstile_invalid_title": "Verification failed", + "problem_turnstile_invalid_desc": "Please complete the challenge again and retry.", + "problem_user_not_found_title": "User not found", + "problem_user_privileged_delete_denied_title": "Privileged users cannot be deleted", + "problem_validation_error_title": "Some fields are invalid", + "problem_webhook_not_found_title": "Webhook not found", + "problem_webhook_unsupported_title": "Only Discord webhooks are supported", + "problem_webhook_unsupported_desc": "Use a discord.com URL, not canary or ptb.", + "error_too_many_requests": "Too many requests", + "error_retry_after_one": "Try again in {{count}} second.", + "error_retry_after_other": "Try again in {{count}} seconds.", + "error_unexpected_response": "Unexpected server response", + "error_internal": "Internal error occurred", + "error_network": "Network error occurred", + "dev_banner": "This is the OpenShock DEVELOPMENT environment. No data is saved, and it is regularly overwritten by production data.", + "firmware_channel_bugs_warning": "This channel might contain bugs." +} From f2d7fae60bbb7dc73f6ea1700aa4bf63a05898bb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Luc=20=E2=99=A5?= Date: Thu, 12 Nov 2026 17:43:14 +0100 Subject: [PATCH 11/27] New translations en.json (Finnish) [ci skip] --- messages/fi.json | 302 ++++++++++++++++++----------------------------- 1 file changed, 117 insertions(+), 185 deletions(-) diff --git a/messages/fi.json b/messages/fi.json index 586c19a0..dd721a8c 100644 --- a/messages/fi.json +++ b/messages/fi.json @@ -1,15 +1,13 @@ { - "$schema": "https://inlang.com/schema/inlang-message-format", - "landing_tagline": "Alusta turvalliseen ja luotettavaan shockerien etäohjaukseen erittäin pienellä viiveellä.", "landing_section_label": "Etusivu", "landing_hubs_online": "Hubeja verkossa nyt: ", "landing_learn_more": "Lue lisää", "landing_wiki": "Wiki", "landing_meta_description": "Tervetuloa OpenShockiin, joka on ilmainen avoimen lähdekoodin ekosysteemi erilaisten shockerien ohjaamiseen internetin kautta.", - "instance_meta_description": "Tervetuloa {siteName}-palveluun, joka on OpenShockin itsenäinen instanssi. OpenShock on ilmainen avoimen lähdekoodin ekosysteemi erilaisten shockerien ohjaamiseen internetin kautta.", + "instance_meta_description": "Tervetuloa {{siteName}}-palveluun, joka on OpenShockin itsenäinen instanssi. OpenShock on ilmainen avoimen lähdekoodin ekosysteemi erilaisten shockerien ohjaamiseen internetin kautta.", "header_sidebar_toggle": "Näytä tai piilota sivupalkki", - "header_avatar_alt": "Käyttäjän {name} avatar", + "header_avatar_alt": "Käyttäjän {{name}} avatar", "header_menu_profile": "Profiili", "header_menu_settings": "Asetukset", "header_menu_logout": "Kirjaudu ulos", @@ -17,16 +15,14 @@ "header_signup": "Rekisteröidy", "header_github_title": "OpenShock GitHubissa", "header_discord_title": "Yhteisön Discord", - - "footer_made_with": "Tehty rakkaudella {#heart/} – {#team}OpenShock-tiimi{/team}", + "footer_made_with": "Tehty rakkaudella – OpenShock-tiimi", "footer_connection_status_label": "Palvelinyhteyden tila", "footer_signalr_state": "SignalR-tila", "footer_frontend_version": "Frontendin versio", - "footer_frontend_commit_title": "Commit {commit}", + "footer_frontend_commit_title": "Commit {{commit}}", "footer_backend_version": "Backendin versio", - "footer_backend_commit_title": "Commit {commit}", + "footer_backend_commit_title": "Commit {{commit}}", "footer_language_label": "Kieli", - "sidebar_home_link_label": "OpenShockin etusivu", "sidebar_group_general": "Yleiset", "sidebar_home": "Etusivu", @@ -53,7 +49,6 @@ "sidebar_settings_audit_log": "Tapahtumaloki", "sidebar_settings_connections": "Yhdistetyt tilit", "sidebar_settings_account": "Tilin asetukset", - "error_meta_title": "Palvelu ei ole käytettävissä", "error_meta_description": "OpenShock ei ole tällä hetkellä käytettävissä", "error_meta_logo_alt": "OpenShockin logo", @@ -62,10 +57,8 @@ "error_not_found_description": "Etsimääsi sivua ei ole olemassa.", "error_unexpected_description": "Tapahtui odottamaton virhe.", "error_go_back": "Takaisin", - "auth_layout_logo_alt": "OpenShockin logo", "auth_layout_invalid_redirect_removed": "Virheellinen uudelleenohjausosoite poistettiin turvallisuutesi vuoksi.", - "auth_activate_breadcrumb": "Aktivoi tili", "auth_activate_title": "Aktivoi tili", "auth_activate_activating": "Tiliäsi aktivoidaan...", @@ -74,17 +67,15 @@ "auth_activate_missing_token": "Aktivointitunnus puuttuu", "auth_activate_continue": "Jatka kirjautumiseen", "auth_activate_toast_success": "Tili aktivoitu", - "auth_forgot_breadcrumb": "Unohtunut salasana", "auth_forgot_title": "Unohtunut salasana", "auth_forgot_description": "Anna sähköpostiosoitteesi salasanan palauttamista varten", "auth_forgot_email_label": "Sähköposti", "auth_forgot_email_placeholder": "Sähköposti", "auth_forgot_submit": "Palauta salasana", - "auth_forgot_signin_prompt": "Muistatko salasanasi? {#signin}Kirjaudu sisään{/signin}", + "auth_forgot_signin_prompt": "Muistatko salasanasi? Kirjaudu sisään", "auth_forgot_mail_disabled": "Salasanan palautus ei ole käytettävissä tässä instanssissa, koska sähköpostipalvelua ei ole määritetty. Ota yhteyttä ylläpitäjään saadaksesi apua tilisi palauttamiseen.", "auth_forgot_toast_sent": "Salasanan palautuspyyntö on lähetetty annettuun sähköpostiosoitteeseen", - "auth_login_breadcrumb": "Kirjaudu sisään", "auth_login_title": "Tervetuloa takaisin", "auth_login_loading_methods": "Ladataan käytettävissä olevia kirjautumistapoja", @@ -98,23 +89,20 @@ "auth_login_username_label": "Käyttäjänimi tai sähköposti", "auth_login_password_label": "Salasana", "auth_login_submit": "Kirjaudu sisään", - "auth_login_signup_prompt": "Eikö sinulla ole tiliä? {#signup}Rekisteröidy{/signup}", - "auth_login_legal": "Napsauttamalla ”Kirjaudu sisään” hyväksyt {#tos}käyttöehtomme{/tos} ja {#privacy}tietosuojakäytäntömme{/privacy}.", - - "auth_oauth_create_breadcrumb": "Rekisteröidy palvelulla {provider}", - "auth_oauth_create_title": "Rekisteröidy palvelulla {#provider}{provider}{/provider}", + "auth_login_signup_prompt": "Eikö sinulla ole tiliä? Rekisteröidy", + "auth_login_legal": "Napsauttamalla ”Kirjaudu sisään” hyväksyt käyttöehtomme ja tietosuojakäytäntömme.", + "auth_oauth_create_breadcrumb": "Rekisteröidy palvelulla {{provider}}", + "auth_oauth_create_title": "Rekisteröidy palvelulla {{provider}}", "auth_oauth_create_description": "Täydennä tilisi tiedot", "auth_oauth_create_username_label": "Käyttäjänimi", "auth_oauth_create_username_placeholder": "Käyttäjänimi", "auth_oauth_create_email_label": "Sähköposti", "auth_oauth_create_email_placeholder": "Sähköposti", "auth_oauth_create_submit": "Rekisteröidy", - "auth_oauth_create_legal": "Napsauttamalla ”Rekisteröidy” hyväksyt {#tos}käyttöehtomme{/tos} ja {#privacy}tietosuojakäytäntömme{/privacy}.", - + "auth_oauth_create_legal": "Napsauttamalla ”Rekisteröidy” hyväksyt käyttöehtomme ja tietosuojakäytäntömme.", "auth_oauth_error_breadcrumb": "Tunnistautumisvirhe", "auth_oauth_error_title": "Tunnistautumisvirhe", "auth_oauth_error_back": "Takaisin kirjautumiseen", - "auth_reset_breadcrumb": "Palauta salasana", "auth_reset_title": "Palauta salasana", "auth_reset_checking": "Tarkistetaan palautuslinkkiä...", @@ -127,7 +115,6 @@ "auth_reset_submit": "Palauta salasana", "auth_reset_request_new": "Pyydä uusi palautuslinkki", "auth_reset_toast_success": "Salasana on palautettu", - "auth_signup_breadcrumb": "Rekisteröidy", "auth_signup_toast_created_mail": "Tili luotiin onnistuneesti. Vahvista tilisi sähköpostiisi lähetetyllä linkillä.", "auth_signup_toast_created_no_mail": "Tili luotiin onnistuneesti. Voit nyt kirjautua sisään.", @@ -150,11 +137,10 @@ "auth_signup_confirm_label": "Vahvista salasana", "auth_signup_confirm_placeholder": "Vahvista salasana", "auth_signup_submit": "Luo tili", - "auth_signup_signin_prompt": "Onko sinulla jo tili? {#signin}Kirjaudu sisään{/signin}", + "auth_signup_signin_prompt": "Onko sinulla jo tili? Kirjaudu sisään", "auth_signup_or": "Tai", "auth_signup_with_email": "Rekisteröidy sähköpostilla", - "auth_signup_legal": "Napsauttamalla ”Luo tili” hyväksyt {#tos}käyttöehtomme{/tos} ja {#privacy}tietosuojakäytäntömme{/privacy}.", - + "auth_signup_legal": "Napsauttamalla ”Luo tili” hyväksyt käyttöehtomme ja tietosuojakäytäntömme.", "auth_verify_breadcrumb": "Vahvista sähköposti", "auth_verify_title": "Vahvista sähköposti", "auth_verify_verifying": "Vahvistetaan sähköpostiosoitettasi...", @@ -163,7 +149,6 @@ "auth_verify_missing_token": "Vahvistustunnus puuttuu", "auth_verify_continue": "Jatka kirjautumiseen", "auth_verify_toast_success": "Sähköpostiosoite vahvistettu", - "common_cancel": "Peruuta", "common_delete": "Poista", "common_edit": "Muokkaa", @@ -194,7 +179,7 @@ "control_type_shock": "Isku", "control_type_vibrate": "Väristä", "control_type_sound": "Ääni", - "live_tooltip_active": "Reaaliaikainen yhteys: {gateway} ({country}), {latency} ms", + "live_tooltip_active": "Reaaliaikainen yhteys: {{gateway}} ({{country}}), {{latency}} ms", "live_tooltip_connecting": "Yhdistetään...", "live_tooltip_connect": "Yhdistä reaaliaikaiseen ohjaukseen", "live_tooltip_hub_start": "Ctrl+napsautus käynnistää koko hubin", @@ -207,14 +192,14 @@ "shocker_hub": "Hubi", "shocker_select_hub": "Valitse hubi", "shocker_rf_id": "RF-tunniste", - "shocker_rf_id_invalid": "RF-tunnisteen on oltava kokonaisluku väliltä {min}–{max}.", + "shocker_rf_id_invalid": "RF-tunnisteen on oltava kokonaisluku väliltä {{min}}–{{max}}.", "shocker_model": "Malli", "shocker_select_model": "Valitse malli", "shocker_name_placeholder": "Shockerin nimi", "shocker_menu_view_logs": "Näytä lokit", "shocker_delete_title": "Poista shocker", - "shocker_delete_desc": "Haluatko varmasti poistaa shockerin ”{name}”? Toimintoa ei voi kumota.", - "shocker_toast_deleted": "Shocker ”{name}” poistettu", + "shocker_delete_desc": "Haluatko varmasti poistaa shockerin ”{{name}}”? Toimintoa ei voi kumota.", + "shocker_toast_deleted": "Shocker ”{{name}}” poistettu", "shocker_toast_paused": "Shocker tauotettu", "shocker_toast_resumed": "Shockeria jatkettu", "shocker_add_desc": "Rekisteröi uusi shocker johonkin hubeistasi.", @@ -239,13 +224,8 @@ "shockers_empty_no_hubs": "Luo ensin hubi ja lisää siihen sitten shockereita.", "shockers_empty_has_hubs": "Aloita lisäämällä shocker johonkin hubeistasi.", "shockers_create_hub": "Luo hubi", - "shockers_count": [ - { - "declarations": ["input count", "local countPlural = count: plural"], - "selectors": ["countPlural"], - "match": { "countPlural=one": "{count} shocker", "countPlural=other": "{count} shockeria" } - } - ], + "shockers_count_one": "{{count}} shocker", + "shockers_count_other": "{{count}} shockeria", "shared_shockers_title": "Jaetut shockerit", "shared_shockers_subtitle": "Muiden käyttäjien kanssasi jakamat shockerit.", "shared_shockers_empty_title": "Kanssasi ei ole vielä jaettu shockereita.", @@ -274,18 +254,17 @@ "shocker_edit_is_active": "Shocker on aktiivinen", "shocker_edit_toast_updated": "Shocker päivitetty", "shocker_edit_delete_desc": "Poista tämä shocker pysyvästi. Toimintoa ei voi kumota.", - "common_close": "Sulje", "common_continue": "Jatka", "common_loading": "Ladataan...", "common_previous": "Edellinen", "common_next": "Seuraava", "common_steps": "Vaiheet", - "common_step_label": "Vaihe {number}: {title}", + "common_step_label": "Vaihe {{number}}: {{title}}", "common_copy": "Kopioi", "common_copied": "Kopioitu", "common_never": "Ei koskaan", - "common_error": "Virhe: {message}", + "common_error": "Virhe: {{message}}", "terminal_title": "Sarjapääte", "terminal_connecting": "Yhdistetään...", "terminal_help_button": "Ongelmia? Hae apua", @@ -298,7 +277,7 @@ "terminal_mode_raw_desc": "Pelkkä konsoli. Lue laitteen lokeja ja lähetä komentoja.", "terminal_step_channel": "Valitse kanava", "terminal_step_board": "Valitse piirilevy", - "terminal_go_to_step": "Siirry vaiheeseen {number}: {title}", + "terminal_go_to_step": "Siirry vaiheeseen {{number}}: {{title}}", "terminal_erase": "Tyhjennä ennen asennusta", "terminal_erase_desc": "Tyhjentää kaikki laitteen tiedot, myös nykyiset asetukset", "terminal_unsupported": "Selaimesi ei tue tätä ominaisuutta.", @@ -313,15 +292,15 @@ "terminal_try_driver": "Varmista, että sarjaportin ajuri on asennettu.", "terminal_open_troubleshooter": "Avaa vianmääritys", "terminal_log_reset_no_device": "Isäntäpuolen virhe nollauksessa: ei laitetta!", - "terminal_log_reset_error": "Isäntäpuolen virhe nollauksessa: {error}", + "terminal_log_reset_error": "Isäntäpuolen virhe nollauksessa: {{error}}", "terminal_log_send_no_device": "Lähetys epäonnistui: ei laitetta!", - "terminal_log_send_error": "Lähetys epäonnistui: {error}", - "terminal_log_firmware_disconnected": "Laiteohjelmiston yhteys katkesi: {error}", - "terminal_log_erase_failed": "Flashin tyhjennys epäonnistui: {error}", - "terminal_log_hard_reset_failed": "Laitteistonollaus epäonnistui: {error}", + "terminal_log_send_error": "Lähetys epäonnistui: {{error}}", + "terminal_log_firmware_disconnected": "Laiteohjelmiston yhteys katkesi: {{error}}", + "terminal_log_erase_failed": "Flashin tyhjennys epäonnistui: {{error}}", + "terminal_log_hard_reset_failed": "Laitteistonollaus epäonnistui: {{error}}", "terminal_log_flash_complete": "Asennus valmis", - "terminal_log_flash_failed": "Asennus epäonnistui: {error}", - "terminal_log_command_failed": "Komennon kirjoittaminen epäonnistui: {error}", + "terminal_log_flash_failed": "Asennus epäonnistui: {{error}}", + "terminal_log_command_failed": "Komennon kirjoittaminen epäonnistui: {{error}}", "terminal_help_title": "Vianmääritys", "terminal_help_desc": "Käy nämä vaiheet läpi järjestyksessä. Jokainen sulkee pois yleisen syyn.", "terminal_help_step_cable": "USB-kaapeli", @@ -333,23 +312,23 @@ "terminal_help_port_body": "Kytke laite suoraan tietokoneen USB-porttiin. Vältä mahdollisuuksien mukaan USB-keskittimiä, telakoita ja etupaneelin portteja, sillä ne aiheuttavat usein virta- ja signaaliongelmia. Pöytäkoneessa kokeile koneen takana olevaa porttia.", "terminal_help_driver_download": "Lataa CP210x-ajuri:", "terminal_help_driver_extract": "Pura zip-tiedoston sisältö tietokoneesi kansioon.", - "terminal_help_driver_run": "Avaa kansio ja suorita {#code}{installer}{/code}. Asenna noudattamalla ohjeita.", + "terminal_help_driver_run": "Avaa kansio ja suorita {{installer}}. Asenna noudattamalla ohjeita.", "terminal_help_driver_reconnect": "Kytke laite uudelleen.", "terminal_help_manual_intro": "Jos ajurin asennus onnistui, mutta laite ei vieläkään näy:", - "terminal_help_manual_open": "Avaa Laitehallinta (paina {#key}Win{/key} + {#key}X{/key} ja valitse {#code}Device Manager{/code}).", - "terminal_help_manual_ports": "Etsi kohdasta {#code}Ports (COM & LPT){/code} esimerkiksi tällaista merkintää:", + "terminal_help_manual_open": "Avaa Laitehallinta (paina Win + X ja valitse Device Manager).", + "terminal_help_manual_ports": "Etsi kohdasta Ports (COM & LPT) esimerkiksi tällaista merkintää:", "terminal_help_manual_missing": "Jos merkintää ei ole, Windows ei tunnista laitetta lainkaan; käy kaapeli- ja porttivaiheet läpi uudelleen.", - "terminal_help_manual_update": "Napsauta laitetta hiiren kakkospainikkeella ja valitse {#code}Update Driver{/code}.", - "terminal_help_manual_browse": "Valitse {#code}Browse my computer for drivers{/code} ja valitse kansio, johon purit ajurin zip-tiedoston. Varmista, että {#code}Include subfolders{/code} on valittuna.", - "terminal_help_manual_success": "Jos päivitys onnistui, merkinnän pitäisi nyt olla {#code}{deviceName}{/code}.", - "terminal_help_discord_intro": "Etkö vieläkään pääse eteenpäin? Liity Discord-palvelimellemme ja kysy kanavalla {#code}{channel}{/code}. Kerro seuraavat:", + "terminal_help_manual_update": "Napsauta laitetta hiiren kakkospainikkeella ja valitse Update Driver.", + "terminal_help_manual_browse": "Valitse Browse my computer for drivers ja valitse kansio, johon purit ajurin zip-tiedoston. Varmista, että Include subfolders on valittuna.", + "terminal_help_manual_success": "Jos päivitys onnistui, merkinnän pitäisi nyt olla {{deviceName}}.", + "terminal_help_discord_intro": "Etkö vieläkään pääse eteenpäin? Liity Discord-palvelimellemme ja kysy kanavalla {{channel}}. Kerro seuraavat:", "terminal_help_discord_os": "käyttöjärjestelmäsi ja selaimesi", "terminal_help_discord_device": "käyttämäsi laite (piirilevyn malli, mistä hankit sen)", "terminal_help_discord_tried": "mitä olet jo kokeillut edellisistä vaiheista", "terminal_help_discord_errors": "mahdolliset virheilmoitukset tai olennainen päätteen tuloste", "terminal_help_discord_join": "Liity Discord-palvelimellemme", "terminal_risk_title": "⚠️ EPÄVAKAA LAITEOHJELMISTO", - "terminal_risk_intro": "Olet asentamassa {#strong}kokeellista laiteohjelmistoa{/strong}, jonka tiedetään olevan {#strong}epävakaa{/strong}.", + "terminal_risk_intro": "Olet asentamassa kokeellista laiteohjelmistoa, jonka tiedetään olevan epävakaa.", "terminal_risk_brick": "Tämä voi rikkoa laitteesi pysyvästi, vaatia manuaalisen palautuksen tai tehdä siitä käyttökelvottoman.", "terminal_risk_no_support": "Emme tarjoa tukea tämän laiteohjelmiston aiheuttamiin ongelmiin.", "terminal_risk_acknowledge": "Ymmärrän, että tämä on täysin omalla vastuullani", @@ -364,7 +343,7 @@ "terminal_board_search": "Hae piirilevyjä...", "terminal_board_none": "Piirilevyä ei löytynyt.", "terminal_flash_button": "Asenna", - "terminal_flash_progress": "Edistyminen: {status}", + "terminal_flash_progress": "Edistyminen: {{status}}", "terminal_flash_idle": "Valmiina", "terminal_flash_no_device": "Laitetta ei ole valittu.", "terminal_flash_resetting": "Nollataan...", @@ -375,7 +354,7 @@ "terminal_flash_done": "Laite käynnistetty uudelleen! Asennus valmis.", "terminal_port_select": "Valitse laite", "terminal_port_disconnect": "Katkaise yhteys laitteeseen", - "terminal_port_connected": "Laite yhdistetty: {#strong}{id}{/strong}", + "terminal_port_connected": "Laite yhdistetty: {{id}}", "terminal_console": "Konsoli", "terminal_connected_device": "Yhdistetty laite", "terminal_resize": "Muuta päätepaneelin kokoa", @@ -391,7 +370,7 @@ "terminal_colors_menu": "Värit...", "terminal_colors_label": "Konsolin värit", "terminal_colors_close": "Sulje värit", - "terminal_color_input": "Väri: {name}", + "terminal_color_input": "Väri: {{name}}", "terminal_colors_reset": "Palauta oletukset", "terminal_color_bg": "Tausta", "terminal_color_fg": "Teksti", @@ -421,13 +400,12 @@ "terminal_toast_clipboard_unreadable": "Leikepöydän lukeminen epäonnistui", "terminal_toast_settings_imported": "Konsolin asetukset tuotu", "terminal_toast_settings_invalid": "Leikepöydällä ei ole konsolin asetuksia", - "common_try_again": "Yritä uudelleen", - "terminal_cfg_intro": "Arvot lähetetään laitteelle UARTin kautta. Laitteen vastaus näkyy alla olevassa konsolissa. Komennot ilman argumenttia lukevat arvon; lue nykyinen arvo kentän vieressä olevalla {#eye/}-painikkeella.", + "terminal_cfg_intro": "Arvot lähetetään laitteelle UARTin kautta. Laitteen vastaus näkyy alla olevassa konsolissa. Komennot ilman argumenttia lukevat arvon; lue nykyinen arvo kentän vieressä olevalla -painikkeella.", "terminal_cfg_rf_title": "RF-lähetin", "terminal_cfg_rf_desc": "Ohjaa shockereille lähtevää RF-signaalia.", "terminal_cfg_tx_pin": "TX GPIO -nasta", - "terminal_cfg_example": "esim. {value}", + "terminal_cfg_example": "esim. {{value}}", "terminal_cfg_read_value": "Lue nykyinen arvo", "terminal_cfg_set": "Aseta", "terminal_cfg_read": "Lue", @@ -439,13 +417,13 @@ "terminal_cfg_estop_desc": "Laitteistopainike, joka pysäyttää kaikki signaalit.", "terminal_cfg_estop_enabled": "Hätäpysäytys käytössä", "terminal_cfg_estop_pin": "Hätäpysäytyksen GPIO-nasta", - "terminal_cfg_estop_note": "Huom: {#code}{latching}{/code}- ja {#code}{active}{/code}-asetuksille ei ole omia komentoja; aseta ne alla olevalla JSON-määrityksellä.", + "terminal_cfg_estop_note": "Huom: {{latching}}- ja {{active}}-asetuksille ei ole omia komentoja; aseta ne alla olevalla JSON-määrityksellä.", "terminal_cfg_wifi_title": "WiFi", "terminal_cfg_wifi_desc": "Verkkojen tunnukset ja laitteen isäntänimi.", "terminal_cfg_hostname": "Isäntänimi", "terminal_cfg_networks": "Verkot (JSON-taulukko)", "terminal_cfg_invalid_json_array": "Oltava kelvollinen JSON-taulukko", - "terminal_cfg_ap_note": "AP-asetuksille ({#code}{ssid}{/code}, {#code}{password}{/code}, {#code}{disabled}{/code}, {#code}{staDisabled}{/code}, {#code}{offlineMode}{/code}) ei ole omia komentoja; käytä JSON-määritystä.", + "terminal_cfg_ap_note": "AP-asetuksille ({{ssid}}, {{password}}, {{disabled}}, {{staDisabled}}, {{offlineMode}}) ei ole omia komentoja; käytä JSON-määritystä.", "terminal_cfg_backend_title": "Taustapalvelu", "terminal_cfg_backend_desc": "OpenShock-palvelin ja todennus.", "terminal_cfg_domain": "Verkkotunnus", @@ -473,12 +451,11 @@ "terminal_cfg_factory_reset_confirm": "Tämä tyhjentää laitteen kaikki määritykset: WiFi-verkot, taustapalvelun tunnukset, nastat ja kaikki muut asetukset. Laite palautetaan oletusasetuksiin.", "terminal_cfg_read_failed_json_title": "JSON-asetuksia ei voitu lukea", "terminal_cfg_read_failed_raw_title": "Raaka-asetuksia ei voitu lukea", - "terminal_cfg_read_failed_desc": "Laite ei vastannut {attempts} yrityksen jälkeen.", + "terminal_cfg_read_failed_desc": "Laite ei vastannut {{attempts}} yrityksen jälkeen.", "terminal_cfg_common_causes": "Yleisiä syitä:", "terminal_cfg_cause_busy": "Laite käsittelee toista komentoa.", "terminal_cfg_cause_disconnected": "Laitteen yhteys katkesi tai se käynnistyi uudelleen.", "terminal_cfg_cause_unsupported": "Laiteohjelmiston versio ei tue tätä komentoa.", - "common_status": "Tila", "common_version": "Versio", "common_created": "Luotu", @@ -499,25 +476,25 @@ "hubs_name_placeholder": "Oma hubi", "hub_toast_not_connected": "Ei yhteyttä palvelimeen", "hub_toast_try_later": "Yritä hetken päästä uudelleen.", - "hub_reboot_title": "Käynnistetäänkö {name} uudelleen?", + "hub_reboot_title": "Käynnistetäänkö {{name}} uudelleen?", "hub_reboot_desc": "Hubi katkaisee yhteyden ja käynnistyy uudelleen. Siihen paritetut shockerit eivät vastaa, ennen kuin se on taas verkossa.", "hub_reboot": "Käynnistä uudelleen", - "hub_hotspot_enable_title": "Otetaanko Wi-Fi-tukiasema käyttöön laitteessa {name}?", - "hub_hotspot_disable_title": "Poistetaanko Wi-Fi-tukiasema käytöstä laitteessa {name}?", + "hub_hotspot_enable_title": "Otetaanko Wi-Fi-tukiasema käyttöön laitteessa {{name}}?", + "hub_hotspot_disable_title": "Poistetaanko Wi-Fi-tukiasema käytöstä laitteessa {{name}}?", "hub_hotspot_enable_desc": "Hubi lähettää oman asennusverkkonsa. Se on edelleen tavoitettavissa Wi-Fi-verkossasi, mutta tukiasema on avoin kaikille kantaman sisällä, kunnes poistat sen käytöstä.", "hub_hotspot_disable_desc": "Asennustukiasema sammuu. Jos hubi ei ole jo Wi-Fi-verkossasi, tarvitset fyysisen pääsyn laitteeseen sen määrittämiseksi uudelleen.", - "hub_delete_desc": "Olet poistamassa hubin {#strong}{name}{/strong}.", + "hub_delete_desc": "Olet poistamassa hubin {{name}}.", "hub_delete_shockers": "Tämä poistaa myös seuraavat shockerit:", "hub_edit_title": "Muokkaa hubia", "hub_edit_apply": "Käytä", "hub_pair_title_generate": "Luodaanko parituskoodi?", "hub_pair_title_generated": "Parituskoodi luotu", "hub_pair_title_paired": "Hubi paritettu", - "hub_pair_consumed": "{#strong}{name}{/strong} käytti tämän parituskoodin ja on nyt paritettu.", + "hub_pair_consumed": "{{name}} käytti tämän parituskoodin ja on nyt paritettu.", "hub_pair_used": "Koodi on käytetty, eikä se ole enää voimassa.", - "hub_pair_generated_for": "Parituskoodi luotu hubille {#strong}{name}{/strong}.", + "hub_pair_generated_for": "Parituskoodi luotu hubille {{name}}.", "hub_copy_now": "Alla olevaa koodia ei voi näyttää myöhemmin. Kopioi se nyt ja päivitä se asiakasohjelmiisi.", - "hub_pair_generate_for": "Olet luomassa parituskoodia hubille {#strong}{name}{/strong}.", + "hub_pair_generate_for": "Olet luomassa parituskoodia hubille {{name}}.", "hub_pair_valid_for": "Se on voimassa 15 minuuttia luomisesta.", "hub_pair_one_active": "Hubilla on vain yksi voimassa oleva parituskoodi; uusi koodi korvaa vanhemman.", "hub_pair_complete": "Paritus valmis", @@ -525,8 +502,8 @@ "hub_pair_copied_close": "Koodi kopioitu, sulje", "hub_pair_get": "Hae parituskoodi", "hub_token_generated": "Tunniste luotu", - "hub_token_generated_for": "Uusi tunniste luotu hubille {#strong}{name}{/strong}.", - "hub_token_regenerate_for": "Olet luomassa uutta tunnistetta hubille {#strong}{name}{/strong}.", + "hub_token_generated_for": "Uusi tunniste luotu hubille {{name}}.", + "hub_token_regenerate_for": "Olet luomassa uutta tunnistetta hubille {{name}}.", "hub_token_invalidate": "Tämä mitätöi nykyisen tunnisteen ja katkaisee sitä käyttävien asiakasohjelmien yhteyden.", "hub_token_confirm": "Haluatko varmasti tehdä tämän?", "hub_token_label": "Uusi tunniste:", @@ -554,12 +531,12 @@ "hub_update_status_error": "Virhe", "hub_update_status_timeout": "Aikakatkaisu", "hub_update_confirm_title": "Vahvista laiteohjelmiston päivitys", - "hub_update_confirm_desc": "Päivitetäänkö {#strong}{name}{/strong} versioon {#strong}{version}{/strong}?", + "hub_update_confirm_desc": "Päivitetäänkö {{name}} versioon {{version}}?", "hub_update_unstable_warning": "Tämä versio ei välttämättä ole vakaalta kanavalta, ja siinä voi olla bugin paskiaisia.", - "hub_update_title": "Päivitä {name}", + "hub_update_title": "Päivitä {{name}}", "hub_update_subtitle": "Hallitse tämän hubin laiteohjelmistopäivityksiä.", "hub_update_status_title": "Hubin tila", - "hub_update_firmware": "Laiteohjelmisto: {#mono}{version}{/mono}", + "hub_update_firmware": "Laiteohjelmisto: {{version}}", "hub_update_confirm": "Päivitä", "hub_update_success": "Päivitys onnistui", "hub_update_rolled_back": "Laite palasi edelliseen versioon", @@ -567,9 +544,9 @@ "hub_update_flash_again": "Asenna uudelleen", "hub_update_card_title": "Laiteohjelmiston päivitys", "hub_update_card_desc": "Valitse asennettava laiteohjelmiston kanava ja versio.", - "hub_update_to": "Päivitä versioon {version}", + "hub_update_to": "Päivitä versioon {{version}}", "hub_update_must_be_online": "Hubin on oltava verkossa päivityksen aloittamiseksi.", - "hub_update_updating_to": "Päivitetään versioon {version}...", + "hub_update_updating_to": "Päivitetään versioon {{version}}...", "hub_update_total": "Yhteensä", "hub_update_task": "Tehtävä", "hub_update_history": "Päivityshistoria", @@ -581,14 +558,14 @@ "hub_update_not_found": "Hubia ei löytynyt.", "home_breadcrumb": "Etusivu", "home_welcome": "Tervetuloa takaisin", - "home_welcome_name": "Tervetuloa takaisin, {name}", + "home_welcome_name": "Tervetuloa takaisin, {{name}}", "home_subtitle": "Tässä on yleiskatsaus OpenShock-asetuksistasi.", - "home_hubs_online": "{count} verkossa", + "home_hubs_online": "{{count}} verkossa", "home_hub_status": "Hubien tila", "home_no_hubs": "Ei hubeja", "home_all_online": "Kaikki verkossa", "home_all_offline": "Kaikki poissa verkosta", - "home_some_online": "{online}/{total} verkossa", + "home_some_online": "{{online}}/{{total}} verkossa", "home_quick_links": "Pikalinkit", "home_my_shockers": "Omat shockerit", "home_my_shockers_desc": "Ohjaa shockereitasi", @@ -599,24 +576,15 @@ "home_get_started_desc": "Sinulla ei ole vielä hubeja. Luo hubi ensimmäisen laitteesi yhdistämiseksi ja lisää siihen sitten shockereita.", "home_set_up_hub": "Määritä hubi", "home_first_shocker": "Lisää ensimmäinen shockerisi", - "home_first_shocker_desc": [ - { - "declarations": ["input count", "local countPlural = count: plural"], - "selectors": ["countPlural"], - "match": { - "countPlural=one": "Sinulla on {count} hubi määritettynä. Lisää shocker, niin voit alkaa ohjata sitä.", - "countPlural=other": "Sinulla on {count} hubia määritettynä. Lisää shocker, niin voit alkaa ohjata sitä." - } - } - ], + "home_first_shocker_desc_one": "Sinulla on {{count}} hubi määritettynä. Lisää shocker, niin voit alkaa ohjata sitä.", + "home_first_shocker_desc_other": "Sinulla on {{count}} hubia määritettynä. Lisää shocker, niin voit alkaa ohjata sitä.", "home_go_to_shockers": "Siirry shockereihin", "profile_title": "Profiili", "profile_coming_soon": "Profiili on tulossa pian", "profile_coming_soon_desc": "Julkinen profiilisi ei ole vielä käytettävissä. Tilin tiedot löytyvät asetuksista.", - "common_retry": "Yritä uudelleen", "common_never_used": "Ei koskaan käytetty", - "common_expires": "Vanhenee {time}", + "common_expires": "Vanhenee {{time}}", "common_search_placeholder": "Hae...", "common_unknown": "Tuntematon", "settings_breadcrumb_account": "Tili", @@ -646,7 +614,7 @@ "account_deactivate": "Poista tili käytöstä", "account_email_title": "Vaihda sähköposti", "account_email_desc": "Anna uusi sähköpostiosoitteesi ja vahvista nykyisellä salasanallasi.", - "account_email_toast_sent": "Vahvistusviesti lähetettiin osoitteeseen {email}. Ota muutos käyttöön napsauttamalla viestin linkkiä.", + "account_email_toast_sent": "Vahvistusviesti lähetettiin osoitteeseen {{email}}. Ota muutos käyttöön napsauttamalla viestin linkkiä.", "account_new_email": "Uusi sähköposti", "account_current_password": "Nykyinen salasana", "account_password_title": "Vaihda salasana", @@ -661,8 +629,8 @@ "tokens_toast_refreshed": "Tunnisteet päivitetty", "tokens_empty_title": "Ei API-tunnisteita", "tokens_empty_desc": "Luo tunniste tunnistautuaksesi OpenShockin API:in.", - "tokens_created_on": "Luotu {date}", - "tokens_last_used": "Viimeksi käytetty {time}", + "tokens_created_on": "Luotu {{date}}", + "tokens_last_used": "Viimeksi käytetty {{time}}", "tokens_never_expires": "Ei vanhene", "tokens_load_failed": "API-tunnisteiden lataaminen epäonnistui.", "token_toast_edited": "Tunnistetta muokattiin", @@ -684,7 +652,7 @@ "token_toast_paused": "Tunniste keskeytetty", "token_toast_resumed": "Tunniste jatkuu", "token_delete_title": "Poista API-tunniste", - "token_delete_desc": "Haluatko varmasti poistaa tunnisteen {#strong}{name}{/strong}?", + "token_delete_desc": "Haluatko varmasti poistaa tunnisteen {{name}}?", "token_delete_permanent": "Tätä ei voi perua. Tunniste poistetaan pysyvästi.", "token_toast_deleted": "Tunniste poistettiin", "token_resume": "Jatka tunnistetta", @@ -697,11 +665,11 @@ "token_new_breadcrumb": "Uusi", "token_redirect_not_allowed": "Annettu redirect_uri ei ole sallittu. Vain loopback-osoitteet tai sovelluksen omat skeemat ovat sallittuja.", "token_params_missing": "Pakollisia GET-parametreja puuttuu. Varmista, että name, redirect_uri ja permissions on annettu.", - "token_invalid_permissions": "Virheellisiä käyttöoikeuksia: {list}", + "token_invalid_permissions": "Virheellisiä käyttöoikeuksia: {{list}}", "token_toast_created": "Tunniste luotiin", "token_request_title": "API-tunnistepyyntö", "token_access_granted": "Pääsy myönnetty", - "token_shared_redirecting": "Tunniste luotiin ja jaettiin sovellukselle. Sinut ohjataan takaisin osoitteeseen {#b}{uri}{/b}.", + "token_shared_redirecting": "Tunniste luotiin ja jaettiin sovellukselle. Sinut ohjataan takaisin osoitteeseen {{uri}}.", "token_not_redirected": "Jos sinua ei ohjata automaattisesti, käytä alla olevaa painiketta.", "token_finish": "Valmis", "token_generated_title": "API-tunniste luotu", @@ -709,7 +677,7 @@ "token_new_title": "Uusi API-tunniste", "token_external_desc": "Ulkoinen sovellus pyytää pääsyä tiliisi. Tarkista ja säädä alla olevat käyttöoikeudet ennen kuin sallit pääsyn.", "token_new_desc": "Määritä ja luo tilillesi uusi API-tunniste.", - "token_external_requesting": "{#b}{name}{/b} pyytää API-tunnistetta. Tunnisteesi jaetaan sovellukselle osoitteessa {#b}{uri}{/b}.", + "token_external_requesting": "{{name}} pyytää API-tunnistetta. Tunnisteesi jaetaan sovellukselle osoitteessa {{uri}}.", "token_allow": "Salli", "token_generate": "Luo", "token_deny": "Estä", @@ -719,13 +687,13 @@ "sessions_load_failed": "Istuntojen lataaminen epäonnistui.", "sessions_empty_title": "Ei aktiivisia istuntoja", "sessions_empty_desc": "Istunnot näkyvät täällä, kun kirjaudut sisään selaimella tai sovelluksella.", - "sessions_last_seen": "Viimeksi nähty {time}", - "sessions_signed_in": "Kirjautunut {time}", + "sessions_last_seen": "Viimeksi nähty {{time}}", + "sessions_signed_in": "Kirjautunut {{time}}", "session_toast_revoked": "Istunto peruttiin", "session_revoke_title": "Peru istunto", "session_revoke": "Peru", "session_revoke_desc": "Haluatko varmasti perua tämän istunnon?", - "session_revoke_from": "Istunto kirjautui osoitteesta {#strong}{ip}{/strong} käyttäen {#strong}{agent}{/strong}", + "session_revoke_from": "Istunto kirjautui osoitteesta {{ip}} käyttäen {{agent}}", "connections_title": "OAuth-yhteydet", "connections_subtitle": "Yhdistä tai irrota kolmannen osapuolen tilejä, niin kirjaudut nopeammin ja profiilisi pysyy ajan tasalla.", "connections_toast_linked": "Tili yhdistetty.", @@ -738,11 +706,11 @@ "connections_empty_desc": "Yhdistä saatavilla olevia palveluja valitsemalla yltä ”Yhdistä uusi palvelu”.", "connections_unlink": "Irrota", "connections_load_failed": "OAuth-yhteyksien lataaminen epäonnistui.", - "connections_unlink_title": "Irrotetaanko {name}?", + "connections_unlink_title": "Irrotetaanko {{name}}?", "connections_unlink_title_generic": "Irrotetaanko tämä tili?", "connections_unlink_desc": "Et voi enää kirjautua tällä palvelulla, ellet yhdistä sitä uudelleen.", - "provider_starting": "Käynnistetään {name}...", - "provider_link": "Yhdistä {name}", + "provider_starting": "Käynnistetään {{name}}...", + "provider_link": "Yhdistä {{name}}", "audit_subtitle": "Tilisi tietoturvan kannalta olennainen toiminta. Tarkista kaikki, mitä et tunnista.", "audit_col_time": "Aika", "audit_col_action": "Toiminto", @@ -768,22 +736,13 @@ "audit_action_automation_token_rotated": "Automaatiotunniste vaihdettu", "audit_action_automation_token_deleted": "Automaatiotunniste poistettu", "audit_action_automation_token_used": "Automaatiotunnistetta käytetty", - "audit_meta_session": "Istunto {id}", - "audit_meta_changed": "{old} → {new}", - "audit_meta_email_requested": "Pyydetty vaihto osoitteeseen {email}", - "audit_meta_accounts_removed": [ - { - "declarations": ["input count", "local countPlural = count: plural"], - "selectors": ["countPlural"], - "match": { - "countPlural=one": "{name} ({count} tili poistettu)", - "countPlural=other": "{name} ({count} tiliä poistettu)" - } - } - ], + "audit_meta_session": "Istunto {{id}}", + "audit_meta_changed": "{{old}} → {{new}}", + "audit_meta_email_requested": "Pyydetty vaihto osoitteeseen {{email}}", + "audit_meta_accounts_removed_one": "{{name}} ({{count}} tili poistettu)", + "audit_meta_accounts_removed_other": "{{name}} ({{count}} tiliä poistettu)", "audit_meta_scheduled_deletion": "Ajastettu poistettavaksi", "audit_meta_kept": "Säilytetty uudelleenaktivointia varten", - "common_view": "Näytä", "common_save": "Tallenna", "common_saving": "Tallennetaan...", @@ -808,20 +767,12 @@ "public_share_create_title": "Luo julkinen jako", "public_share_toast_deleted": "Julkinen jako poistettu", "public_share_delete_title": "Poista julkinen jako", - "public_share_delete_desc": "Haluatko varmasti poistaa julkisen jaon {#strong}{name}{/strong}?", - "public_share_edit_title": "Julkinen jako: {name}", + "public_share_delete_desc": "Haluatko varmasti poistaa julkisen jaon {{name}}?", + "public_share_edit_title": "Julkinen jako: {{name}}", "public_share_edit_subtitle": "Muokkaus: muutokset tulevat voimaan, kun tallennat.", "public_share_add_shocker": "Lisää shocker", - "public_share_toast_added": [ - { - "declarations": ["input count", "local countPlural = count: plural"], - "selectors": ["countPlural"], - "match": { - "countPlural=one": "{count} shocker lisättiin jakoon", - "countPlural=other": "{count} shockeria lisättiin jakoon" - } - } - ], + "public_share_toast_added_one": "{{count}} shocker lisättiin jakoon", + "public_share_toast_added_other": "{{count}} shockeria lisättiin jakoon", "public_share_empty_shockers_title": "Tässä jaossa ei ole shockereita", "public_share_empty_shockers_desc": "Lisää shocker, niin kuka tahansa linkin saanut voi ohjata sitä.", "public_share_load_failed": "Julkisen jaon tietojen hakeminen epäonnistui", @@ -851,15 +802,14 @@ "perm_live_on": "Live käytössä", "perm_live_off": "Live pois käytöstä", "perm_live_control": "Live-ohjaus", - "user_selector_avatar_of": "Käyttäjän {name} profiilikuva", + "user_selector_avatar_of": "Käyttäjän {{name}} profiilikuva", "user_selector_placeholder": "Anna käyttäjänimi", "user_selector_aria": "Haettava käyttäjänimi", "user_selector_search": "Hae käyttäjää", "user_selector_found": "Käyttäjä löytyi", - "common_remove": "Poista", "user_shares_subtitle": "Suorat, pysyvät jaot muiden käyttäjien kanssa.", - "user_shares_toast_invited": "Shocker-kutsu lähetettiin käyttäjälle {name}", + "user_shares_toast_invited": "Shocker-kutsu lähetettiin käyttäjälle {{name}}", "user_shares_redeem": "Lunasta koodi", "user_shares_new": "Uusi jako", "user_shares_tab_shares": "Jaot", @@ -882,12 +832,12 @@ "share_code_redeem": "Lunasta", "incoming_shares_empty_title": "Kanssasi ei ole jaettu mitään", "incoming_shares_empty_desc": "Kukaan ei ole vielä jakanut shockeria kanssasi.", - "incoming_share_toast_removed": "Käyttäjän {name} jako poistettiin", + "incoming_share_toast_removed": "Käyttäjän {{name}} jako poistettiin", "incoming_share_remove_title": "Poista jako", - "incoming_share_remove_desc": "Haluatko varmasti poistaa käyttäjän {#strong}{name}{/strong} jaon?", - "incoming_share_toast_removed_shocker": "Käyttäjän {name} jakama {shocker} poistettiin", + "incoming_share_remove_desc": "Haluatko varmasti poistaa käyttäjän {{name}} jaon?", + "incoming_share_toast_removed_shocker": "Käyttäjän {{name}} jakama {{shocker}} poistettiin", "incoming_share_remove_shocker_title": "Poistetaanko tämä jaettu shocker?", - "incoming_share_remove_shocker_desc": "Haluatko varmasti poistaa käyttäjän {#strong}{name}{/strong} jakaman shockerin {#strong}{shocker}{/strong}?", + "incoming_share_remove_shocker_desc": "Haluatko varmasti poistaa käyttäjän {{name}} jakaman shockerin {{shocker}}?", "incoming_share_manage_from": "Hallitse jakoja käyttäjältä", "share_remove": "Poista jako", "invites_empty_title": "Ei vielä kutsuja", @@ -898,23 +848,23 @@ "invites_incoming": "Saapuvat", "invites_incoming_empty_title": "Ei saapuvia kutsuja", "invites_incoming_empty_desc": "Sinulla ei ole saapuvia kutsuja.", - "invite_toast_accepted": "Hyväksyit käyttäjän {name} kutsun", - "invite_toast_declined": "Hylkäsit käyttäjän {name} kutsun", + "invite_toast_accepted": "Hyväksyit käyttäjän {{name}} kutsun", + "invite_toast_declined": "Hylkäsit käyttäjän {{name}} kutsun", "invite_deny_title": "Hylkää kutsu", "invite_deny_label": "Hylkää kutsu", "invite_deny": "Hylkää", - "invite_deny_desc": "Haluatko varmasti hylätä käyttäjän {#strong}{name}{/strong} kutsun?", + "invite_deny_desc": "Haluatko varmasti hylätä käyttäjän {{name}} kutsun?", "invite_accept": "Hyväksy kutsu", - "invite_toast_cancelled_for": "Käyttäjän {name} kutsu peruttiin ({id})", - "invite_toast_cancelled": "Kutsu {id} peruttiin", + "invite_toast_cancelled_for": "Käyttäjän {{name}} kutsu peruttiin ({{id}})", + "invite_toast_cancelled": "Kutsu {{id}} peruttiin", "invite_cancel_title": "Peru kutsu", "invite_cancel": "Peru", - "invite_cancel_for_desc": "Haluatko varmasti perua käyttäjän {#strong}{name}{/strong} kutsun?", - "invite_cancel_code_desc": "Haluatko varmasti perua kutsun, jonka koodi on {#strong}{code}{/strong}?", + "invite_cancel_for_desc": "Haluatko varmasti perua käyttäjän {{name}} kutsun?", + "invite_cancel_code_desc": "Haluatko varmasti perua kutsun, jonka koodi on {{code}}?", "invite_cancel_outstanding": "Peru odottava kutsu", "outgoing_shares_empty_title": "Ei jaettuja shockereita", "outgoing_shares_empty_desc": "Et ole vielä jakanut shockereita muiden käyttäjien kanssa.", - "outgoing_share_toast_removed": "Jaettu shocker {name} poistettiin", + "outgoing_share_toast_removed": "Jaettu shocker {{name}} poistettiin", "outgoing_share_remove_title": "Lopetetaanko tämän shockerin jakaminen?", "outgoing_share_editing_for": "Muokataan jakoja käyttäjälle", "outgoing_share_limits": "Rajat ja käyttöoikeudet", @@ -922,11 +872,9 @@ "outgoing_share_per_desc": "Säädä rajoituksia shockerikohtaisesti", "outgoing_share_all": "Kaikki", "outgoing_share_per": "Shockerikohtaisesti", - - "outgoing_share_remove_desc": "Haluatko varmasti lopettaa shockerin {#strong}{shocker}{/strong} jakamisen käyttäjälle {#strong}{name}{/strong}?", - + "outgoing_share_remove_desc": "Haluatko varmasti lopettaa shockerin {{shocker}} jakamisen käyttäjälle {{name}}?", "report_breadcrumb": "Ilmoita API-tunnisteista", - "report_toast_clipboard_failed": "Leikepöydän lukeminen epäonnistui: {error}", + "report_toast_clipboard_failed": "Leikepöydän lukeminen epäonnistui: {{error}}", "report_title": "Ilmoita vuotaneista API-tunnisteista", "report_paste": "Liitä leikepöydältä", "report_warning": "Tämä lomake on vain vahingossa vuotaneista API-tunnisteista ilmoittamiseen.", @@ -944,16 +892,11 @@ "expiration_label": "Vanheneminen", "expiration_never": "Ei koskaan", "expiration_custom": "Mukautettu", - "expiration_days": [ - { - "declarations": ["input count", "local countPlural = count: plural"], - "selectors": ["countPlural"], - "match": { "countPlural=one": "{count} päivä", "countPlural=other": "{count} päivää" } - } - ], + "expiration_days_one": "{{count}} päivä", + "expiration_days_other": "{{count}} päivää", "expiration_required": "Vanhenemispäivä on pakollinen", "expiration_never_desc": "Ei vanhene koskaan", - "expiration_expires_at": "Vanhenee {time} ({date})", + "expiration_expires_at": "Vanhenee {{time}} ({{date}})", "date_picker_placeholder": "Valitse päivä", "telemetry_toast_title": "Autatko parantamaan OpenShockia?", "telemetry_toast_desc": "Lähetä diagnostiikkaa, niin voimme korjata kaatumisia ja hitaita API-kutsuja. Raportit sisältävät virheilmoituksen, pinojäljityksen ja IP-osoitteesi. Voit muuttaa tätä milloin tahansa tilin asetuksissa.", @@ -963,28 +906,27 @@ "table_show_details": "Näytä tiedot", "table_hide_details": "Piilota tiedot", "table_no_results": "Ei tuloksia.", - "table_sort_asc": "Lajittele: {name}, nouseva", - "table_sort_desc": "Lajittele: {name}, laskeva", - "table_sort_none": "Lajittele: {name}, lajittelematon", + "table_sort_asc": "Lajittele: {{name}}, nouseva", + "table_sort_desc": "Lajittele: {{name}}, laskeva", + "table_sort_none": "Lajittele: {{name}}, lajittelematon", "cell_na": "Ei sovellu", "cell_not_applicable": "Ei sovellu", "cell_invalid": "Virheellinen", "cell_unavailable": "Ei saatavilla", "cell_none": "Ei mitään", - "oauth_login_with": "Kirjaudu palvelulla {provider}", - "oauth_signup_with": "Rekisteröidy palvelulla {provider}", + "oauth_login_with": "Kirjaudu palvelulla {{provider}}", + "oauth_signup_with": "Rekisteröidy palvelulla {{provider}}", "signalr_connect_failed": "Yhteys palvelimeen epäonnistui!", "signalr_disconnect_failed": "Virhe katkaistaessa yhteyttä palvelimeen!", "signalr_invalid_update": "Palvelimelta saatiin virheellinen päivitys!", "signalr_invalid_log": "Palvelimelta saatiin virheellisiä lokitietoja!", "signalr_invalid_ota": "Palvelimelta saatiin virheellisiä laiteohjelmistopäivityksen tietoja!", - "ota_toast_failed": "Hubin laiteohjelmistopäivitys epäonnistui: {message}", + "ota_toast_failed": "Hubin laiteohjelmistopäivitys epäonnistui: {{message}}", "ota_toast_succeeded": "Hubin laiteohjelmistopäivitys onnistui!", "ota_toast_rolled_back": "Hubin laiteohjelmisto palasi edelliseen versioon", "lcg_connect_failed": "Yhteys live-ohjauksen yhdyskäytävään epäonnistui", - "terminal_toast_bootloader_failed": "Käynnistyslataimeen siirtyminen epäonnistui: {error}", - "terminal_toast_app_mode_failed": "Sovellustilaan siirtyminen epäonnistui: {error}", - + "terminal_toast_bootloader_failed": "Käynnistyslataimeen siirtyminen epäonnistui: {{error}}", + "terminal_toast_app_mode_failed": "Sovellustilaan siirtyminen epäonnistui: {{error}}", "problem_account_account_not_activated_title": "Tiliä ei ole aktivoitu", "problem_account_account_not_activated_desc": "Etsi aktivointiviesti saapuneista.", "problem_account_activation_not_found_title": "Aktivointilinkki on virheellinen", @@ -1102,22 +1044,12 @@ "problem_webhook_not_found_title": "Webhookia ei löytynyt", "problem_webhook_unsupported_title": "Vain Discord-webhookit ovat tuettuja", "problem_webhook_unsupported_desc": "Käytä discord.com-osoitetta, ei canary- tai ptb-osoitetta.", - "error_too_many_requests": "Liian monta pyyntöä", - "error_retry_after": [ - { - "declarations": ["input seconds", "local secondsPlural = seconds: plural"], - "selectors": ["secondsPlural"], - "match": { - "secondsPlural=one": "Yritä uudelleen {seconds} sekunnin päästä.", - "secondsPlural=other": "Yritä uudelleen {seconds} sekunnin päästä." - } - } - ], + "error_retry_after_one": "Yritä uudelleen {{count}} sekunnin päästä.", + "error_retry_after_other": "Yritä uudelleen {{count}} sekunnin päästä.", "error_unexpected_response": "Odottamaton vastaus palvelimelta", "error_internal": "Tapahtui sisäinen virhe", "error_network": "Tapahtui verkkovirhe", - - "dev_banner": "Tämä on OpenShockin {#b}KEHITYSYMPÄRISTÖ{/b}. {#u}Tietoja ei tallenneta{/u}, ja ympäristö korvataan säännöllisesti tuotantotiedoilla.", + "dev_banner": "Tämä on OpenShockin KEHITYSYMPÄRISTÖ. Tietoja ei tallenneta, ja ympäristö korvataan säännöllisesti tuotantotiedoilla.", "firmware_channel_bugs_warning": "Tällä kanavalla voi olla bugin paskiaisia." } From 45afc47022ebadf54acdbc25b909f554fe33e6bc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Luc=20=E2=99=A5?= Date: Thu, 12 Nov 2026 17:43:16 +0100 Subject: [PATCH 12/27] New translations en.json (Hebrew) [ci skip] --- messages/he.json | 1055 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 1055 insertions(+) create mode 100644 messages/he.json diff --git a/messages/he.json b/messages/he.json new file mode 100644 index 00000000..ef4df56c --- /dev/null +++ b/messages/he.json @@ -0,0 +1,1055 @@ +{ + "landing_tagline": "The go-to platform for safe, reliable, real low-latency remote shocking.", + "landing_section_label": "Home", + "landing_hubs_online": "Hubs online right now: ", + "landing_learn_more": "Learn More", + "landing_wiki": "Wiki", + "landing_meta_description": "Welcome to OpenShock, a free and open-source ecosystem to control various shock collars over the internet.", + "instance_meta_description": "Welcome to {{siteName}}, an independent instance of OpenShock, a free and open-source ecosystem to control various shock collars over the internet.", + "header_sidebar_toggle": "Toggle Sidebar", + "header_avatar_alt": "{{name}}'s avatar", + "header_menu_profile": "Profile", + "header_menu_settings": "Settings", + "header_menu_logout": "Logout", + "header_login": "Login", + "header_signup": "Sign Up", + "header_github_title": "OpenShock on GitHub", + "header_discord_title": "Community Discord", + "footer_made_with": "Made with by the OpenShock Team", + "footer_connection_status_label": "Server connection status", + "footer_signalr_state": "SignalR State", + "footer_frontend_version": "Frontend Version", + "footer_frontend_commit_title": "Commit {{commit}}", + "footer_backend_version": "Backend Version", + "footer_backend_commit_title": "Commit {{commit}}", + "footer_language_label": "Language", + "sidebar_home_link_label": "OpenShock home", + "sidebar_group_general": "General", + "sidebar_home": "Home", + "sidebar_shockers": "Shockers", + "sidebar_shared_shockers": "Shared Shockers", + "sidebar_hubs": "Hubs", + "sidebar_user_shares": "User Shares", + "sidebar_public_shares": "Public Shares", + "sidebar_serial_terminal": "Serial Terminal", + "sidebar_group_admin": "Admin", + "sidebar_admin_monitoring": "Monitoring", + "sidebar_admin_online_hubs": "Online Hubs", + "sidebar_admin_online_gateways": "Online Gateways", + "sidebar_admin_management": "Management", + "sidebar_admin_users": "Users", + "sidebar_admin_blacklists": "Blacklists", + "sidebar_admin_webhooks": "Webhooks", + "sidebar_admin_mail": "Mail", + "sidebar_admin_automation_tokens": "Automation Tokens", + "sidebar_admin_configuration": "Configuration", + "sidebar_group_settings": "Settings", + "sidebar_settings_api_tokens": "API Tokens", + "sidebar_settings_sessions": "Sessions", + "sidebar_settings_audit_log": "Audit Log", + "sidebar_settings_connections": "Connections", + "sidebar_settings_account": "Account Settings", + "error_meta_title": "Service Unavailable", + "error_meta_description": "OpenShock is currently unavailable", + "error_meta_logo_alt": "OpenShock Logo", + "error_fallback_message": "Something went wrong.", + "error_not_found_message": "Page not found", + "error_not_found_description": "The page you're looking for doesn't exist.", + "error_unexpected_description": "An unexpected error occurred.", + "error_go_back": "Go back", + "auth_layout_logo_alt": "OpenShock Logo", + "auth_layout_invalid_redirect_removed": "An invalid redirect URL was removed for your safety.", + "auth_activate_breadcrumb": "Activate Account", + "auth_activate_title": "Activate Account", + "auth_activate_activating": "Activating your account...", + "auth_activate_success": "Your account has been activated", + "auth_activate_failed": "This activation link is invalid or has expired", + "auth_activate_missing_token": "Missing activation token", + "auth_activate_continue": "Continue to login", + "auth_activate_toast_success": "Account activated", + "auth_forgot_breadcrumb": "Forgot Password", + "auth_forgot_title": "Forgot Password", + "auth_forgot_description": "Enter your email to reset your password", + "auth_forgot_email_label": "Email", + "auth_forgot_email_placeholder": "Email", + "auth_forgot_submit": "Reset Password", + "auth_forgot_signin_prompt": "Remember your password? Sign in", + "auth_forgot_mail_disabled": "Password resets are unavailable on this instance because it has no mail provider configured. Please contact your administrator for help recovering your account.", + "auth_forgot_toast_sent": "Reset password request has been sent to the given email", + "auth_login_breadcrumb": "Login", + "auth_login_title": "Welcome back", + "auth_login_loading_methods": "Loading available login methods", + "auth_login_choose_method": "Login with one of these methods", + "auth_login_with_account": "Login with your OpenShock Account", + "auth_login_activation_after_signup": "Your account has been created. We've sent an activation link to your email address. Check your inbox and spam folder.", + "auth_login_activation_pending": "Your account isn't activated yet. We've sent an activation link to your email address. Check your inbox and spam folder. If nothing arrives, try logging in again later to get a new link.", + "auth_login_oauth_only": "This account has no password. Sign in with the provider you signed up with.", + "auth_login_oauth_only_with_buttons": "This account has no password. Sign in with the provider you signed up with using the buttons above.", + "auth_login_or_continue_with": "Or continue with", + "auth_login_username_label": "Username or Email", + "auth_login_password_label": "Password", + "auth_login_submit": "Login", + "auth_login_signup_prompt": "Don't have an account? Sign up", + "auth_login_legal": "By clicking Login, you agree to our Terms of Service and Privacy Policy.", + "auth_oauth_create_breadcrumb": "Sign Up With {{provider}}", + "auth_oauth_create_title": "Sign Up With {{provider}}", + "auth_oauth_create_description": "Complete your account details", + "auth_oauth_create_username_label": "Username", + "auth_oauth_create_username_placeholder": "Username", + "auth_oauth_create_email_label": "Email", + "auth_oauth_create_email_placeholder": "Email", + "auth_oauth_create_submit": "Sign Up", + "auth_oauth_create_legal": "By clicking Sign Up, you agree to our Terms of Service and Privacy Policy.", + "auth_oauth_error_breadcrumb": "Authentication Error", + "auth_oauth_error_title": "Authentication Error", + "auth_oauth_error_back": "Back to login", + "auth_reset_breadcrumb": "Reset Password", + "auth_reset_title": "Reset Password", + "auth_reset_checking": "Verifying reset link...", + "auth_reset_choose_password": "Choose a new password for your account", + "auth_reset_invalid": "This reset link is invalid or has expired", + "auth_reset_password_label": "New Password", + "auth_reset_password_placeholder": "New Password", + "auth_reset_confirm_label": "Confirm New Password", + "auth_reset_confirm_placeholder": "Confirm New Password", + "auth_reset_submit": "Reset Password", + "auth_reset_request_new": "Request a new reset link", + "auth_reset_toast_success": "Password has been reset", + "auth_signup_breadcrumb": "Sign Up", + "auth_signup_toast_created_mail": "Account created successfully. Please check your email to verify your account.", + "auth_signup_toast_created_no_mail": "Account created successfully. You can log in now.", + "auth_signup_dialog_title": "Welcome! Thank you for signing up! ❤️", + "auth_signup_dialog_created_mail": "Your account has been created. 🎉 Please check your email to verify your account.", + "auth_signup_dialog_verify_then_login": "After verifying your email, you can log in to your account.", + "auth_signup_dialog_created_no_mail": "Your account has been created and is ready to use. 🎉", + "auth_signup_dialog_login_now": "You can log in to your account now.", + "auth_signup_title": "Create your account", + "auth_signup_loading_methods": "Loading available sign-up methods", + "auth_signup_using_email": "Signing up using email", + "auth_signup_choose_method": "Choose your preferred sign-up method", + "auth_signup_back": "Back", + "auth_signup_username_label": "Username", + "auth_signup_username_placeholder": "John OpenShock", + "auth_signup_email_label": "Email", + "auth_signup_email_placeholder": "john@example.com", + "auth_signup_password_label": "Password", + "auth_signup_password_placeholder": "Password", + "auth_signup_confirm_label": "Confirm Password", + "auth_signup_confirm_placeholder": "Confirm Password", + "auth_signup_submit": "Create Account", + "auth_signup_signin_prompt": "Already have an account? Sign in", + "auth_signup_or": "Or", + "auth_signup_with_email": "Signup with Email", + "auth_signup_legal": "By clicking Create Account, you agree to our Terms of Service and Privacy Policy.", + "auth_verify_breadcrumb": "Verify Email", + "auth_verify_title": "Verify Email", + "auth_verify_verifying": "Verifying your email address...", + "auth_verify_success": "Your email has been verified", + "auth_verify_failed": "This verification link is invalid or has expired", + "auth_verify_missing_token": "Missing verification token", + "auth_verify_continue": "Continue to login", + "auth_verify_toast_success": "Email verified", + "common_cancel": "Cancel", + "common_delete": "Delete", + "common_edit": "Edit", + "common_share": "Share", + "common_copy_id": "Copy ID", + "common_id_copied": "ID copied to clipboard", + "common_open_menu": "Open menu", + "common_refresh": "Refresh", + "common_settings": "Settings", + "common_clear": "Clear", + "common_online": "Online", + "common_offline": "Offline", + "common_paused": "Paused", + "common_resume": "Resume", + "common_resuming": "Resuming...", + "common_coming_soon": "(Coming soon)", + "common_save_changes": "Save Changes", + "common_danger_zone": "Danger Zone", + "common_name": "Name", + "control_intensity": "Intensity", + "control_duration": "Duration", + "control_max_intensity": "Max Intensity", + "control_max_duration": "Max Duration", + "control_vibration": "Vibration", + "control_value": "Value", + "control_live_intensity": "Live intensity", + "control_type_stop": "Stop", + "control_type_shock": "Shock", + "control_type_vibrate": "Vibrate", + "control_type_sound": "Sound", + "live_tooltip_active": "Live via {{gateway}} ({{country}}), {{latency}}ms", + "live_tooltip_connecting": "Connecting...", + "live_tooltip_connect": "Connect to Live Control", + "live_tooltip_hub_start": "Ctrl+click to start the whole hub", + "live_tooltip_hub_stop": "Ctrl+click to stop the whole hub", + "pause_resume_shocker": "Resume shocker", + "pause_pause_shocker": "Pause shocker", + "pause_resume_all": "Resume all shockers", + "pause_pause_all": "Pause all shockers", + "shocker_label": "Shocker", + "shocker_hub": "Hub", + "shocker_select_hub": "Select hub", + "shocker_rf_id": "RF ID", + "shocker_rf_id_invalid": "RF ID must be a whole number between {{min}} and {{max}}.", + "shocker_model": "Model", + "shocker_select_model": "Select model", + "shocker_name_placeholder": "Shocker name", + "shocker_menu_view_logs": "View Logs", + "shocker_delete_title": "Delete Shocker", + "shocker_delete_desc": "Are you sure you want to delete \"{{name}}\"? This action cannot be undone.", + "shocker_toast_deleted": "Shocker \"{{name}}\" deleted", + "shocker_toast_paused": "Shocker paused", + "shocker_toast_resumed": "Shocker resumed", + "shocker_add_desc": "Register a new shocker to one of your hubs.", + "shocker_add_name_placeholder": "My Shocker", + "shockers_title": "Shockers", + "shockers_subtitle": "Every shocker paired to your hubs.", + "shockers_loading": "Loading shockers...", + "shockers_toast_refreshed": "Shockers refreshed", + "shockers_toast_need_hub": "You need to create a hub before adding shockers.", + "shockers_toast_added": "Shocker added", + "shockers_unknown_module": "Unknown module type", + "shockers_add": "Add Shocker", + "shockers_view_mode": "View mode", + "shockers_mode_classic": "Classic", + "shockers_mode_rich": "Rich", + "shockers_mode_simple": "Simple", + "shockers_mode_map": "Map", + "shockers_group_by_hub": "Group by Hub", + "shockers_global_limits": "Global Limits", + "shockers_logs_label": "Logs", + "shockers_empty_title": "No shockers yet", + "shockers_empty_no_hubs": "Create a hub first, then add shockers to it.", + "shockers_empty_has_hubs": "Add a shocker to one of your hubs to get started.", + "shockers_create_hub": "Create a Hub", + "shockers_count_one": "{{count}} shocker", + "shockers_count_other": "{{count}} shockers", + "shared_shockers_title": "Shared Shockers", + "shared_shockers_subtitle": "Shockers other users have shared with you.", + "shared_shockers_empty_title": "No shockers have been shared with you yet.", + "shared_shockers_empty_desc": "When someone shares their shockers with you, they'll appear here.", + "shocker_logs_title": "Shocker Logs", + "shocker_logs_subtitle": "Every control command sent to your shockers.", + "shocker_logs_live_title": "New logs appear in real time", + "shocker_logs_paused_title": "Live updates pause when sorting or viewing a page other than the first", + "shocker_logs_live": "Live", + "shocker_logs_col_time": "Time", + "shocker_logs_col_type": "Type", + "shocker_logs_col_by": "By", + "shocker_logs_filter_label": "Filter by shocker", + "shocker_logs_filter_placeholder": "Search shockers...", + "shocker_logs_filter_all": "All shockers", + "shocker_logs_filter_none": "No matching shockers", + "shocker_edit_title": "Edit Shocker", + "shocker_edit_subtitle": "Change this shocker's details or remove it.", + "shocker_edit_back": "Back to Shockers", + "shocker_edit_load_failed": "Failed to load shocker.", + "shocker_edit_loading": "Loading shocker...", + "shocker_edit_details_title": "Shocker Details", + "shocker_edit_details_desc": "Update the name, RF ID, and model for this shocker.", + "shocker_edit_pause_state": "Pause State", + "shocker_edit_is_paused": "Shocker is paused", + "shocker_edit_is_active": "Shocker is active", + "shocker_edit_toast_updated": "Shocker updated", + "shocker_edit_delete_desc": "Permanently delete this shocker. This action cannot be undone.", + "common_close": "Close", + "common_continue": "Continue", + "common_loading": "Loading...", + "common_previous": "Previous", + "common_next": "Next", + "common_steps": "Steps", + "common_step_label": "Step {{number}}: {{title}}", + "common_copy": "Copy", + "common_copied": "Copied", + "common_never": "Never", + "common_error": "Error: {{message}}", + "terminal_title": "Serial Terminal", + "terminal_connecting": "Connecting...", + "terminal_help_button": "I'm having trouble, help?", + "terminal_back_to_modes": "Back to mode picker", + "terminal_mode_configure": "Configure Device", + "terminal_mode_configure_desc": "Configure WiFi, authentication, and more. Includes an interactive serial console.", + "terminal_mode_flash": "Flash Firmware", + "terminal_mode_flash_desc": "Install or update firmware on a connected device.", + "terminal_mode_raw": "Serial Monitor", + "terminal_mode_raw_desc": "Just the console. Read device logs and send commands.", + "terminal_step_channel": "Select Channel", + "terminal_step_board": "Select Board", + "terminal_go_to_step": "Go to step {{number}}: {{title}}", + "terminal_erase": "Erase before flashing", + "terminal_erase_desc": "Clears all data on the device including existing configs", + "terminal_unsupported": "Your browser does not support this feature.", + "terminal_update_browser": "Please update your browser to the latest version.", + "terminal_use_browsers": "Please use one of the following browsers:", + "terminal_connect_failed_bootloader": "Could not enter bootloader mode", + "terminal_connect_failed": "Device connection failed", + "terminal_connect_failed_desc": "We couldn't establish a serial connection with the device.", + "terminal_quick_tries": "Quick things to try:", + "terminal_try_replug": "Unplug and replug the device.", + "terminal_try_cable": "Try a different USB cable or port.", + "terminal_try_driver": "Make sure the serial driver is installed.", + "terminal_open_troubleshooter": "Open troubleshooter", + "terminal_log_reset_no_device": "Host-side error during reset: no device!", + "terminal_log_reset_error": "Host-side error during reset: {{error}}", + "terminal_log_send_no_device": "Couldn't send: no device!", + "terminal_log_send_error": "Couldn't send: {{error}}", + "terminal_log_firmware_disconnected": "Firmware disconnected: {{error}}", + "terminal_log_erase_failed": "Failed to erase flash: {{error}}", + "terminal_log_hard_reset_failed": "Failed to hard reset: {{error}}", + "terminal_log_flash_complete": "Flash complete", + "terminal_log_flash_failed": "Failed to flash: {{error}}", + "terminal_log_command_failed": "Failed to write application command: {{error}}", + "terminal_help_title": "Troubleshooter", + "terminal_help_desc": "Work through these steps in order. Each one rules out a common cause.", + "terminal_help_step_cable": "USB cable", + "terminal_help_step_port": "USB port", + "terminal_help_step_driver": "Install driver", + "terminal_help_step_manual": "Manual driver update", + "terminal_help_step_discord": "Ask on Discord", + "terminal_help_cable_body": "Many USB-C and micro-USB cables are charge-only and don't carry data. Swap to a known-good data cable (one you've used to transfer files or connect other devices) and reconnect the hub.", + "terminal_help_port_body": "Plug the device directly into a USB port on your computer. Avoid USB hubs, docking stations, and front-panel ports if possible; these are common sources of power and signal issues. If you're on a desktop, try a port on the back of the machine.", + "terminal_help_driver_download": "Download the CP210x driver:", + "terminal_help_driver_extract": "Extract the contents of the zip file to a folder on your computer.", + "terminal_help_driver_run": "Open the folder and run {{installer}}. Follow the prompts to install.", + "terminal_help_driver_reconnect": "Reconnect the device.", + "terminal_help_manual_intro": "If the driver installer ran but the device still doesn't show up:", + "terminal_help_manual_open": "Open Device Manager (press Win + X and select Device Manager).", + "terminal_help_manual_ports": "Under Ports (COM & LPT), look for an entry like:", + "terminal_help_manual_missing": "If it's missing, the device isn't being detected by Windows at all; revisit the cable and port steps.", + "terminal_help_manual_update": "Right-click the device and pick Update Driver.", + "terminal_help_manual_browse": "Choose Browse my computer for drivers and select the folder you extracted the driver zip into. Make sure Include subfolders is checked.", + "terminal_help_manual_success": "On success, the entry should now read {{deviceName}}.", + "terminal_help_discord_intro": "Still stuck after all of the above? Hop into our Discord server and ask in the {{channel}} channel. Please include:", + "terminal_help_discord_os": "your operating system and browser", + "terminal_help_discord_device": "the device you're using (board model, where you got it)", + "terminal_help_discord_tried": "what you've already tried from the previous steps", + "terminal_help_discord_errors": "any error messages or relevant terminal output", + "terminal_help_discord_join": "Join our Discord server", + "terminal_risk_title": "⚠️ UNSTABLE FIRMWARE", + "terminal_risk_intro": "You are about to flash experimental firmware that is known to be unstable.", + "terminal_risk_brick": "This may permanently brick your device, require manual recovery, or render it unusable.", + "terminal_risk_no_support": "We will NOT provide support for issues caused by this firmware.", + "terminal_risk_acknowledge": "I understand this is entirely my responsibility", + "terminal_risk_abort": "Abort", + "terminal_risk_accept": "I ACCEPT FULL RESPONSIBILITY", + "firmware_channel_recommended": "This is the recommended channel.", + "firmware_channel_danger": "DO NOT USE THIS UNLESS YOU KNOW WHAT YOU ARE DOING", + "firmware_channel_stable": "Stable", + "firmware_channel_beta": "Beta", + "firmware_channel_develop": "Develop", + "terminal_board_select": "Select a board...", + "terminal_board_search": "Search boards...", + "terminal_board_none": "No board found.", + "terminal_flash_button": "Flash", + "terminal_flash_progress": "Flash Progress: {{status}}", + "terminal_flash_idle": "Idle", + "terminal_flash_no_device": "No device selected.", + "terminal_flash_resetting": "Resetting...", + "terminal_flash_downloading": "Downloading firmware...", + "terminal_flash_download_failed": "Failed to download firmware.", + "terminal_flash_flashing": "Flashing firmware...", + "terminal_flash_rebooting": "Rebooting device... (Reconnect to power manually if stuck)", + "terminal_flash_done": "Rebooted device! Flashing complete.", + "terminal_port_select": "Select Device", + "terminal_port_disconnect": "Disconnect Device", + "terminal_port_connected": "Device connected: {{id}}", + "terminal_console": "Console", + "terminal_connected_device": "Connected device", + "terminal_resize": "Resize terminal panel", + "terminal_reboot": "Reboot", + "terminal_disconnect": "Disconnect", + "terminal_fullscreen_exit_esc": "Exit fullscreen (Esc)", + "terminal_fullscreen_exit": "Exit fullscreen", + "terminal_fullscreen_fill": "Fill the window", + "terminal_command_label": "Serial command", + "terminal_command_placeholder": "Type a command...", + "terminal_command_send": "Send command", + "terminal_colors": "Colors", + "terminal_colors_menu": "Colors...", + "terminal_colors_label": "Console colors", + "terminal_colors_close": "Close colors", + "terminal_color_input": "{{name}} color", + "terminal_colors_reset": "Reset to defaults", + "terminal_color_bg": "Background", + "terminal_color_fg": "Text", + "terminal_color_ts": "Timestamp", + "terminal_color_error": "Error", + "terminal_color_warning": "Warning", + "terminal_color_info": "Info", + "terminal_color_debug": "Debug", + "terminal_color_verbose": "Verbose", + "terminal_options": "Options", + "terminal_options_label": "Console options", + "terminal_hide_system": "Hide system messages", + "terminal_stick_bottom": "Stick to bottom", + "terminal_raw_output": "Raw output", + "terminal_timestamps": "Timestamps", + "terminal_timestamp_uptime": "Uptime", + "terminal_timestamp_local": "Local", + "terminal_timestamp_ms": "Ms", + "terminal_timestamp_off": "Off", + "terminal_copy_settings": "Copy settings", + "terminal_import_settings": "Import settings", + "terminal_copy_selection": "Copy selection", + "terminal_copy_all": "Copy all output", + "terminal_toast_selection_copied": "Selection copied", + "terminal_toast_output_copied": "Console output copied", + "terminal_toast_settings_copied": "Console settings copied", + "terminal_toast_clipboard_unreadable": "Could not read the clipboard", + "terminal_toast_settings_imported": "Console settings imported", + "terminal_toast_settings_invalid": "Clipboard does not contain console settings", + "common_try_again": "Try again", + "terminal_cfg_intro": "Values are sent to the device via UART. Read the device's response in the console below. Commands without an argument act as getters; use the button next to each field to read the current value.", + "terminal_cfg_rf_title": "RF Transmitter", + "terminal_cfg_rf_desc": "Controls the shocker RF output.", + "terminal_cfg_tx_pin": "TX GPIO pin", + "terminal_cfg_example": "e.g. {{value}}", + "terminal_cfg_read_value": "Read current value", + "terminal_cfg_set": "Set", + "terminal_cfg_read": "Read", + "terminal_cfg_reading": "Reading…", + "terminal_cfg_apply": "Apply", + "terminal_cfg_keepalive": "Keepalive enabled", + "terminal_cfg_keepalive_desc": "Periodically pings paired shockers to keep them awake.", + "terminal_cfg_estop_title": "Emergency Stop", + "terminal_cfg_estop_desc": "Hardware button that halts all output.", + "terminal_cfg_estop_enabled": "EStop enabled", + "terminal_cfg_estop_pin": "EStop GPIO pin", + "terminal_cfg_estop_note": "Note: {{latching}} and {{active}} have no dedicated commands; set them via the JSON config below.", + "terminal_cfg_wifi_title": "WiFi", + "terminal_cfg_wifi_desc": "Station credentials and device hostname.", + "terminal_cfg_hostname": "Hostname", + "terminal_cfg_networks": "Networks (JSON array)", + "terminal_cfg_invalid_json_array": "Must be a valid JSON array", + "terminal_cfg_ap_note": "AP settings ({{ssid}}, {{password}}, {{disabled}}, {{staDisabled}}, {{offlineMode}}) have no dedicated commands; use the JSON config.", + "terminal_cfg_backend_title": "Backend", + "terminal_cfg_backend_desc": "OpenShock server and authentication.", + "terminal_cfg_domain": "Domain", + "terminal_cfg_domain_restart": "Setting the domain will restart the device.", + "terminal_cfg_auth_token": "Auth token", + "terminal_cfg_auth_token_placeholder": "Paste device token", + "terminal_cfg_hide": "Hide", + "terminal_cfg_show": "Show", + "terminal_cfg_serial_title": "Serial Input", + "terminal_cfg_echo": "Echo enabled", + "terminal_cfg_echo_desc": "Print typed characters back to the console.", + "terminal_cfg_advanced_title": "Advanced: full config", + "terminal_cfg_advanced_desc": "For fields without dedicated commands (captive portal, OTA, LAN, etc.), replace the entire config.", + "terminal_cfg_json_config": "JSON config", + "terminal_cfg_invalid_json": "Must be valid JSON", + "terminal_cfg_read_json": "Read current config as JSON", + "terminal_cfg_json_restart": "Applying a JSON config will restart the device.", + "terminal_cfg_raw_config": "Raw FlatBuffer config (base64)", + "terminal_cfg_invalid_base64": "Must be a valid base64 string", + "terminal_cfg_read_raw": "Read current config as base64", + "terminal_cfg_factory_reset": "Factory reset", + "terminal_cfg_factory_reset_desc": "Wipes the entire device configuration.", + "terminal_cfg_factory_reset_title": "Factory reset device?", + "terminal_cfg_factory_reset_action": "Wipe config", + "terminal_cfg_factory_reset_confirm": "This will erase all configuration on the device; WiFi networks, backend credentials, pins, and all other settings. The device will be reset to defaults.", + "terminal_cfg_read_failed_json_title": "Couldn't read the JSON config", + "terminal_cfg_read_failed_raw_title": "Couldn't read the raw config", + "terminal_cfg_read_failed_desc": "The device didn't respond after {{attempts}} attempts.", + "terminal_cfg_common_causes": "Common causes:", + "terminal_cfg_cause_busy": "The device is busy handling another command.", + "terminal_cfg_cause_disconnected": "The device disconnected or rebooted.", + "terminal_cfg_cause_unsupported": "The firmware version doesn't support this command.", + "common_status": "Status", + "common_version": "Version", + "common_created": "Created", + "common_create": "Create", + "common_done": "Done", + "common_enable": "Enable", + "common_disable": "Disable", + "common_are_you_sure": "Are you sure?", + "common_generating": "Generating...", + "hubs_title": "Hubs", + "hubs_subtitle": "Every hub registered to your account.", + "hubs_add": "Add Hub", + "hubs_load_failed": "Failed to load hubs.", + "hubs_empty_title": "No hubs yet", + "hubs_empty_desc": "A hub is the device that relays commands to your shockers. Add one to get started.", + "hubs_create_title": "Create hub", + "hubs_name_label": "Hub Name", + "hubs_name_placeholder": "My Hub", + "hub_toast_not_connected": "Not connected to the server", + "hub_toast_try_later": "Try again in a moment.", + "hub_reboot_title": "Reboot {{name}}?", + "hub_reboot_desc": "The hub will disconnect and restart. Any shockers paired to it stop responding until it comes back online.", + "hub_reboot": "Reboot", + "hub_hotspot_enable_title": "Enable Wi-Fi hotspot on {{name}}?", + "hub_hotspot_disable_title": "Disable Wi-Fi hotspot on {{name}}?", + "hub_hotspot_enable_desc": "The hub broadcasts its own setup network. It stays reachable on your Wi-Fi, but the hotspot is open to anyone in range until you turn it off.", + "hub_hotspot_disable_desc": "The setup hotspot shuts down. If the hub is not already on your Wi-Fi you will need physical access to set it up again.", + "hub_delete_desc": "You are about to delete hub {{name}}.", + "hub_delete_shockers": "This will also delete the following shockers:", + "hub_edit_title": "Edit hub", + "hub_edit_apply": "Apply", + "hub_pair_title_generate": "Generate pair code?", + "hub_pair_title_generated": "Pair code generated", + "hub_pair_title_paired": "Hub paired", + "hub_pair_consumed": "{{name}} consumed this pair code and is now paired.", + "hub_pair_used": "The code has been used and is no longer valid.", + "hub_pair_generated_for": "Pair code generated for {{name}}.", + "hub_copy_now": "The code below will not be accessible later, please copy it now and update clients with it.", + "hub_pair_generate_for": "You are about to generate a pair code for {{name}}.", + "hub_pair_valid_for": "It will be valid for 15 minutes after its creation.", + "hub_pair_one_active": "There is only one active pair code per hub, newly generated ones will override the older active ones.", + "hub_pair_complete": "Pairing complete", + "hub_pair_code_label": "Pair code:", + "hub_pair_copied_close": "Code has been copied, close", + "hub_pair_get": "Get Pair Code", + "hub_token_generated": "Token generated", + "hub_token_generated_for": "New token generated for {{name}}.", + "hub_token_regenerate_for": "You are about to regenerate the token for {{name}}.", + "hub_token_invalidate": "This action will invalidate the current token and disconnect clients using it.", + "hub_token_confirm": "Are you sure you want to do this?", + "hub_token_label": "New token:", + "hub_token_copied_close": "Token has been copied, close", + "hub_token_regenerate": "Regenerate Token", + "hub_menu_update": "Update", + "hub_menu_label": "Hub", + "hub_menu_hotspot_enable": "Enable Wi-Fi hotspot", + "hub_menu_hotspot_disable": "Disable Wi-Fi hotspot", + "hub_menu_pair": "Pair", + "hub_menu_estop": "Emergency Stop", + "hub_update_breadcrumb": "Update", + "hub_update_unknown_hub": "Unknown Hub", + "hub_update_unknown_task": "Unknown Task", + "hub_update_task_metadata": "Fetching Metadata", + "hub_update_task_preparing": "Preparing for Update", + "hub_update_task_flash_fs": "Flashing Filesystem", + "hub_update_task_verify_fs": "Verifying Filesystem", + "hub_update_task_flash_app": "Flashing Application", + "hub_update_task_bootable": "Marking Application Bootable", + "hub_update_task_rebooting": "Rebooting", + "hub_update_status_started": "Started", + "hub_update_status_running": "Running", + "hub_update_status_finished": "Finished", + "hub_update_status_error": "Error", + "hub_update_status_timeout": "Timeout", + "hub_update_confirm_title": "Confirm firmware update", + "hub_update_confirm_desc": "Update {{name}} to version {{version}}?", + "hub_update_unstable_warning": "This version may not be from the stable channel and could contain bugs.", + "hub_update_title": "Update {{name}}", + "hub_update_subtitle": "Manage firmware updates for this hub.", + "hub_update_status_title": "Hub Status", + "hub_update_firmware": "Firmware: {{version}}", + "hub_update_confirm": "Update", + "hub_update_success": "Update completed successfully", + "hub_update_rolled_back": "Device rolled back to previous version", + "hub_update_back": "Back to Hubs", + "hub_update_flash_again": "Flash Again", + "hub_update_card_title": "Firmware Update", + "hub_update_card_desc": "Select a firmware channel and version to install.", + "hub_update_to": "Update to {{version}}", + "hub_update_must_be_online": "Hub must be online to start an update.", + "hub_update_updating_to": "Updating to {{version}}...", + "hub_update_total": "Total", + "hub_update_task": "Task", + "hub_update_history": "Update History", + "hub_update_no_history": "No update history found for this hub.", + "hub_update_col_id": "ID", + "hub_update_col_started": "Started", + "hub_update_col_message": "Message", + "hub_update_loading": "Loading hub information...", + "hub_update_not_found": "Hub not found.", + "home_breadcrumb": "Home", + "home_welcome": "Welcome back", + "home_welcome_name": "Welcome back, {{name}}", + "home_subtitle": "Here's an overview of your OpenShock setup.", + "home_hubs_online": "{{count}} online", + "home_hub_status": "Hub Status", + "home_no_hubs": "No hubs", + "home_all_online": "All online", + "home_all_offline": "All offline", + "home_some_online": "{{online}}/{{total}} online", + "home_quick_links": "Quick Links", + "home_my_shockers": "My Shockers", + "home_my_shockers_desc": "Control your shockers", + "home_hubs_desc": "Manage your hubs", + "home_shared_desc": "Shockers shared with you", + "home_public_desc": "Manage share links", + "home_get_started": "Get Started", + "home_get_started_desc": "You don't have any hubs yet. Create a hub to connect your first device, then add shockers to it.", + "home_set_up_hub": "Set Up a Hub", + "home_first_shocker": "Add Your First Shocker", + "home_first_shocker_desc_one": "You have {{count}} hub set up. Add a shocker to start controlling it.", + "home_first_shocker_desc_other": "You have {{count}} hubs set up. Add a shocker to start controlling it.", + "home_go_to_shockers": "Go to Shockers", + "profile_title": "Profile", + "profile_coming_soon": "Profile is coming soon", + "profile_coming_soon_desc": "Your public profile is not available yet. Account details live under Settings.", + "common_retry": "Retry", + "common_never_used": "Never used", + "common_expires": "Expires {{time}}", + "common_search_placeholder": "Search...", + "common_unknown": "Unknown", + "settings_breadcrumb_account": "Account", + "account_subtitle": "Your sign-in details and account actions.", + "account_change_username": "Change Username", + "account_change_email": "Change Email", + "account_change_password": "Change Password", + "account_username_label": "Username", + "account_email_label": "Email", + "account_password_label": "Password", + "account_new_password_label": "New Password", + "account_confirm_password_label": "Confirm New Password", + "account_oauth_only": "Not available for OAuth-only accounts", + "account_oauth_no_password": "This account signs in via OAuth and has no password.", + "account_diagnostics": "Diagnostics", + "account_diagnostics_desc": "Help us fix crashes and slow API calls. Reports include the error message, stack trace and your IP. Off by default.", + "account_diagnostics_level": "Diagnostics level", + "account_telemetry_off": "Off", + "account_telemetry_off_desc": "Send nothing.", + "account_telemetry_errors": "Errors", + "account_telemetry_errors_desc": "Send browser error reports only.", + "account_telemetry_full": "Full", + "account_telemetry_full_desc": "Error reports plus traces of API calls (no page navigations).", + "account_toast_deactivated": "Account deactivated successfully", + "account_deactivate_title": "Deactivate account", + "account_deactivate_desc": "Are you sure you want to deactivate your account?", + "account_deactivate": "Deactivate Account", + "account_email_title": "Change email", + "account_email_desc": "Enter your new email address and confirm with your current password.", + "account_email_toast_sent": "Verification email sent to {{email}}. Click the link in that email to apply the change.", + "account_new_email": "New Email", + "account_current_password": "Current Password", + "account_password_title": "Change password", + "account_password_desc": "Enter your current password and choose a new one.", + "account_password_toast": "Password has been changed", + "account_username_title": "Change username", + "account_username_desc": "Enter a new username.", + "account_new_username": "New Username", + "account_username_toast": "Username changed successfully", + "tokens_subtitle": "API Tokens are used to authenticate with the OpenShock API.", + "tokens_generate": "Generate Token", + "tokens_toast_refreshed": "Tokens refreshed successfully", + "tokens_empty_title": "No API tokens", + "tokens_empty_desc": "Generate a token to authenticate with the OpenShock API.", + "tokens_created_on": "Created {{date}}", + "tokens_last_used": "Last used {{time}}", + "tokens_never_expires": "Never expires", + "tokens_load_failed": "Failed to load API tokens.", + "token_toast_edited": "Token edited successfully", + "token_name_required": "Name is required", + "token_name_too_long": "Name is too long", + "token_edit_title": "Edit API token", + "token_name_label": "Token Name", + "token_name_placeholder": "Token name...", + "token_permissions": "Permissions", + "token_perm_category_shockers": "Shockers", + "token_perm_category_devices": "Hubs", + "token_perm_category_usershares": "User Shares", + "token_perm_category_publicshares": "Public Shares", + "token_perm_use": "Use", + "token_perm_edit": "Edit", + "token_perm_pause": "Pause", + "token_perm_auth": "Authenticate", + "token_shocker_control": "Shocker Control", + "token_toast_paused": "Token paused", + "token_toast_resumed": "Token resumed", + "token_delete_title": "Delete API token", + "token_delete_desc": "Are you sure you want to delete {{name}}?", + "token_delete_permanent": "This action cannot be undone. This will permanently delete the token.", + "token_toast_deleted": "Token deleted successfully", + "token_resume": "Resume token", + "token_pause": "Pause token", + "token_mode_clamp_desc": "Clamp: requests outside the allowed range are capped to the nearest limit (the min or the max).", + "token_mode_lerp_desc": "Lerp: the full input range is linearly rescaled so it fits within your allowed min–max range.", + "token_paused_desc": "A paused token may not send shocker control messages.", + "token_intensity_range": "Intensity range", + "token_duration_range": "Duration range", + "token_new_breadcrumb": "New", + "token_redirect_not_allowed": "The provided redirect_uri is not allowed. Only loopback addresses or custom application schemes are permitted.", + "token_params_missing": "Required get parameters are missing. Make sure name, redirect_uri, and permissions are provided.", + "token_invalid_permissions": "Invalid permissions provided: {{list}}", + "token_toast_created": "Token created successfully", + "token_request_title": "API Token Request", + "token_access_granted": "Access granted", + "token_shared_redirecting": "The token has been created and shared with the application. Redirecting you back to {{uri}}.", + "token_not_redirected": "If you are not redirected automatically, use the button below.", + "token_finish": "Finish", + "token_generated_title": "API Token Generated", + "token_copy_now": "Please copy your API Token now, you will not be able to view it again later!", + "token_new_title": "New API Token", + "token_external_desc": "An external application is requesting access to your account. Review and adjust the permissions below before allowing access.", + "token_new_desc": "Configure and generate a new API token for your account.", + "token_external_requesting": "{{name}} is requesting an API Token. Your token will be shared with the application at {{uri}}.", + "token_allow": "Allow", + "token_generate": "Generate", + "token_deny": "Deny", + "sessions_subtitle": "Every active session on your account. Revoke any you do not recognize.", + "sessions_unknown_device": "Unknown device", + "sessions_toast_refreshed": "Sessions refreshed successfully", + "sessions_load_failed": "Failed to load sessions.", + "sessions_empty_title": "No active sessions", + "sessions_empty_desc": "Sessions appear here once you sign in from a browser or app.", + "sessions_last_seen": "Last seen {{time}}", + "sessions_signed_in": "Signed in {{time}}", + "session_toast_revoked": "Session revoked successfully", + "session_revoke_title": "Revoke session", + "session_revoke": "Revoke", + "session_revoke_desc": "Are you sure you want to revoke this session?", + "session_revoke_from": "Session logged in from {{ip}} using {{agent}}", + "connections_title": "OAuth Connections", + "connections_subtitle": "Link or unlink third-party accounts to sign in faster and keep your profile in sync.", + "connections_toast_linked": "Account linked.", + "connections_toast_cancelled": "Link flow cancelled.", + "connections_toast_failed": "Linking failed.", + "connections_toast_removed": "Connection removed", + "connections_refreshing": "Refreshing…", + "connections_link_new": "Link new provider", + "connections_empty_title": "No connections yet", + "connections_empty_desc": "Choose “Link new provider” above to connect available providers.", + "connections_unlink": "Unlink", + "connections_load_failed": "Failed to load OAuth connections.", + "connections_unlink_title": "Unlink {{name}}?", + "connections_unlink_title_generic": "Unlink this account?", + "connections_unlink_desc": "You'll no longer be able to sign in with this provider unless you link it again.", + "provider_starting": "Starting {{name}}...", + "provider_link": "Link {{name}}", + "audit_subtitle": "Security-relevant activity on your account. Review anything you do not recognize.", + "audit_col_time": "Time", + "audit_col_action": "Action", + "audit_col_details": "Details", + "audit_col_reason": "Reason", + "audit_col_ip": "IP address", + "audit_col_device": "Device", + "audit_action_login": "Signed in", + "audit_action_logout": "Signed out", + "audit_action_password_changed": "Password changed", + "audit_action_email_change_requested": "Email change requested", + "audit_action_email_changed": "Email changed", + "audit_action_username_changed": "Username changed", + "audit_action_api_token_created": "API token created", + "audit_action_api_token_deleted": "API token deleted", + "audit_action_oauth_connected": "Connection added", + "audit_action_oauth_disconnected": "Connection removed", + "audit_action_account_deactivated": "Account deactivated", + "audit_action_account_reactivated": "Account reactivated", + "audit_action_account_deleted": "Account deleted", + "audit_action_automation_token_created": "Automation token created", + "audit_action_automation_token_updated": "Automation token updated", + "audit_action_automation_token_rotated": "Automation token rotated", + "audit_action_automation_token_deleted": "Automation token deleted", + "audit_action_automation_token_used": "Automation token used", + "audit_meta_session": "Session {{id}}", + "audit_meta_changed": "{{old}} to {{new}}", + "audit_meta_email_requested": "Requested change to {{email}}", + "audit_meta_accounts_removed_one": "{{name}} ({{count}} account removed)", + "audit_meta_accounts_removed_other": "{{name}} ({{count}} accounts removed)", + "audit_meta_scheduled_deletion": "Scheduled for deletion", + "audit_meta_kept": "Kept for reactivation", + "common_view": "View", + "common_save": "Save", + "common_saving": "Saving...", + "common_back": "Back", + "common_shared_by": "Shared by", + "common_user_avatar": "User Avatar", + "common_toast_saved": "Changes saved successfully", + "pause_reason_shocker": "Paused at shocker level", + "pause_reason_shocker_user_share": "Paused at shocker and user share level", + "pause_reason_shocker_public_share": "Paused at shocker and public share level", + "pause_reason_user_share": "Paused at user share level", + "pause_reason_public_share": "Paused at public share level", + "public_shares_subtitle": "A link anyone can use, no account required.", + "public_shares_new": "New Share", + "public_share_never_expires": "Never expires", + "public_shares_empty_title": "No public shares yet", + "public_shares_empty_desc": "Create a link that anyone can use to control your shockers.", + "public_share_expired": "Expired", + "public_share_no_expiry": "No expiry", + "public_share_label": "Public Share", + "public_share_toast_created": "Created new public share", + "public_share_create_title": "Create public share", + "public_share_toast_deleted": "Deleted public share", + "public_share_delete_title": "Delete public share", + "public_share_delete_desc": "Are you sure you want to delete public share {{name}}?", + "public_share_edit_title": "Public Share: {{name}}", + "public_share_edit_subtitle": "Editing: changes apply when you save.", + "public_share_add_shocker": "Add Shocker", + "public_share_toast_added_one": "Added {{count}} shocker to share", + "public_share_toast_added_other": "Added {{count}} shockers to share", + "public_share_empty_shockers_title": "No shockers in this share", + "public_share_empty_shockers_desc": "Add a shocker and anyone with the link will be able to control it.", + "public_share_load_failed": "Error fetching public share details", + "public_share_paused_here": "Paused for this share", + "public_share_resume_shocker": "Resume shocker", + "public_share_pause_shocker": "Pause shocker", + "public_share_remove": "Remove from share", + "public_share_toast_removed": "Shocker removed from share", + "public_share_add_title": "Add shockers", + "public_share_add_desc": "Add shockers to this public share. You can set their limits once they are added.", + "public_share_add_placeholder": "Select shockers to share...", + "public_share_add_no_match": "No matching shockers", + "public_share_add_submit": "Add Shockers", + "public_share_view_loading": "Loading share details...", + "public_share_view_title": "Public Share Link", + "public_share_view_desc": "Enter as a guest or login with your OpenShock account", + "public_share_view_guest_name": "Guest Name", + "public_share_view_enter": "Enter", + "public_share_view_enter_guest": "Enter as Guest", + "public_share_login": "Login", + "perm_shock_on": "Shock enabled", + "perm_shock_off": "Shock disabled", + "perm_vibrate_on": "Vibrate enabled", + "perm_vibrate_off": "Vibrate disabled", + "perm_sound_on": "Sound enabled", + "perm_sound_off": "Sound disabled", + "perm_live_on": "Live enabled", + "perm_live_off": "Live disabled", + "perm_live_control": "Live Control", + "user_selector_avatar_of": "{{name}}'s avatar", + "user_selector_placeholder": "Enter user name", + "user_selector_aria": "Username to search", + "user_selector_search": "Search user", + "user_selector_found": "User found", + "common_remove": "Remove", + "user_shares_subtitle": "Direct permanent shares with other users.", + "user_shares_toast_invited": "Sent a shocker invite to {{name}}", + "user_shares_redeem": "Redeem Code", + "user_shares_new": "New Share", + "user_shares_tab_shares": "Shares", + "user_shares_tab_incoming": "Shared with Me", + "user_shares_tab_invites": "Invites", + "share_code_create_title": "New share code", + "share_code_create_desc": "Create a Share Code or Invite", + "share_code_shocker_placeholder": "Select shockers to share...", + "share_code_no_match": "No matching shockers", + "share_code_send_invite": "Send Share Invite", + "share_code_create": "Create Share Code", + "share_code_created_title": "Share code generated", + "share_code_created_desc": "Please copy share code or code link!", + "share_code_redeem_title": "Redeem share code", + "share_code_redeem_desc": "Enter the share code to redeem", + "share_code_redeem_placeholder": "Enter share code", + "share_code_redeemed": "Redeemed successfully!", + "share_code_shared_shockers": "Shared shockers", + "share_code_redeeming": "Redeeming...", + "share_code_redeem": "Redeem", + "incoming_shares_empty_title": "Nothing shared with you", + "incoming_shares_empty_desc": "No one has shared a shocker with you yet.", + "incoming_share_toast_removed": "Removed share for {{name}}", + "incoming_share_remove_title": "Remove Share", + "incoming_share_remove_desc": "Are you sure you want to remove the share for {{name}}?", + "incoming_share_toast_removed_shocker": "Removed {{shocker}} shared by {{name}}", + "incoming_share_remove_shocker_title": "Remove this shared shocker?", + "incoming_share_remove_shocker_desc": "Are you sure you want to remove the shocker share {{shocker}} by {{name}}?", + "incoming_share_manage_from": "Manage shares from", + "share_remove": "Remove share", + "invites_empty_title": "No invites yet", + "invites_empty_desc": "You have no incoming or outgoing share invites.", + "invites_outgoing": "Outgoing", + "invites_outgoing_empty_title": "No outgoing invites", + "invites_outgoing_empty_desc": "You have no outgoing share invites.", + "invites_incoming": "Incoming", + "invites_incoming_empty_title": "No incoming invites", + "invites_incoming_empty_desc": "You have no incoming share invites.", + "invite_toast_accepted": "Accepted share invite from {{name}}", + "invite_toast_declined": "Declined share invite from {{name}}", + "invite_deny_title": "Deny Invite", + "invite_deny_label": "Deny Invite", + "invite_deny": "Deny", + "invite_deny_desc": "Are you sure you want to deny the invite from {{name}}?", + "invite_accept": "Accept Invite", + "invite_toast_cancelled_for": "Cancelled invite for {{name}} ({{id}})", + "invite_toast_cancelled": "Cancelled invite {{id}}", + "invite_cancel_title": "Cancel Invite", + "invite_cancel": "Cancel", + "invite_cancel_for_desc": "Are you sure you want to cancel the invite for {{name}}?", + "invite_cancel_code_desc": "Are you sure you want to cancel the invite with code {{code}}?", + "invite_cancel_outstanding": "Cancel Outstanding Invite", + "outgoing_shares_empty_title": "No shared shockers", + "outgoing_shares_empty_desc": "You haven't shared any shockers with other users yet.", + "outgoing_share_toast_removed": "Removed shocker share {{name}}", + "outgoing_share_remove_title": "Stop sharing this shocker?", + "outgoing_share_editing_for": "Editing shares for", + "outgoing_share_limits": "Limits & Permissions", + "outgoing_share_same": "Same restrictions on every shocker", + "outgoing_share_per_desc": "Tune restrictions per shocker", + "outgoing_share_all": "All", + "outgoing_share_per": "Per shocker", + "outgoing_share_remove_desc": "Are you sure you want to stop sharing {{shocker}} with {{name}}?", + "report_breadcrumb": "Report API Tokens", + "report_toast_clipboard_failed": "Failed to read clipboard: {{error}}", + "report_title": "Report Leaked API Tokens", + "report_paste": "Paste from clipboard", + "report_warning": "This form is only for reporting accidentally leaked API tokens.", + "report_abuse_warning": "Intentional abuse will result in bans or severe endpoint restrictions.", + "report_detected": "Detected Tokens", + "report_invalid": "One or more tokens appear to be invalid. Please check for formatting issues.", + "report_acknowledge": "I confirm I understand what this feature is for and accept responsibility.", + "report_submit": "Submit Report", + "turnstile_disabled": "Turnstile disabled", + "common_internal_error": "Internal error", + "resend_toast_sent": "Activation email sent. Check your inbox and spam folder.", + "resend_toast_throttled": "Too many activation emails have been requested. Please try again later.", + "resend_toast_unavailable": "No activation email can be resent from this browser. If your account isn't activated yet, logging in sends a new link.", + "resend_button": "Didn't get the email? Resend", + "expiration_label": "Expiration", + "expiration_never": "Never", + "expiration_custom": "Custom", + "expiration_days_one": "{{count}} Day", + "expiration_days_other": "{{count}} Days", + "expiration_required": "Expire date is required", + "expiration_never_desc": "This will never expire", + "expiration_expires_at": "Expires {{time}} ({{date}})", + "date_picker_placeholder": "Pick a date", + "telemetry_toast_title": "Help improve OpenShock?", + "telemetry_toast_desc": "Send diagnostics to help us fix crashes and slow API calls. Reports include the error message, stack trace and your IP. You can change this any time in Account settings.", + "telemetry_toast_no": "No thanks", + "telemetry_toast_errors": "Errors only", + "telemetry_toast_full": "Full", + "table_show_details": "Show details", + "table_hide_details": "Hide details", + "table_no_results": "No results.", + "table_sort_asc": "Sort by {{name}}, ascending", + "table_sort_desc": "Sort by {{name}}, descending", + "table_sort_none": "Sort by {{name}}, unsorted", + "cell_na": "N/A", + "cell_not_applicable": "Not applicable", + "cell_invalid": "Invalid", + "cell_unavailable": "Unavailable", + "cell_none": "None", + "oauth_login_with": "Login with {{provider}}", + "oauth_signup_with": "Signup with {{provider}}", + "signalr_connect_failed": "Failed to connect to server!", + "signalr_disconnect_failed": "Encountered error while disconnecting from server!", + "signalr_invalid_update": "Received invalid update from server!", + "signalr_invalid_log": "Received invalid log data from server!", + "signalr_invalid_ota": "Received invalid firmware update data from server!", + "ota_toast_failed": "Hub firmware update failed: {{message}}", + "ota_toast_succeeded": "Hub firmware update completed successfully!", + "ota_toast_rolled_back": "Hub firmware rolled back to previous version", + "lcg_connect_failed": "Failed to connect to live control gateway", + "terminal_toast_bootloader_failed": "Failed to enter bootloader: {{error}}", + "terminal_toast_app_mode_failed": "Failed to enter application mode: {{error}}", + "problem_account_account_not_activated_title": "Account not activated", + "problem_account_account_not_activated_desc": "Check your inbox for the activation email.", + "problem_account_activation_not_found_title": "Activation link is invalid", + "problem_account_activation_not_found_desc": "The link may have expired or already been used.", + "problem_account_activation_resend_too_many_title": "Too many activation emails requested", + "problem_account_activation_resend_too_many_desc": "Please wait a while before trying again.", + "problem_account_activation_resend_unavailable_title": "Cannot resend activation email", + "problem_account_activation_resend_unavailable_desc": "Log in again to request a new activation link.", + "problem_account_deactivate_already_deactivated_title": "Account is already deactivated", + "problem_account_deactivate_denied_privileged_title": "Privileged accounts cannot be deactivated", + "problem_account_deactivate_unauthorized_title": "You are not allowed to do this", + "problem_account_deactivated_title": "This account has been deactivated", + "problem_account_email_already_in_use_title": "That email address is already in use", + "problem_account_email_invalid_title": "That email address is not valid", + "problem_account_email_taken_title": "That email address is already in use", + "problem_account_email_too_many_requests_title": "Too many email change requests", + "problem_account_email_too_many_requests_desc": "Please wait a while before trying again.", + "problem_account_email_unchanged_title": "That is already your email address", + "problem_account_email_verify_not_found_title": "Verification link is invalid", + "problem_account_email_verify_not_found_desc": "The link may have expired or already been used.", + "problem_account_o_auth_only_title": "This account has no password", + "problem_account_o_auth_only_desc": "Sign in with the provider you signed up with.", + "problem_account_password_not_set_title": "No password set", + "problem_account_password_not_set_desc": "This account signs in through an external provider.", + "problem_account_password_old_password_invalid_title": "Current password is incorrect", + "problem_account_username_invalid_title": "That username is not allowed", + "problem_account_username_recently_changed_title": "Username changed too recently", + "problem_account_username_recently_changed_desc": "You can change your username once every 7 days.", + "problem_account_username_taken_title": "That username is already taken", + "problem_admin_user_deactivated_title": "This user is deactivated", + "problem_admin_user_not_activated_title": "This user has not been activated yet", + "problem_api_token_can_only_delete_self_title": "An API token can only delete itself", + "problem_api_token_not_found_title": "API token not found", + "problem_api_token_paused_title": "This API token is paused", + "problem_assign_lcg_bad_schema_version_title": "Unsupported hub protocol version", + "problem_assign_lcg_bad_schema_version_desc": "Update the hub firmware to connect.", + "problem_assign_lcg_no_lcg_available_title": "No gateway available", + "problem_assign_lcg_no_lcg_available_desc": "No live control gateway is available right now. Please try again later.", + "problem_authentication_account_deactivated_title": "This account has been deactivated", + "problem_authentication_account_not_activated_title": "This account has not been activated", + "problem_authentication_cookie_missing_or_invalid_title": "You are not logged in", + "problem_authentication_cookie_missing_or_invalid_desc": "Your session may have expired. Please log in again.", + "problem_authentication_header_missing_or_invalid_title": "Invalid API token", + "problem_authentication_session_invalid_title": "Session expired", + "problem_authentication_session_invalid_desc": "Please log in again.", + "problem_authentication_token_invalid_title": "Invalid API token", + "problem_authentication_unknown_error_title": "Authentication failed", + "problem_authorization_policy_not_met_title": "You do not have permission to do this", + "problem_authorization_token_only_title": "This action requires an API token", + "problem_authorization_token_permission_missing_title": "This API token is missing a required permission", + "problem_authorization_unknown_error_title": "Authorization failed", + "problem_authorization_user_session_only_title": "This action requires a logged-in session", + "problem_automation_token_not_allowed_for_account_title": "Automation tokens cannot be used with privileged accounts", + "problem_configuration_already_exists_title": "A configuration entry with that name already exists", + "problem_configuration_invalid_name_format_title": "Invalid configuration name", + "problem_configuration_invalid_name_format_desc": "Only A to Z and underscores are allowed.", + "problem_configuration_invalid_value_format_title": "Value does not match the configuration type", + "problem_configuration_not_found_title": "Configuration entry not found", + "problem_control_stats_invalid_range_title": "The from date must not be after the to date", + "problem_control_stats_invalid_time_zone_title": "Unknown time zone", + "problem_control_stats_missing_capability_title": "Control statistics are not available on this server", + "problem_device_not_found_title": "Hub not found", + "problem_device_not_online_title": "Hub is offline", + "problem_device_too_many_hubs_title": "You have reached the maximum number of hubs", + "problem_device_too_many_shockers_title": "This hub has reached its maximum number of shockers", + "problem_endpoint_retired_title": "This feature is no longer available", + "problem_expression_error_title": "Invalid filter expression", + "problem_internal_server_error_title": "Something went wrong on our end", + "problem_login_invalid_credentials_title": "Invalid username or password", + "problem_login_invalid_domain_title": "Logging in from this address is not allowed", + "problem_o_auth_connection_already_exists_title": "Your account is already connected to this provider", + "problem_o_auth_connection_already_linked_title": "This external account is already linked to another user", + "problem_o_auth_flow_anonymous_only_title": "You are already signed in", + "problem_o_auth_flow_mismatch_title": "Sign-in attempt does not match", + "problem_o_auth_flow_mismatch_desc": "Please start over.", + "problem_o_auth_flow_missing_data_title": "The provider did not return your account details", + "problem_o_auth_flow_missing_data_desc": "Please try again.", + "problem_o_auth_flow_not_found_title": "Sign-in attempt expired", + "problem_o_auth_flow_not_found_desc": "Please start over.", + "problem_o_auth_flow_unsupported_title": "Unsupported sign-in flow", + "problem_o_auth_internal_error_title": "Something went wrong during sign-in", + "problem_o_auth_internal_error_desc": "Please try again in a moment.", + "problem_o_auth_link_authenticated_user_only_title": "You must be signed in to link an external account", + "problem_o_auth_provider_mismatch_title": "Sign-in attempt does not match the provider", + "problem_o_auth_provider_mismatch_desc": "Please start over.", + "problem_o_auth_provider_unsupported_title": "This sign-in provider is not supported", + "problem_pair_code_not_found_title": "Pair code not found", + "problem_password_reset_not_found_title": "Password reset link is invalid", + "problem_password_reset_not_found_desc": "The link may have expired or already been used.", + "problem_session_not_found_title": "Session not found", + "problem_share_get_no_shares_title": "You have no shares with this user", + "problem_share_request_create_cannot_share_with_self_title": "You cannot share with yourself", + "problem_share_request_create_shocker_not_found_title": "One or more shockers were not found", + "problem_share_request_create_shocker_not_found_desc": "They may have been removed or do not belong to you.", + "problem_share_request_not_found_title": "Share invite not found", + "problem_share_user_not_found_title": "Share not found", + "problem_share_code_already_linked_title": "Shocker is already linked to your account", + "problem_share_code_cant_link_own_share_code_title": "You cannot redeem your own share code", + "problem_share_code_not_found_title": "Share code not found", + "problem_share_link_expiry_date_in_past_title": "Expiry date cannot be in the past", + "problem_share_link_not_found_title": "Public share not found", + "problem_share_link_shocker_already_in_share_link_title": "Shocker is already in this public share", + "problem_share_link_shocker_not_in_share_link_title": "Shocker is not in this public share", + "problem_shocker_control_no_permission_title": "You do not have permission to control this shocker", + "problem_shocker_control_not_found_title": "Shocker not found", + "problem_shocker_control_paused_title": "Shocker is paused", + "problem_shocker_not_found_title": "Shocker not found", + "problem_signup_registration_disabled_title": "Registration is currently disabled", + "problem_signup_username_or_email_exists_title": "That username or email is already in use", + "problem_turnstile_invalid_title": "Verification failed", + "problem_turnstile_invalid_desc": "Please complete the challenge again and retry.", + "problem_user_not_found_title": "User not found", + "problem_user_privileged_delete_denied_title": "Privileged users cannot be deleted", + "problem_validation_error_title": "Some fields are invalid", + "problem_webhook_not_found_title": "Webhook not found", + "problem_webhook_unsupported_title": "Only Discord webhooks are supported", + "problem_webhook_unsupported_desc": "Use a discord.com URL, not canary or ptb.", + "error_too_many_requests": "Too many requests", + "error_retry_after_one": "Try again in {{count}} second.", + "error_retry_after_other": "Try again in {{count}} seconds.", + "error_unexpected_response": "Unexpected server response", + "error_internal": "Internal error occurred", + "error_network": "Network error occurred", + "dev_banner": "This is the OpenShock DEVELOPMENT environment. No data is saved, and it is regularly overwritten by production data.", + "firmware_channel_bugs_warning": "This channel might contain bugs." +} From 7599ac9e6c19ea82ae95471f603bf1afa457ea9d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Luc=20=E2=99=A5?= Date: Thu, 12 Nov 2026 17:43:17 +0100 Subject: [PATCH 13/27] New translations en.json (Hungarian) [ci skip] --- messages/hu.json | 1055 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 1055 insertions(+) create mode 100644 messages/hu.json diff --git a/messages/hu.json b/messages/hu.json new file mode 100644 index 00000000..ef4df56c --- /dev/null +++ b/messages/hu.json @@ -0,0 +1,1055 @@ +{ + "landing_tagline": "The go-to platform for safe, reliable, real low-latency remote shocking.", + "landing_section_label": "Home", + "landing_hubs_online": "Hubs online right now: ", + "landing_learn_more": "Learn More", + "landing_wiki": "Wiki", + "landing_meta_description": "Welcome to OpenShock, a free and open-source ecosystem to control various shock collars over the internet.", + "instance_meta_description": "Welcome to {{siteName}}, an independent instance of OpenShock, a free and open-source ecosystem to control various shock collars over the internet.", + "header_sidebar_toggle": "Toggle Sidebar", + "header_avatar_alt": "{{name}}'s avatar", + "header_menu_profile": "Profile", + "header_menu_settings": "Settings", + "header_menu_logout": "Logout", + "header_login": "Login", + "header_signup": "Sign Up", + "header_github_title": "OpenShock on GitHub", + "header_discord_title": "Community Discord", + "footer_made_with": "Made with by the OpenShock Team", + "footer_connection_status_label": "Server connection status", + "footer_signalr_state": "SignalR State", + "footer_frontend_version": "Frontend Version", + "footer_frontend_commit_title": "Commit {{commit}}", + "footer_backend_version": "Backend Version", + "footer_backend_commit_title": "Commit {{commit}}", + "footer_language_label": "Language", + "sidebar_home_link_label": "OpenShock home", + "sidebar_group_general": "General", + "sidebar_home": "Home", + "sidebar_shockers": "Shockers", + "sidebar_shared_shockers": "Shared Shockers", + "sidebar_hubs": "Hubs", + "sidebar_user_shares": "User Shares", + "sidebar_public_shares": "Public Shares", + "sidebar_serial_terminal": "Serial Terminal", + "sidebar_group_admin": "Admin", + "sidebar_admin_monitoring": "Monitoring", + "sidebar_admin_online_hubs": "Online Hubs", + "sidebar_admin_online_gateways": "Online Gateways", + "sidebar_admin_management": "Management", + "sidebar_admin_users": "Users", + "sidebar_admin_blacklists": "Blacklists", + "sidebar_admin_webhooks": "Webhooks", + "sidebar_admin_mail": "Mail", + "sidebar_admin_automation_tokens": "Automation Tokens", + "sidebar_admin_configuration": "Configuration", + "sidebar_group_settings": "Settings", + "sidebar_settings_api_tokens": "API Tokens", + "sidebar_settings_sessions": "Sessions", + "sidebar_settings_audit_log": "Audit Log", + "sidebar_settings_connections": "Connections", + "sidebar_settings_account": "Account Settings", + "error_meta_title": "Service Unavailable", + "error_meta_description": "OpenShock is currently unavailable", + "error_meta_logo_alt": "OpenShock Logo", + "error_fallback_message": "Something went wrong.", + "error_not_found_message": "Page not found", + "error_not_found_description": "The page you're looking for doesn't exist.", + "error_unexpected_description": "An unexpected error occurred.", + "error_go_back": "Go back", + "auth_layout_logo_alt": "OpenShock Logo", + "auth_layout_invalid_redirect_removed": "An invalid redirect URL was removed for your safety.", + "auth_activate_breadcrumb": "Activate Account", + "auth_activate_title": "Activate Account", + "auth_activate_activating": "Activating your account...", + "auth_activate_success": "Your account has been activated", + "auth_activate_failed": "This activation link is invalid or has expired", + "auth_activate_missing_token": "Missing activation token", + "auth_activate_continue": "Continue to login", + "auth_activate_toast_success": "Account activated", + "auth_forgot_breadcrumb": "Forgot Password", + "auth_forgot_title": "Forgot Password", + "auth_forgot_description": "Enter your email to reset your password", + "auth_forgot_email_label": "Email", + "auth_forgot_email_placeholder": "Email", + "auth_forgot_submit": "Reset Password", + "auth_forgot_signin_prompt": "Remember your password? Sign in", + "auth_forgot_mail_disabled": "Password resets are unavailable on this instance because it has no mail provider configured. Please contact your administrator for help recovering your account.", + "auth_forgot_toast_sent": "Reset password request has been sent to the given email", + "auth_login_breadcrumb": "Login", + "auth_login_title": "Welcome back", + "auth_login_loading_methods": "Loading available login methods", + "auth_login_choose_method": "Login with one of these methods", + "auth_login_with_account": "Login with your OpenShock Account", + "auth_login_activation_after_signup": "Your account has been created. We've sent an activation link to your email address. Check your inbox and spam folder.", + "auth_login_activation_pending": "Your account isn't activated yet. We've sent an activation link to your email address. Check your inbox and spam folder. If nothing arrives, try logging in again later to get a new link.", + "auth_login_oauth_only": "This account has no password. Sign in with the provider you signed up with.", + "auth_login_oauth_only_with_buttons": "This account has no password. Sign in with the provider you signed up with using the buttons above.", + "auth_login_or_continue_with": "Or continue with", + "auth_login_username_label": "Username or Email", + "auth_login_password_label": "Password", + "auth_login_submit": "Login", + "auth_login_signup_prompt": "Don't have an account? Sign up", + "auth_login_legal": "By clicking Login, you agree to our Terms of Service and Privacy Policy.", + "auth_oauth_create_breadcrumb": "Sign Up With {{provider}}", + "auth_oauth_create_title": "Sign Up With {{provider}}", + "auth_oauth_create_description": "Complete your account details", + "auth_oauth_create_username_label": "Username", + "auth_oauth_create_username_placeholder": "Username", + "auth_oauth_create_email_label": "Email", + "auth_oauth_create_email_placeholder": "Email", + "auth_oauth_create_submit": "Sign Up", + "auth_oauth_create_legal": "By clicking Sign Up, you agree to our Terms of Service and Privacy Policy.", + "auth_oauth_error_breadcrumb": "Authentication Error", + "auth_oauth_error_title": "Authentication Error", + "auth_oauth_error_back": "Back to login", + "auth_reset_breadcrumb": "Reset Password", + "auth_reset_title": "Reset Password", + "auth_reset_checking": "Verifying reset link...", + "auth_reset_choose_password": "Choose a new password for your account", + "auth_reset_invalid": "This reset link is invalid or has expired", + "auth_reset_password_label": "New Password", + "auth_reset_password_placeholder": "New Password", + "auth_reset_confirm_label": "Confirm New Password", + "auth_reset_confirm_placeholder": "Confirm New Password", + "auth_reset_submit": "Reset Password", + "auth_reset_request_new": "Request a new reset link", + "auth_reset_toast_success": "Password has been reset", + "auth_signup_breadcrumb": "Sign Up", + "auth_signup_toast_created_mail": "Account created successfully. Please check your email to verify your account.", + "auth_signup_toast_created_no_mail": "Account created successfully. You can log in now.", + "auth_signup_dialog_title": "Welcome! Thank you for signing up! ❤️", + "auth_signup_dialog_created_mail": "Your account has been created. 🎉 Please check your email to verify your account.", + "auth_signup_dialog_verify_then_login": "After verifying your email, you can log in to your account.", + "auth_signup_dialog_created_no_mail": "Your account has been created and is ready to use. 🎉", + "auth_signup_dialog_login_now": "You can log in to your account now.", + "auth_signup_title": "Create your account", + "auth_signup_loading_methods": "Loading available sign-up methods", + "auth_signup_using_email": "Signing up using email", + "auth_signup_choose_method": "Choose your preferred sign-up method", + "auth_signup_back": "Back", + "auth_signup_username_label": "Username", + "auth_signup_username_placeholder": "John OpenShock", + "auth_signup_email_label": "Email", + "auth_signup_email_placeholder": "john@example.com", + "auth_signup_password_label": "Password", + "auth_signup_password_placeholder": "Password", + "auth_signup_confirm_label": "Confirm Password", + "auth_signup_confirm_placeholder": "Confirm Password", + "auth_signup_submit": "Create Account", + "auth_signup_signin_prompt": "Already have an account? Sign in", + "auth_signup_or": "Or", + "auth_signup_with_email": "Signup with Email", + "auth_signup_legal": "By clicking Create Account, you agree to our Terms of Service and Privacy Policy.", + "auth_verify_breadcrumb": "Verify Email", + "auth_verify_title": "Verify Email", + "auth_verify_verifying": "Verifying your email address...", + "auth_verify_success": "Your email has been verified", + "auth_verify_failed": "This verification link is invalid or has expired", + "auth_verify_missing_token": "Missing verification token", + "auth_verify_continue": "Continue to login", + "auth_verify_toast_success": "Email verified", + "common_cancel": "Cancel", + "common_delete": "Delete", + "common_edit": "Edit", + "common_share": "Share", + "common_copy_id": "Copy ID", + "common_id_copied": "ID copied to clipboard", + "common_open_menu": "Open menu", + "common_refresh": "Refresh", + "common_settings": "Settings", + "common_clear": "Clear", + "common_online": "Online", + "common_offline": "Offline", + "common_paused": "Paused", + "common_resume": "Resume", + "common_resuming": "Resuming...", + "common_coming_soon": "(Coming soon)", + "common_save_changes": "Save Changes", + "common_danger_zone": "Danger Zone", + "common_name": "Name", + "control_intensity": "Intensity", + "control_duration": "Duration", + "control_max_intensity": "Max Intensity", + "control_max_duration": "Max Duration", + "control_vibration": "Vibration", + "control_value": "Value", + "control_live_intensity": "Live intensity", + "control_type_stop": "Stop", + "control_type_shock": "Shock", + "control_type_vibrate": "Vibrate", + "control_type_sound": "Sound", + "live_tooltip_active": "Live via {{gateway}} ({{country}}), {{latency}}ms", + "live_tooltip_connecting": "Connecting...", + "live_tooltip_connect": "Connect to Live Control", + "live_tooltip_hub_start": "Ctrl+click to start the whole hub", + "live_tooltip_hub_stop": "Ctrl+click to stop the whole hub", + "pause_resume_shocker": "Resume shocker", + "pause_pause_shocker": "Pause shocker", + "pause_resume_all": "Resume all shockers", + "pause_pause_all": "Pause all shockers", + "shocker_label": "Shocker", + "shocker_hub": "Hub", + "shocker_select_hub": "Select hub", + "shocker_rf_id": "RF ID", + "shocker_rf_id_invalid": "RF ID must be a whole number between {{min}} and {{max}}.", + "shocker_model": "Model", + "shocker_select_model": "Select model", + "shocker_name_placeholder": "Shocker name", + "shocker_menu_view_logs": "View Logs", + "shocker_delete_title": "Delete Shocker", + "shocker_delete_desc": "Are you sure you want to delete \"{{name}}\"? This action cannot be undone.", + "shocker_toast_deleted": "Shocker \"{{name}}\" deleted", + "shocker_toast_paused": "Shocker paused", + "shocker_toast_resumed": "Shocker resumed", + "shocker_add_desc": "Register a new shocker to one of your hubs.", + "shocker_add_name_placeholder": "My Shocker", + "shockers_title": "Shockers", + "shockers_subtitle": "Every shocker paired to your hubs.", + "shockers_loading": "Loading shockers...", + "shockers_toast_refreshed": "Shockers refreshed", + "shockers_toast_need_hub": "You need to create a hub before adding shockers.", + "shockers_toast_added": "Shocker added", + "shockers_unknown_module": "Unknown module type", + "shockers_add": "Add Shocker", + "shockers_view_mode": "View mode", + "shockers_mode_classic": "Classic", + "shockers_mode_rich": "Rich", + "shockers_mode_simple": "Simple", + "shockers_mode_map": "Map", + "shockers_group_by_hub": "Group by Hub", + "shockers_global_limits": "Global Limits", + "shockers_logs_label": "Logs", + "shockers_empty_title": "No shockers yet", + "shockers_empty_no_hubs": "Create a hub first, then add shockers to it.", + "shockers_empty_has_hubs": "Add a shocker to one of your hubs to get started.", + "shockers_create_hub": "Create a Hub", + "shockers_count_one": "{{count}} shocker", + "shockers_count_other": "{{count}} shockers", + "shared_shockers_title": "Shared Shockers", + "shared_shockers_subtitle": "Shockers other users have shared with you.", + "shared_shockers_empty_title": "No shockers have been shared with you yet.", + "shared_shockers_empty_desc": "When someone shares their shockers with you, they'll appear here.", + "shocker_logs_title": "Shocker Logs", + "shocker_logs_subtitle": "Every control command sent to your shockers.", + "shocker_logs_live_title": "New logs appear in real time", + "shocker_logs_paused_title": "Live updates pause when sorting or viewing a page other than the first", + "shocker_logs_live": "Live", + "shocker_logs_col_time": "Time", + "shocker_logs_col_type": "Type", + "shocker_logs_col_by": "By", + "shocker_logs_filter_label": "Filter by shocker", + "shocker_logs_filter_placeholder": "Search shockers...", + "shocker_logs_filter_all": "All shockers", + "shocker_logs_filter_none": "No matching shockers", + "shocker_edit_title": "Edit Shocker", + "shocker_edit_subtitle": "Change this shocker's details or remove it.", + "shocker_edit_back": "Back to Shockers", + "shocker_edit_load_failed": "Failed to load shocker.", + "shocker_edit_loading": "Loading shocker...", + "shocker_edit_details_title": "Shocker Details", + "shocker_edit_details_desc": "Update the name, RF ID, and model for this shocker.", + "shocker_edit_pause_state": "Pause State", + "shocker_edit_is_paused": "Shocker is paused", + "shocker_edit_is_active": "Shocker is active", + "shocker_edit_toast_updated": "Shocker updated", + "shocker_edit_delete_desc": "Permanently delete this shocker. This action cannot be undone.", + "common_close": "Close", + "common_continue": "Continue", + "common_loading": "Loading...", + "common_previous": "Previous", + "common_next": "Next", + "common_steps": "Steps", + "common_step_label": "Step {{number}}: {{title}}", + "common_copy": "Copy", + "common_copied": "Copied", + "common_never": "Never", + "common_error": "Error: {{message}}", + "terminal_title": "Serial Terminal", + "terminal_connecting": "Connecting...", + "terminal_help_button": "I'm having trouble, help?", + "terminal_back_to_modes": "Back to mode picker", + "terminal_mode_configure": "Configure Device", + "terminal_mode_configure_desc": "Configure WiFi, authentication, and more. Includes an interactive serial console.", + "terminal_mode_flash": "Flash Firmware", + "terminal_mode_flash_desc": "Install or update firmware on a connected device.", + "terminal_mode_raw": "Serial Monitor", + "terminal_mode_raw_desc": "Just the console. Read device logs and send commands.", + "terminal_step_channel": "Select Channel", + "terminal_step_board": "Select Board", + "terminal_go_to_step": "Go to step {{number}}: {{title}}", + "terminal_erase": "Erase before flashing", + "terminal_erase_desc": "Clears all data on the device including existing configs", + "terminal_unsupported": "Your browser does not support this feature.", + "terminal_update_browser": "Please update your browser to the latest version.", + "terminal_use_browsers": "Please use one of the following browsers:", + "terminal_connect_failed_bootloader": "Could not enter bootloader mode", + "terminal_connect_failed": "Device connection failed", + "terminal_connect_failed_desc": "We couldn't establish a serial connection with the device.", + "terminal_quick_tries": "Quick things to try:", + "terminal_try_replug": "Unplug and replug the device.", + "terminal_try_cable": "Try a different USB cable or port.", + "terminal_try_driver": "Make sure the serial driver is installed.", + "terminal_open_troubleshooter": "Open troubleshooter", + "terminal_log_reset_no_device": "Host-side error during reset: no device!", + "terminal_log_reset_error": "Host-side error during reset: {{error}}", + "terminal_log_send_no_device": "Couldn't send: no device!", + "terminal_log_send_error": "Couldn't send: {{error}}", + "terminal_log_firmware_disconnected": "Firmware disconnected: {{error}}", + "terminal_log_erase_failed": "Failed to erase flash: {{error}}", + "terminal_log_hard_reset_failed": "Failed to hard reset: {{error}}", + "terminal_log_flash_complete": "Flash complete", + "terminal_log_flash_failed": "Failed to flash: {{error}}", + "terminal_log_command_failed": "Failed to write application command: {{error}}", + "terminal_help_title": "Troubleshooter", + "terminal_help_desc": "Work through these steps in order. Each one rules out a common cause.", + "terminal_help_step_cable": "USB cable", + "terminal_help_step_port": "USB port", + "terminal_help_step_driver": "Install driver", + "terminal_help_step_manual": "Manual driver update", + "terminal_help_step_discord": "Ask on Discord", + "terminal_help_cable_body": "Many USB-C and micro-USB cables are charge-only and don't carry data. Swap to a known-good data cable (one you've used to transfer files or connect other devices) and reconnect the hub.", + "terminal_help_port_body": "Plug the device directly into a USB port on your computer. Avoid USB hubs, docking stations, and front-panel ports if possible; these are common sources of power and signal issues. If you're on a desktop, try a port on the back of the machine.", + "terminal_help_driver_download": "Download the CP210x driver:", + "terminal_help_driver_extract": "Extract the contents of the zip file to a folder on your computer.", + "terminal_help_driver_run": "Open the folder and run {{installer}}. Follow the prompts to install.", + "terminal_help_driver_reconnect": "Reconnect the device.", + "terminal_help_manual_intro": "If the driver installer ran but the device still doesn't show up:", + "terminal_help_manual_open": "Open Device Manager (press Win + X and select Device Manager).", + "terminal_help_manual_ports": "Under Ports (COM & LPT), look for an entry like:", + "terminal_help_manual_missing": "If it's missing, the device isn't being detected by Windows at all; revisit the cable and port steps.", + "terminal_help_manual_update": "Right-click the device and pick Update Driver.", + "terminal_help_manual_browse": "Choose Browse my computer for drivers and select the folder you extracted the driver zip into. Make sure Include subfolders is checked.", + "terminal_help_manual_success": "On success, the entry should now read {{deviceName}}.", + "terminal_help_discord_intro": "Still stuck after all of the above? Hop into our Discord server and ask in the {{channel}} channel. Please include:", + "terminal_help_discord_os": "your operating system and browser", + "terminal_help_discord_device": "the device you're using (board model, where you got it)", + "terminal_help_discord_tried": "what you've already tried from the previous steps", + "terminal_help_discord_errors": "any error messages or relevant terminal output", + "terminal_help_discord_join": "Join our Discord server", + "terminal_risk_title": "⚠️ UNSTABLE FIRMWARE", + "terminal_risk_intro": "You are about to flash experimental firmware that is known to be unstable.", + "terminal_risk_brick": "This may permanently brick your device, require manual recovery, or render it unusable.", + "terminal_risk_no_support": "We will NOT provide support for issues caused by this firmware.", + "terminal_risk_acknowledge": "I understand this is entirely my responsibility", + "terminal_risk_abort": "Abort", + "terminal_risk_accept": "I ACCEPT FULL RESPONSIBILITY", + "firmware_channel_recommended": "This is the recommended channel.", + "firmware_channel_danger": "DO NOT USE THIS UNLESS YOU KNOW WHAT YOU ARE DOING", + "firmware_channel_stable": "Stable", + "firmware_channel_beta": "Beta", + "firmware_channel_develop": "Develop", + "terminal_board_select": "Select a board...", + "terminal_board_search": "Search boards...", + "terminal_board_none": "No board found.", + "terminal_flash_button": "Flash", + "terminal_flash_progress": "Flash Progress: {{status}}", + "terminal_flash_idle": "Idle", + "terminal_flash_no_device": "No device selected.", + "terminal_flash_resetting": "Resetting...", + "terminal_flash_downloading": "Downloading firmware...", + "terminal_flash_download_failed": "Failed to download firmware.", + "terminal_flash_flashing": "Flashing firmware...", + "terminal_flash_rebooting": "Rebooting device... (Reconnect to power manually if stuck)", + "terminal_flash_done": "Rebooted device! Flashing complete.", + "terminal_port_select": "Select Device", + "terminal_port_disconnect": "Disconnect Device", + "terminal_port_connected": "Device connected: {{id}}", + "terminal_console": "Console", + "terminal_connected_device": "Connected device", + "terminal_resize": "Resize terminal panel", + "terminal_reboot": "Reboot", + "terminal_disconnect": "Disconnect", + "terminal_fullscreen_exit_esc": "Exit fullscreen (Esc)", + "terminal_fullscreen_exit": "Exit fullscreen", + "terminal_fullscreen_fill": "Fill the window", + "terminal_command_label": "Serial command", + "terminal_command_placeholder": "Type a command...", + "terminal_command_send": "Send command", + "terminal_colors": "Colors", + "terminal_colors_menu": "Colors...", + "terminal_colors_label": "Console colors", + "terminal_colors_close": "Close colors", + "terminal_color_input": "{{name}} color", + "terminal_colors_reset": "Reset to defaults", + "terminal_color_bg": "Background", + "terminal_color_fg": "Text", + "terminal_color_ts": "Timestamp", + "terminal_color_error": "Error", + "terminal_color_warning": "Warning", + "terminal_color_info": "Info", + "terminal_color_debug": "Debug", + "terminal_color_verbose": "Verbose", + "terminal_options": "Options", + "terminal_options_label": "Console options", + "terminal_hide_system": "Hide system messages", + "terminal_stick_bottom": "Stick to bottom", + "terminal_raw_output": "Raw output", + "terminal_timestamps": "Timestamps", + "terminal_timestamp_uptime": "Uptime", + "terminal_timestamp_local": "Local", + "terminal_timestamp_ms": "Ms", + "terminal_timestamp_off": "Off", + "terminal_copy_settings": "Copy settings", + "terminal_import_settings": "Import settings", + "terminal_copy_selection": "Copy selection", + "terminal_copy_all": "Copy all output", + "terminal_toast_selection_copied": "Selection copied", + "terminal_toast_output_copied": "Console output copied", + "terminal_toast_settings_copied": "Console settings copied", + "terminal_toast_clipboard_unreadable": "Could not read the clipboard", + "terminal_toast_settings_imported": "Console settings imported", + "terminal_toast_settings_invalid": "Clipboard does not contain console settings", + "common_try_again": "Try again", + "terminal_cfg_intro": "Values are sent to the device via UART. Read the device's response in the console below. Commands without an argument act as getters; use the button next to each field to read the current value.", + "terminal_cfg_rf_title": "RF Transmitter", + "terminal_cfg_rf_desc": "Controls the shocker RF output.", + "terminal_cfg_tx_pin": "TX GPIO pin", + "terminal_cfg_example": "e.g. {{value}}", + "terminal_cfg_read_value": "Read current value", + "terminal_cfg_set": "Set", + "terminal_cfg_read": "Read", + "terminal_cfg_reading": "Reading…", + "terminal_cfg_apply": "Apply", + "terminal_cfg_keepalive": "Keepalive enabled", + "terminal_cfg_keepalive_desc": "Periodically pings paired shockers to keep them awake.", + "terminal_cfg_estop_title": "Emergency Stop", + "terminal_cfg_estop_desc": "Hardware button that halts all output.", + "terminal_cfg_estop_enabled": "EStop enabled", + "terminal_cfg_estop_pin": "EStop GPIO pin", + "terminal_cfg_estop_note": "Note: {{latching}} and {{active}} have no dedicated commands; set them via the JSON config below.", + "terminal_cfg_wifi_title": "WiFi", + "terminal_cfg_wifi_desc": "Station credentials and device hostname.", + "terminal_cfg_hostname": "Hostname", + "terminal_cfg_networks": "Networks (JSON array)", + "terminal_cfg_invalid_json_array": "Must be a valid JSON array", + "terminal_cfg_ap_note": "AP settings ({{ssid}}, {{password}}, {{disabled}}, {{staDisabled}}, {{offlineMode}}) have no dedicated commands; use the JSON config.", + "terminal_cfg_backend_title": "Backend", + "terminal_cfg_backend_desc": "OpenShock server and authentication.", + "terminal_cfg_domain": "Domain", + "terminal_cfg_domain_restart": "Setting the domain will restart the device.", + "terminal_cfg_auth_token": "Auth token", + "terminal_cfg_auth_token_placeholder": "Paste device token", + "terminal_cfg_hide": "Hide", + "terminal_cfg_show": "Show", + "terminal_cfg_serial_title": "Serial Input", + "terminal_cfg_echo": "Echo enabled", + "terminal_cfg_echo_desc": "Print typed characters back to the console.", + "terminal_cfg_advanced_title": "Advanced: full config", + "terminal_cfg_advanced_desc": "For fields without dedicated commands (captive portal, OTA, LAN, etc.), replace the entire config.", + "terminal_cfg_json_config": "JSON config", + "terminal_cfg_invalid_json": "Must be valid JSON", + "terminal_cfg_read_json": "Read current config as JSON", + "terminal_cfg_json_restart": "Applying a JSON config will restart the device.", + "terminal_cfg_raw_config": "Raw FlatBuffer config (base64)", + "terminal_cfg_invalid_base64": "Must be a valid base64 string", + "terminal_cfg_read_raw": "Read current config as base64", + "terminal_cfg_factory_reset": "Factory reset", + "terminal_cfg_factory_reset_desc": "Wipes the entire device configuration.", + "terminal_cfg_factory_reset_title": "Factory reset device?", + "terminal_cfg_factory_reset_action": "Wipe config", + "terminal_cfg_factory_reset_confirm": "This will erase all configuration on the device; WiFi networks, backend credentials, pins, and all other settings. The device will be reset to defaults.", + "terminal_cfg_read_failed_json_title": "Couldn't read the JSON config", + "terminal_cfg_read_failed_raw_title": "Couldn't read the raw config", + "terminal_cfg_read_failed_desc": "The device didn't respond after {{attempts}} attempts.", + "terminal_cfg_common_causes": "Common causes:", + "terminal_cfg_cause_busy": "The device is busy handling another command.", + "terminal_cfg_cause_disconnected": "The device disconnected or rebooted.", + "terminal_cfg_cause_unsupported": "The firmware version doesn't support this command.", + "common_status": "Status", + "common_version": "Version", + "common_created": "Created", + "common_create": "Create", + "common_done": "Done", + "common_enable": "Enable", + "common_disable": "Disable", + "common_are_you_sure": "Are you sure?", + "common_generating": "Generating...", + "hubs_title": "Hubs", + "hubs_subtitle": "Every hub registered to your account.", + "hubs_add": "Add Hub", + "hubs_load_failed": "Failed to load hubs.", + "hubs_empty_title": "No hubs yet", + "hubs_empty_desc": "A hub is the device that relays commands to your shockers. Add one to get started.", + "hubs_create_title": "Create hub", + "hubs_name_label": "Hub Name", + "hubs_name_placeholder": "My Hub", + "hub_toast_not_connected": "Not connected to the server", + "hub_toast_try_later": "Try again in a moment.", + "hub_reboot_title": "Reboot {{name}}?", + "hub_reboot_desc": "The hub will disconnect and restart. Any shockers paired to it stop responding until it comes back online.", + "hub_reboot": "Reboot", + "hub_hotspot_enable_title": "Enable Wi-Fi hotspot on {{name}}?", + "hub_hotspot_disable_title": "Disable Wi-Fi hotspot on {{name}}?", + "hub_hotspot_enable_desc": "The hub broadcasts its own setup network. It stays reachable on your Wi-Fi, but the hotspot is open to anyone in range until you turn it off.", + "hub_hotspot_disable_desc": "The setup hotspot shuts down. If the hub is not already on your Wi-Fi you will need physical access to set it up again.", + "hub_delete_desc": "You are about to delete hub {{name}}.", + "hub_delete_shockers": "This will also delete the following shockers:", + "hub_edit_title": "Edit hub", + "hub_edit_apply": "Apply", + "hub_pair_title_generate": "Generate pair code?", + "hub_pair_title_generated": "Pair code generated", + "hub_pair_title_paired": "Hub paired", + "hub_pair_consumed": "{{name}} consumed this pair code and is now paired.", + "hub_pair_used": "The code has been used and is no longer valid.", + "hub_pair_generated_for": "Pair code generated for {{name}}.", + "hub_copy_now": "The code below will not be accessible later, please copy it now and update clients with it.", + "hub_pair_generate_for": "You are about to generate a pair code for {{name}}.", + "hub_pair_valid_for": "It will be valid for 15 minutes after its creation.", + "hub_pair_one_active": "There is only one active pair code per hub, newly generated ones will override the older active ones.", + "hub_pair_complete": "Pairing complete", + "hub_pair_code_label": "Pair code:", + "hub_pair_copied_close": "Code has been copied, close", + "hub_pair_get": "Get Pair Code", + "hub_token_generated": "Token generated", + "hub_token_generated_for": "New token generated for {{name}}.", + "hub_token_regenerate_for": "You are about to regenerate the token for {{name}}.", + "hub_token_invalidate": "This action will invalidate the current token and disconnect clients using it.", + "hub_token_confirm": "Are you sure you want to do this?", + "hub_token_label": "New token:", + "hub_token_copied_close": "Token has been copied, close", + "hub_token_regenerate": "Regenerate Token", + "hub_menu_update": "Update", + "hub_menu_label": "Hub", + "hub_menu_hotspot_enable": "Enable Wi-Fi hotspot", + "hub_menu_hotspot_disable": "Disable Wi-Fi hotspot", + "hub_menu_pair": "Pair", + "hub_menu_estop": "Emergency Stop", + "hub_update_breadcrumb": "Update", + "hub_update_unknown_hub": "Unknown Hub", + "hub_update_unknown_task": "Unknown Task", + "hub_update_task_metadata": "Fetching Metadata", + "hub_update_task_preparing": "Preparing for Update", + "hub_update_task_flash_fs": "Flashing Filesystem", + "hub_update_task_verify_fs": "Verifying Filesystem", + "hub_update_task_flash_app": "Flashing Application", + "hub_update_task_bootable": "Marking Application Bootable", + "hub_update_task_rebooting": "Rebooting", + "hub_update_status_started": "Started", + "hub_update_status_running": "Running", + "hub_update_status_finished": "Finished", + "hub_update_status_error": "Error", + "hub_update_status_timeout": "Timeout", + "hub_update_confirm_title": "Confirm firmware update", + "hub_update_confirm_desc": "Update {{name}} to version {{version}}?", + "hub_update_unstable_warning": "This version may not be from the stable channel and could contain bugs.", + "hub_update_title": "Update {{name}}", + "hub_update_subtitle": "Manage firmware updates for this hub.", + "hub_update_status_title": "Hub Status", + "hub_update_firmware": "Firmware: {{version}}", + "hub_update_confirm": "Update", + "hub_update_success": "Update completed successfully", + "hub_update_rolled_back": "Device rolled back to previous version", + "hub_update_back": "Back to Hubs", + "hub_update_flash_again": "Flash Again", + "hub_update_card_title": "Firmware Update", + "hub_update_card_desc": "Select a firmware channel and version to install.", + "hub_update_to": "Update to {{version}}", + "hub_update_must_be_online": "Hub must be online to start an update.", + "hub_update_updating_to": "Updating to {{version}}...", + "hub_update_total": "Total", + "hub_update_task": "Task", + "hub_update_history": "Update History", + "hub_update_no_history": "No update history found for this hub.", + "hub_update_col_id": "ID", + "hub_update_col_started": "Started", + "hub_update_col_message": "Message", + "hub_update_loading": "Loading hub information...", + "hub_update_not_found": "Hub not found.", + "home_breadcrumb": "Home", + "home_welcome": "Welcome back", + "home_welcome_name": "Welcome back, {{name}}", + "home_subtitle": "Here's an overview of your OpenShock setup.", + "home_hubs_online": "{{count}} online", + "home_hub_status": "Hub Status", + "home_no_hubs": "No hubs", + "home_all_online": "All online", + "home_all_offline": "All offline", + "home_some_online": "{{online}}/{{total}} online", + "home_quick_links": "Quick Links", + "home_my_shockers": "My Shockers", + "home_my_shockers_desc": "Control your shockers", + "home_hubs_desc": "Manage your hubs", + "home_shared_desc": "Shockers shared with you", + "home_public_desc": "Manage share links", + "home_get_started": "Get Started", + "home_get_started_desc": "You don't have any hubs yet. Create a hub to connect your first device, then add shockers to it.", + "home_set_up_hub": "Set Up a Hub", + "home_first_shocker": "Add Your First Shocker", + "home_first_shocker_desc_one": "You have {{count}} hub set up. Add a shocker to start controlling it.", + "home_first_shocker_desc_other": "You have {{count}} hubs set up. Add a shocker to start controlling it.", + "home_go_to_shockers": "Go to Shockers", + "profile_title": "Profile", + "profile_coming_soon": "Profile is coming soon", + "profile_coming_soon_desc": "Your public profile is not available yet. Account details live under Settings.", + "common_retry": "Retry", + "common_never_used": "Never used", + "common_expires": "Expires {{time}}", + "common_search_placeholder": "Search...", + "common_unknown": "Unknown", + "settings_breadcrumb_account": "Account", + "account_subtitle": "Your sign-in details and account actions.", + "account_change_username": "Change Username", + "account_change_email": "Change Email", + "account_change_password": "Change Password", + "account_username_label": "Username", + "account_email_label": "Email", + "account_password_label": "Password", + "account_new_password_label": "New Password", + "account_confirm_password_label": "Confirm New Password", + "account_oauth_only": "Not available for OAuth-only accounts", + "account_oauth_no_password": "This account signs in via OAuth and has no password.", + "account_diagnostics": "Diagnostics", + "account_diagnostics_desc": "Help us fix crashes and slow API calls. Reports include the error message, stack trace and your IP. Off by default.", + "account_diagnostics_level": "Diagnostics level", + "account_telemetry_off": "Off", + "account_telemetry_off_desc": "Send nothing.", + "account_telemetry_errors": "Errors", + "account_telemetry_errors_desc": "Send browser error reports only.", + "account_telemetry_full": "Full", + "account_telemetry_full_desc": "Error reports plus traces of API calls (no page navigations).", + "account_toast_deactivated": "Account deactivated successfully", + "account_deactivate_title": "Deactivate account", + "account_deactivate_desc": "Are you sure you want to deactivate your account?", + "account_deactivate": "Deactivate Account", + "account_email_title": "Change email", + "account_email_desc": "Enter your new email address and confirm with your current password.", + "account_email_toast_sent": "Verification email sent to {{email}}. Click the link in that email to apply the change.", + "account_new_email": "New Email", + "account_current_password": "Current Password", + "account_password_title": "Change password", + "account_password_desc": "Enter your current password and choose a new one.", + "account_password_toast": "Password has been changed", + "account_username_title": "Change username", + "account_username_desc": "Enter a new username.", + "account_new_username": "New Username", + "account_username_toast": "Username changed successfully", + "tokens_subtitle": "API Tokens are used to authenticate with the OpenShock API.", + "tokens_generate": "Generate Token", + "tokens_toast_refreshed": "Tokens refreshed successfully", + "tokens_empty_title": "No API tokens", + "tokens_empty_desc": "Generate a token to authenticate with the OpenShock API.", + "tokens_created_on": "Created {{date}}", + "tokens_last_used": "Last used {{time}}", + "tokens_never_expires": "Never expires", + "tokens_load_failed": "Failed to load API tokens.", + "token_toast_edited": "Token edited successfully", + "token_name_required": "Name is required", + "token_name_too_long": "Name is too long", + "token_edit_title": "Edit API token", + "token_name_label": "Token Name", + "token_name_placeholder": "Token name...", + "token_permissions": "Permissions", + "token_perm_category_shockers": "Shockers", + "token_perm_category_devices": "Hubs", + "token_perm_category_usershares": "User Shares", + "token_perm_category_publicshares": "Public Shares", + "token_perm_use": "Use", + "token_perm_edit": "Edit", + "token_perm_pause": "Pause", + "token_perm_auth": "Authenticate", + "token_shocker_control": "Shocker Control", + "token_toast_paused": "Token paused", + "token_toast_resumed": "Token resumed", + "token_delete_title": "Delete API token", + "token_delete_desc": "Are you sure you want to delete {{name}}?", + "token_delete_permanent": "This action cannot be undone. This will permanently delete the token.", + "token_toast_deleted": "Token deleted successfully", + "token_resume": "Resume token", + "token_pause": "Pause token", + "token_mode_clamp_desc": "Clamp: requests outside the allowed range are capped to the nearest limit (the min or the max).", + "token_mode_lerp_desc": "Lerp: the full input range is linearly rescaled so it fits within your allowed min–max range.", + "token_paused_desc": "A paused token may not send shocker control messages.", + "token_intensity_range": "Intensity range", + "token_duration_range": "Duration range", + "token_new_breadcrumb": "New", + "token_redirect_not_allowed": "The provided redirect_uri is not allowed. Only loopback addresses or custom application schemes are permitted.", + "token_params_missing": "Required get parameters are missing. Make sure name, redirect_uri, and permissions are provided.", + "token_invalid_permissions": "Invalid permissions provided: {{list}}", + "token_toast_created": "Token created successfully", + "token_request_title": "API Token Request", + "token_access_granted": "Access granted", + "token_shared_redirecting": "The token has been created and shared with the application. Redirecting you back to {{uri}}.", + "token_not_redirected": "If you are not redirected automatically, use the button below.", + "token_finish": "Finish", + "token_generated_title": "API Token Generated", + "token_copy_now": "Please copy your API Token now, you will not be able to view it again later!", + "token_new_title": "New API Token", + "token_external_desc": "An external application is requesting access to your account. Review and adjust the permissions below before allowing access.", + "token_new_desc": "Configure and generate a new API token for your account.", + "token_external_requesting": "{{name}} is requesting an API Token. Your token will be shared with the application at {{uri}}.", + "token_allow": "Allow", + "token_generate": "Generate", + "token_deny": "Deny", + "sessions_subtitle": "Every active session on your account. Revoke any you do not recognize.", + "sessions_unknown_device": "Unknown device", + "sessions_toast_refreshed": "Sessions refreshed successfully", + "sessions_load_failed": "Failed to load sessions.", + "sessions_empty_title": "No active sessions", + "sessions_empty_desc": "Sessions appear here once you sign in from a browser or app.", + "sessions_last_seen": "Last seen {{time}}", + "sessions_signed_in": "Signed in {{time}}", + "session_toast_revoked": "Session revoked successfully", + "session_revoke_title": "Revoke session", + "session_revoke": "Revoke", + "session_revoke_desc": "Are you sure you want to revoke this session?", + "session_revoke_from": "Session logged in from {{ip}} using {{agent}}", + "connections_title": "OAuth Connections", + "connections_subtitle": "Link or unlink third-party accounts to sign in faster and keep your profile in sync.", + "connections_toast_linked": "Account linked.", + "connections_toast_cancelled": "Link flow cancelled.", + "connections_toast_failed": "Linking failed.", + "connections_toast_removed": "Connection removed", + "connections_refreshing": "Refreshing…", + "connections_link_new": "Link new provider", + "connections_empty_title": "No connections yet", + "connections_empty_desc": "Choose “Link new provider” above to connect available providers.", + "connections_unlink": "Unlink", + "connections_load_failed": "Failed to load OAuth connections.", + "connections_unlink_title": "Unlink {{name}}?", + "connections_unlink_title_generic": "Unlink this account?", + "connections_unlink_desc": "You'll no longer be able to sign in with this provider unless you link it again.", + "provider_starting": "Starting {{name}}...", + "provider_link": "Link {{name}}", + "audit_subtitle": "Security-relevant activity on your account. Review anything you do not recognize.", + "audit_col_time": "Time", + "audit_col_action": "Action", + "audit_col_details": "Details", + "audit_col_reason": "Reason", + "audit_col_ip": "IP address", + "audit_col_device": "Device", + "audit_action_login": "Signed in", + "audit_action_logout": "Signed out", + "audit_action_password_changed": "Password changed", + "audit_action_email_change_requested": "Email change requested", + "audit_action_email_changed": "Email changed", + "audit_action_username_changed": "Username changed", + "audit_action_api_token_created": "API token created", + "audit_action_api_token_deleted": "API token deleted", + "audit_action_oauth_connected": "Connection added", + "audit_action_oauth_disconnected": "Connection removed", + "audit_action_account_deactivated": "Account deactivated", + "audit_action_account_reactivated": "Account reactivated", + "audit_action_account_deleted": "Account deleted", + "audit_action_automation_token_created": "Automation token created", + "audit_action_automation_token_updated": "Automation token updated", + "audit_action_automation_token_rotated": "Automation token rotated", + "audit_action_automation_token_deleted": "Automation token deleted", + "audit_action_automation_token_used": "Automation token used", + "audit_meta_session": "Session {{id}}", + "audit_meta_changed": "{{old}} to {{new}}", + "audit_meta_email_requested": "Requested change to {{email}}", + "audit_meta_accounts_removed_one": "{{name}} ({{count}} account removed)", + "audit_meta_accounts_removed_other": "{{name}} ({{count}} accounts removed)", + "audit_meta_scheduled_deletion": "Scheduled for deletion", + "audit_meta_kept": "Kept for reactivation", + "common_view": "View", + "common_save": "Save", + "common_saving": "Saving...", + "common_back": "Back", + "common_shared_by": "Shared by", + "common_user_avatar": "User Avatar", + "common_toast_saved": "Changes saved successfully", + "pause_reason_shocker": "Paused at shocker level", + "pause_reason_shocker_user_share": "Paused at shocker and user share level", + "pause_reason_shocker_public_share": "Paused at shocker and public share level", + "pause_reason_user_share": "Paused at user share level", + "pause_reason_public_share": "Paused at public share level", + "public_shares_subtitle": "A link anyone can use, no account required.", + "public_shares_new": "New Share", + "public_share_never_expires": "Never expires", + "public_shares_empty_title": "No public shares yet", + "public_shares_empty_desc": "Create a link that anyone can use to control your shockers.", + "public_share_expired": "Expired", + "public_share_no_expiry": "No expiry", + "public_share_label": "Public Share", + "public_share_toast_created": "Created new public share", + "public_share_create_title": "Create public share", + "public_share_toast_deleted": "Deleted public share", + "public_share_delete_title": "Delete public share", + "public_share_delete_desc": "Are you sure you want to delete public share {{name}}?", + "public_share_edit_title": "Public Share: {{name}}", + "public_share_edit_subtitle": "Editing: changes apply when you save.", + "public_share_add_shocker": "Add Shocker", + "public_share_toast_added_one": "Added {{count}} shocker to share", + "public_share_toast_added_other": "Added {{count}} shockers to share", + "public_share_empty_shockers_title": "No shockers in this share", + "public_share_empty_shockers_desc": "Add a shocker and anyone with the link will be able to control it.", + "public_share_load_failed": "Error fetching public share details", + "public_share_paused_here": "Paused for this share", + "public_share_resume_shocker": "Resume shocker", + "public_share_pause_shocker": "Pause shocker", + "public_share_remove": "Remove from share", + "public_share_toast_removed": "Shocker removed from share", + "public_share_add_title": "Add shockers", + "public_share_add_desc": "Add shockers to this public share. You can set their limits once they are added.", + "public_share_add_placeholder": "Select shockers to share...", + "public_share_add_no_match": "No matching shockers", + "public_share_add_submit": "Add Shockers", + "public_share_view_loading": "Loading share details...", + "public_share_view_title": "Public Share Link", + "public_share_view_desc": "Enter as a guest or login with your OpenShock account", + "public_share_view_guest_name": "Guest Name", + "public_share_view_enter": "Enter", + "public_share_view_enter_guest": "Enter as Guest", + "public_share_login": "Login", + "perm_shock_on": "Shock enabled", + "perm_shock_off": "Shock disabled", + "perm_vibrate_on": "Vibrate enabled", + "perm_vibrate_off": "Vibrate disabled", + "perm_sound_on": "Sound enabled", + "perm_sound_off": "Sound disabled", + "perm_live_on": "Live enabled", + "perm_live_off": "Live disabled", + "perm_live_control": "Live Control", + "user_selector_avatar_of": "{{name}}'s avatar", + "user_selector_placeholder": "Enter user name", + "user_selector_aria": "Username to search", + "user_selector_search": "Search user", + "user_selector_found": "User found", + "common_remove": "Remove", + "user_shares_subtitle": "Direct permanent shares with other users.", + "user_shares_toast_invited": "Sent a shocker invite to {{name}}", + "user_shares_redeem": "Redeem Code", + "user_shares_new": "New Share", + "user_shares_tab_shares": "Shares", + "user_shares_tab_incoming": "Shared with Me", + "user_shares_tab_invites": "Invites", + "share_code_create_title": "New share code", + "share_code_create_desc": "Create a Share Code or Invite", + "share_code_shocker_placeholder": "Select shockers to share...", + "share_code_no_match": "No matching shockers", + "share_code_send_invite": "Send Share Invite", + "share_code_create": "Create Share Code", + "share_code_created_title": "Share code generated", + "share_code_created_desc": "Please copy share code or code link!", + "share_code_redeem_title": "Redeem share code", + "share_code_redeem_desc": "Enter the share code to redeem", + "share_code_redeem_placeholder": "Enter share code", + "share_code_redeemed": "Redeemed successfully!", + "share_code_shared_shockers": "Shared shockers", + "share_code_redeeming": "Redeeming...", + "share_code_redeem": "Redeem", + "incoming_shares_empty_title": "Nothing shared with you", + "incoming_shares_empty_desc": "No one has shared a shocker with you yet.", + "incoming_share_toast_removed": "Removed share for {{name}}", + "incoming_share_remove_title": "Remove Share", + "incoming_share_remove_desc": "Are you sure you want to remove the share for {{name}}?", + "incoming_share_toast_removed_shocker": "Removed {{shocker}} shared by {{name}}", + "incoming_share_remove_shocker_title": "Remove this shared shocker?", + "incoming_share_remove_shocker_desc": "Are you sure you want to remove the shocker share {{shocker}} by {{name}}?", + "incoming_share_manage_from": "Manage shares from", + "share_remove": "Remove share", + "invites_empty_title": "No invites yet", + "invites_empty_desc": "You have no incoming or outgoing share invites.", + "invites_outgoing": "Outgoing", + "invites_outgoing_empty_title": "No outgoing invites", + "invites_outgoing_empty_desc": "You have no outgoing share invites.", + "invites_incoming": "Incoming", + "invites_incoming_empty_title": "No incoming invites", + "invites_incoming_empty_desc": "You have no incoming share invites.", + "invite_toast_accepted": "Accepted share invite from {{name}}", + "invite_toast_declined": "Declined share invite from {{name}}", + "invite_deny_title": "Deny Invite", + "invite_deny_label": "Deny Invite", + "invite_deny": "Deny", + "invite_deny_desc": "Are you sure you want to deny the invite from {{name}}?", + "invite_accept": "Accept Invite", + "invite_toast_cancelled_for": "Cancelled invite for {{name}} ({{id}})", + "invite_toast_cancelled": "Cancelled invite {{id}}", + "invite_cancel_title": "Cancel Invite", + "invite_cancel": "Cancel", + "invite_cancel_for_desc": "Are you sure you want to cancel the invite for {{name}}?", + "invite_cancel_code_desc": "Are you sure you want to cancel the invite with code {{code}}?", + "invite_cancel_outstanding": "Cancel Outstanding Invite", + "outgoing_shares_empty_title": "No shared shockers", + "outgoing_shares_empty_desc": "You haven't shared any shockers with other users yet.", + "outgoing_share_toast_removed": "Removed shocker share {{name}}", + "outgoing_share_remove_title": "Stop sharing this shocker?", + "outgoing_share_editing_for": "Editing shares for", + "outgoing_share_limits": "Limits & Permissions", + "outgoing_share_same": "Same restrictions on every shocker", + "outgoing_share_per_desc": "Tune restrictions per shocker", + "outgoing_share_all": "All", + "outgoing_share_per": "Per shocker", + "outgoing_share_remove_desc": "Are you sure you want to stop sharing {{shocker}} with {{name}}?", + "report_breadcrumb": "Report API Tokens", + "report_toast_clipboard_failed": "Failed to read clipboard: {{error}}", + "report_title": "Report Leaked API Tokens", + "report_paste": "Paste from clipboard", + "report_warning": "This form is only for reporting accidentally leaked API tokens.", + "report_abuse_warning": "Intentional abuse will result in bans or severe endpoint restrictions.", + "report_detected": "Detected Tokens", + "report_invalid": "One or more tokens appear to be invalid. Please check for formatting issues.", + "report_acknowledge": "I confirm I understand what this feature is for and accept responsibility.", + "report_submit": "Submit Report", + "turnstile_disabled": "Turnstile disabled", + "common_internal_error": "Internal error", + "resend_toast_sent": "Activation email sent. Check your inbox and spam folder.", + "resend_toast_throttled": "Too many activation emails have been requested. Please try again later.", + "resend_toast_unavailable": "No activation email can be resent from this browser. If your account isn't activated yet, logging in sends a new link.", + "resend_button": "Didn't get the email? Resend", + "expiration_label": "Expiration", + "expiration_never": "Never", + "expiration_custom": "Custom", + "expiration_days_one": "{{count}} Day", + "expiration_days_other": "{{count}} Days", + "expiration_required": "Expire date is required", + "expiration_never_desc": "This will never expire", + "expiration_expires_at": "Expires {{time}} ({{date}})", + "date_picker_placeholder": "Pick a date", + "telemetry_toast_title": "Help improve OpenShock?", + "telemetry_toast_desc": "Send diagnostics to help us fix crashes and slow API calls. Reports include the error message, stack trace and your IP. You can change this any time in Account settings.", + "telemetry_toast_no": "No thanks", + "telemetry_toast_errors": "Errors only", + "telemetry_toast_full": "Full", + "table_show_details": "Show details", + "table_hide_details": "Hide details", + "table_no_results": "No results.", + "table_sort_asc": "Sort by {{name}}, ascending", + "table_sort_desc": "Sort by {{name}}, descending", + "table_sort_none": "Sort by {{name}}, unsorted", + "cell_na": "N/A", + "cell_not_applicable": "Not applicable", + "cell_invalid": "Invalid", + "cell_unavailable": "Unavailable", + "cell_none": "None", + "oauth_login_with": "Login with {{provider}}", + "oauth_signup_with": "Signup with {{provider}}", + "signalr_connect_failed": "Failed to connect to server!", + "signalr_disconnect_failed": "Encountered error while disconnecting from server!", + "signalr_invalid_update": "Received invalid update from server!", + "signalr_invalid_log": "Received invalid log data from server!", + "signalr_invalid_ota": "Received invalid firmware update data from server!", + "ota_toast_failed": "Hub firmware update failed: {{message}}", + "ota_toast_succeeded": "Hub firmware update completed successfully!", + "ota_toast_rolled_back": "Hub firmware rolled back to previous version", + "lcg_connect_failed": "Failed to connect to live control gateway", + "terminal_toast_bootloader_failed": "Failed to enter bootloader: {{error}}", + "terminal_toast_app_mode_failed": "Failed to enter application mode: {{error}}", + "problem_account_account_not_activated_title": "Account not activated", + "problem_account_account_not_activated_desc": "Check your inbox for the activation email.", + "problem_account_activation_not_found_title": "Activation link is invalid", + "problem_account_activation_not_found_desc": "The link may have expired or already been used.", + "problem_account_activation_resend_too_many_title": "Too many activation emails requested", + "problem_account_activation_resend_too_many_desc": "Please wait a while before trying again.", + "problem_account_activation_resend_unavailable_title": "Cannot resend activation email", + "problem_account_activation_resend_unavailable_desc": "Log in again to request a new activation link.", + "problem_account_deactivate_already_deactivated_title": "Account is already deactivated", + "problem_account_deactivate_denied_privileged_title": "Privileged accounts cannot be deactivated", + "problem_account_deactivate_unauthorized_title": "You are not allowed to do this", + "problem_account_deactivated_title": "This account has been deactivated", + "problem_account_email_already_in_use_title": "That email address is already in use", + "problem_account_email_invalid_title": "That email address is not valid", + "problem_account_email_taken_title": "That email address is already in use", + "problem_account_email_too_many_requests_title": "Too many email change requests", + "problem_account_email_too_many_requests_desc": "Please wait a while before trying again.", + "problem_account_email_unchanged_title": "That is already your email address", + "problem_account_email_verify_not_found_title": "Verification link is invalid", + "problem_account_email_verify_not_found_desc": "The link may have expired or already been used.", + "problem_account_o_auth_only_title": "This account has no password", + "problem_account_o_auth_only_desc": "Sign in with the provider you signed up with.", + "problem_account_password_not_set_title": "No password set", + "problem_account_password_not_set_desc": "This account signs in through an external provider.", + "problem_account_password_old_password_invalid_title": "Current password is incorrect", + "problem_account_username_invalid_title": "That username is not allowed", + "problem_account_username_recently_changed_title": "Username changed too recently", + "problem_account_username_recently_changed_desc": "You can change your username once every 7 days.", + "problem_account_username_taken_title": "That username is already taken", + "problem_admin_user_deactivated_title": "This user is deactivated", + "problem_admin_user_not_activated_title": "This user has not been activated yet", + "problem_api_token_can_only_delete_self_title": "An API token can only delete itself", + "problem_api_token_not_found_title": "API token not found", + "problem_api_token_paused_title": "This API token is paused", + "problem_assign_lcg_bad_schema_version_title": "Unsupported hub protocol version", + "problem_assign_lcg_bad_schema_version_desc": "Update the hub firmware to connect.", + "problem_assign_lcg_no_lcg_available_title": "No gateway available", + "problem_assign_lcg_no_lcg_available_desc": "No live control gateway is available right now. Please try again later.", + "problem_authentication_account_deactivated_title": "This account has been deactivated", + "problem_authentication_account_not_activated_title": "This account has not been activated", + "problem_authentication_cookie_missing_or_invalid_title": "You are not logged in", + "problem_authentication_cookie_missing_or_invalid_desc": "Your session may have expired. Please log in again.", + "problem_authentication_header_missing_or_invalid_title": "Invalid API token", + "problem_authentication_session_invalid_title": "Session expired", + "problem_authentication_session_invalid_desc": "Please log in again.", + "problem_authentication_token_invalid_title": "Invalid API token", + "problem_authentication_unknown_error_title": "Authentication failed", + "problem_authorization_policy_not_met_title": "You do not have permission to do this", + "problem_authorization_token_only_title": "This action requires an API token", + "problem_authorization_token_permission_missing_title": "This API token is missing a required permission", + "problem_authorization_unknown_error_title": "Authorization failed", + "problem_authorization_user_session_only_title": "This action requires a logged-in session", + "problem_automation_token_not_allowed_for_account_title": "Automation tokens cannot be used with privileged accounts", + "problem_configuration_already_exists_title": "A configuration entry with that name already exists", + "problem_configuration_invalid_name_format_title": "Invalid configuration name", + "problem_configuration_invalid_name_format_desc": "Only A to Z and underscores are allowed.", + "problem_configuration_invalid_value_format_title": "Value does not match the configuration type", + "problem_configuration_not_found_title": "Configuration entry not found", + "problem_control_stats_invalid_range_title": "The from date must not be after the to date", + "problem_control_stats_invalid_time_zone_title": "Unknown time zone", + "problem_control_stats_missing_capability_title": "Control statistics are not available on this server", + "problem_device_not_found_title": "Hub not found", + "problem_device_not_online_title": "Hub is offline", + "problem_device_too_many_hubs_title": "You have reached the maximum number of hubs", + "problem_device_too_many_shockers_title": "This hub has reached its maximum number of shockers", + "problem_endpoint_retired_title": "This feature is no longer available", + "problem_expression_error_title": "Invalid filter expression", + "problem_internal_server_error_title": "Something went wrong on our end", + "problem_login_invalid_credentials_title": "Invalid username or password", + "problem_login_invalid_domain_title": "Logging in from this address is not allowed", + "problem_o_auth_connection_already_exists_title": "Your account is already connected to this provider", + "problem_o_auth_connection_already_linked_title": "This external account is already linked to another user", + "problem_o_auth_flow_anonymous_only_title": "You are already signed in", + "problem_o_auth_flow_mismatch_title": "Sign-in attempt does not match", + "problem_o_auth_flow_mismatch_desc": "Please start over.", + "problem_o_auth_flow_missing_data_title": "The provider did not return your account details", + "problem_o_auth_flow_missing_data_desc": "Please try again.", + "problem_o_auth_flow_not_found_title": "Sign-in attempt expired", + "problem_o_auth_flow_not_found_desc": "Please start over.", + "problem_o_auth_flow_unsupported_title": "Unsupported sign-in flow", + "problem_o_auth_internal_error_title": "Something went wrong during sign-in", + "problem_o_auth_internal_error_desc": "Please try again in a moment.", + "problem_o_auth_link_authenticated_user_only_title": "You must be signed in to link an external account", + "problem_o_auth_provider_mismatch_title": "Sign-in attempt does not match the provider", + "problem_o_auth_provider_mismatch_desc": "Please start over.", + "problem_o_auth_provider_unsupported_title": "This sign-in provider is not supported", + "problem_pair_code_not_found_title": "Pair code not found", + "problem_password_reset_not_found_title": "Password reset link is invalid", + "problem_password_reset_not_found_desc": "The link may have expired or already been used.", + "problem_session_not_found_title": "Session not found", + "problem_share_get_no_shares_title": "You have no shares with this user", + "problem_share_request_create_cannot_share_with_self_title": "You cannot share with yourself", + "problem_share_request_create_shocker_not_found_title": "One or more shockers were not found", + "problem_share_request_create_shocker_not_found_desc": "They may have been removed or do not belong to you.", + "problem_share_request_not_found_title": "Share invite not found", + "problem_share_user_not_found_title": "Share not found", + "problem_share_code_already_linked_title": "Shocker is already linked to your account", + "problem_share_code_cant_link_own_share_code_title": "You cannot redeem your own share code", + "problem_share_code_not_found_title": "Share code not found", + "problem_share_link_expiry_date_in_past_title": "Expiry date cannot be in the past", + "problem_share_link_not_found_title": "Public share not found", + "problem_share_link_shocker_already_in_share_link_title": "Shocker is already in this public share", + "problem_share_link_shocker_not_in_share_link_title": "Shocker is not in this public share", + "problem_shocker_control_no_permission_title": "You do not have permission to control this shocker", + "problem_shocker_control_not_found_title": "Shocker not found", + "problem_shocker_control_paused_title": "Shocker is paused", + "problem_shocker_not_found_title": "Shocker not found", + "problem_signup_registration_disabled_title": "Registration is currently disabled", + "problem_signup_username_or_email_exists_title": "That username or email is already in use", + "problem_turnstile_invalid_title": "Verification failed", + "problem_turnstile_invalid_desc": "Please complete the challenge again and retry.", + "problem_user_not_found_title": "User not found", + "problem_user_privileged_delete_denied_title": "Privileged users cannot be deleted", + "problem_validation_error_title": "Some fields are invalid", + "problem_webhook_not_found_title": "Webhook not found", + "problem_webhook_unsupported_title": "Only Discord webhooks are supported", + "problem_webhook_unsupported_desc": "Use a discord.com URL, not canary or ptb.", + "error_too_many_requests": "Too many requests", + "error_retry_after_one": "Try again in {{count}} second.", + "error_retry_after_other": "Try again in {{count}} seconds.", + "error_unexpected_response": "Unexpected server response", + "error_internal": "Internal error occurred", + "error_network": "Network error occurred", + "dev_banner": "This is the OpenShock DEVELOPMENT environment. No data is saved, and it is regularly overwritten by production data.", + "firmware_channel_bugs_warning": "This channel might contain bugs." +} From ac79149737085ed0a28e1a390b315eda3494558e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Luc=20=E2=99=A5?= Date: Thu, 12 Nov 2026 17:43:19 +0100 Subject: [PATCH 14/27] New translations en.json (Italian) [ci skip] --- messages/it.json | 1055 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 1055 insertions(+) create mode 100644 messages/it.json diff --git a/messages/it.json b/messages/it.json new file mode 100644 index 00000000..ef4df56c --- /dev/null +++ b/messages/it.json @@ -0,0 +1,1055 @@ +{ + "landing_tagline": "The go-to platform for safe, reliable, real low-latency remote shocking.", + "landing_section_label": "Home", + "landing_hubs_online": "Hubs online right now: ", + "landing_learn_more": "Learn More", + "landing_wiki": "Wiki", + "landing_meta_description": "Welcome to OpenShock, a free and open-source ecosystem to control various shock collars over the internet.", + "instance_meta_description": "Welcome to {{siteName}}, an independent instance of OpenShock, a free and open-source ecosystem to control various shock collars over the internet.", + "header_sidebar_toggle": "Toggle Sidebar", + "header_avatar_alt": "{{name}}'s avatar", + "header_menu_profile": "Profile", + "header_menu_settings": "Settings", + "header_menu_logout": "Logout", + "header_login": "Login", + "header_signup": "Sign Up", + "header_github_title": "OpenShock on GitHub", + "header_discord_title": "Community Discord", + "footer_made_with": "Made with by the OpenShock Team", + "footer_connection_status_label": "Server connection status", + "footer_signalr_state": "SignalR State", + "footer_frontend_version": "Frontend Version", + "footer_frontend_commit_title": "Commit {{commit}}", + "footer_backend_version": "Backend Version", + "footer_backend_commit_title": "Commit {{commit}}", + "footer_language_label": "Language", + "sidebar_home_link_label": "OpenShock home", + "sidebar_group_general": "General", + "sidebar_home": "Home", + "sidebar_shockers": "Shockers", + "sidebar_shared_shockers": "Shared Shockers", + "sidebar_hubs": "Hubs", + "sidebar_user_shares": "User Shares", + "sidebar_public_shares": "Public Shares", + "sidebar_serial_terminal": "Serial Terminal", + "sidebar_group_admin": "Admin", + "sidebar_admin_monitoring": "Monitoring", + "sidebar_admin_online_hubs": "Online Hubs", + "sidebar_admin_online_gateways": "Online Gateways", + "sidebar_admin_management": "Management", + "sidebar_admin_users": "Users", + "sidebar_admin_blacklists": "Blacklists", + "sidebar_admin_webhooks": "Webhooks", + "sidebar_admin_mail": "Mail", + "sidebar_admin_automation_tokens": "Automation Tokens", + "sidebar_admin_configuration": "Configuration", + "sidebar_group_settings": "Settings", + "sidebar_settings_api_tokens": "API Tokens", + "sidebar_settings_sessions": "Sessions", + "sidebar_settings_audit_log": "Audit Log", + "sidebar_settings_connections": "Connections", + "sidebar_settings_account": "Account Settings", + "error_meta_title": "Service Unavailable", + "error_meta_description": "OpenShock is currently unavailable", + "error_meta_logo_alt": "OpenShock Logo", + "error_fallback_message": "Something went wrong.", + "error_not_found_message": "Page not found", + "error_not_found_description": "The page you're looking for doesn't exist.", + "error_unexpected_description": "An unexpected error occurred.", + "error_go_back": "Go back", + "auth_layout_logo_alt": "OpenShock Logo", + "auth_layout_invalid_redirect_removed": "An invalid redirect URL was removed for your safety.", + "auth_activate_breadcrumb": "Activate Account", + "auth_activate_title": "Activate Account", + "auth_activate_activating": "Activating your account...", + "auth_activate_success": "Your account has been activated", + "auth_activate_failed": "This activation link is invalid or has expired", + "auth_activate_missing_token": "Missing activation token", + "auth_activate_continue": "Continue to login", + "auth_activate_toast_success": "Account activated", + "auth_forgot_breadcrumb": "Forgot Password", + "auth_forgot_title": "Forgot Password", + "auth_forgot_description": "Enter your email to reset your password", + "auth_forgot_email_label": "Email", + "auth_forgot_email_placeholder": "Email", + "auth_forgot_submit": "Reset Password", + "auth_forgot_signin_prompt": "Remember your password? Sign in", + "auth_forgot_mail_disabled": "Password resets are unavailable on this instance because it has no mail provider configured. Please contact your administrator for help recovering your account.", + "auth_forgot_toast_sent": "Reset password request has been sent to the given email", + "auth_login_breadcrumb": "Login", + "auth_login_title": "Welcome back", + "auth_login_loading_methods": "Loading available login methods", + "auth_login_choose_method": "Login with one of these methods", + "auth_login_with_account": "Login with your OpenShock Account", + "auth_login_activation_after_signup": "Your account has been created. We've sent an activation link to your email address. Check your inbox and spam folder.", + "auth_login_activation_pending": "Your account isn't activated yet. We've sent an activation link to your email address. Check your inbox and spam folder. If nothing arrives, try logging in again later to get a new link.", + "auth_login_oauth_only": "This account has no password. Sign in with the provider you signed up with.", + "auth_login_oauth_only_with_buttons": "This account has no password. Sign in with the provider you signed up with using the buttons above.", + "auth_login_or_continue_with": "Or continue with", + "auth_login_username_label": "Username or Email", + "auth_login_password_label": "Password", + "auth_login_submit": "Login", + "auth_login_signup_prompt": "Don't have an account? Sign up", + "auth_login_legal": "By clicking Login, you agree to our Terms of Service and Privacy Policy.", + "auth_oauth_create_breadcrumb": "Sign Up With {{provider}}", + "auth_oauth_create_title": "Sign Up With {{provider}}", + "auth_oauth_create_description": "Complete your account details", + "auth_oauth_create_username_label": "Username", + "auth_oauth_create_username_placeholder": "Username", + "auth_oauth_create_email_label": "Email", + "auth_oauth_create_email_placeholder": "Email", + "auth_oauth_create_submit": "Sign Up", + "auth_oauth_create_legal": "By clicking Sign Up, you agree to our Terms of Service and Privacy Policy.", + "auth_oauth_error_breadcrumb": "Authentication Error", + "auth_oauth_error_title": "Authentication Error", + "auth_oauth_error_back": "Back to login", + "auth_reset_breadcrumb": "Reset Password", + "auth_reset_title": "Reset Password", + "auth_reset_checking": "Verifying reset link...", + "auth_reset_choose_password": "Choose a new password for your account", + "auth_reset_invalid": "This reset link is invalid or has expired", + "auth_reset_password_label": "New Password", + "auth_reset_password_placeholder": "New Password", + "auth_reset_confirm_label": "Confirm New Password", + "auth_reset_confirm_placeholder": "Confirm New Password", + "auth_reset_submit": "Reset Password", + "auth_reset_request_new": "Request a new reset link", + "auth_reset_toast_success": "Password has been reset", + "auth_signup_breadcrumb": "Sign Up", + "auth_signup_toast_created_mail": "Account created successfully. Please check your email to verify your account.", + "auth_signup_toast_created_no_mail": "Account created successfully. You can log in now.", + "auth_signup_dialog_title": "Welcome! Thank you for signing up! ❤️", + "auth_signup_dialog_created_mail": "Your account has been created. 🎉 Please check your email to verify your account.", + "auth_signup_dialog_verify_then_login": "After verifying your email, you can log in to your account.", + "auth_signup_dialog_created_no_mail": "Your account has been created and is ready to use. 🎉", + "auth_signup_dialog_login_now": "You can log in to your account now.", + "auth_signup_title": "Create your account", + "auth_signup_loading_methods": "Loading available sign-up methods", + "auth_signup_using_email": "Signing up using email", + "auth_signup_choose_method": "Choose your preferred sign-up method", + "auth_signup_back": "Back", + "auth_signup_username_label": "Username", + "auth_signup_username_placeholder": "John OpenShock", + "auth_signup_email_label": "Email", + "auth_signup_email_placeholder": "john@example.com", + "auth_signup_password_label": "Password", + "auth_signup_password_placeholder": "Password", + "auth_signup_confirm_label": "Confirm Password", + "auth_signup_confirm_placeholder": "Confirm Password", + "auth_signup_submit": "Create Account", + "auth_signup_signin_prompt": "Already have an account? Sign in", + "auth_signup_or": "Or", + "auth_signup_with_email": "Signup with Email", + "auth_signup_legal": "By clicking Create Account, you agree to our Terms of Service and Privacy Policy.", + "auth_verify_breadcrumb": "Verify Email", + "auth_verify_title": "Verify Email", + "auth_verify_verifying": "Verifying your email address...", + "auth_verify_success": "Your email has been verified", + "auth_verify_failed": "This verification link is invalid or has expired", + "auth_verify_missing_token": "Missing verification token", + "auth_verify_continue": "Continue to login", + "auth_verify_toast_success": "Email verified", + "common_cancel": "Cancel", + "common_delete": "Delete", + "common_edit": "Edit", + "common_share": "Share", + "common_copy_id": "Copy ID", + "common_id_copied": "ID copied to clipboard", + "common_open_menu": "Open menu", + "common_refresh": "Refresh", + "common_settings": "Settings", + "common_clear": "Clear", + "common_online": "Online", + "common_offline": "Offline", + "common_paused": "Paused", + "common_resume": "Resume", + "common_resuming": "Resuming...", + "common_coming_soon": "(Coming soon)", + "common_save_changes": "Save Changes", + "common_danger_zone": "Danger Zone", + "common_name": "Name", + "control_intensity": "Intensity", + "control_duration": "Duration", + "control_max_intensity": "Max Intensity", + "control_max_duration": "Max Duration", + "control_vibration": "Vibration", + "control_value": "Value", + "control_live_intensity": "Live intensity", + "control_type_stop": "Stop", + "control_type_shock": "Shock", + "control_type_vibrate": "Vibrate", + "control_type_sound": "Sound", + "live_tooltip_active": "Live via {{gateway}} ({{country}}), {{latency}}ms", + "live_tooltip_connecting": "Connecting...", + "live_tooltip_connect": "Connect to Live Control", + "live_tooltip_hub_start": "Ctrl+click to start the whole hub", + "live_tooltip_hub_stop": "Ctrl+click to stop the whole hub", + "pause_resume_shocker": "Resume shocker", + "pause_pause_shocker": "Pause shocker", + "pause_resume_all": "Resume all shockers", + "pause_pause_all": "Pause all shockers", + "shocker_label": "Shocker", + "shocker_hub": "Hub", + "shocker_select_hub": "Select hub", + "shocker_rf_id": "RF ID", + "shocker_rf_id_invalid": "RF ID must be a whole number between {{min}} and {{max}}.", + "shocker_model": "Model", + "shocker_select_model": "Select model", + "shocker_name_placeholder": "Shocker name", + "shocker_menu_view_logs": "View Logs", + "shocker_delete_title": "Delete Shocker", + "shocker_delete_desc": "Are you sure you want to delete \"{{name}}\"? This action cannot be undone.", + "shocker_toast_deleted": "Shocker \"{{name}}\" deleted", + "shocker_toast_paused": "Shocker paused", + "shocker_toast_resumed": "Shocker resumed", + "shocker_add_desc": "Register a new shocker to one of your hubs.", + "shocker_add_name_placeholder": "My Shocker", + "shockers_title": "Shockers", + "shockers_subtitle": "Every shocker paired to your hubs.", + "shockers_loading": "Loading shockers...", + "shockers_toast_refreshed": "Shockers refreshed", + "shockers_toast_need_hub": "You need to create a hub before adding shockers.", + "shockers_toast_added": "Shocker added", + "shockers_unknown_module": "Unknown module type", + "shockers_add": "Add Shocker", + "shockers_view_mode": "View mode", + "shockers_mode_classic": "Classic", + "shockers_mode_rich": "Rich", + "shockers_mode_simple": "Simple", + "shockers_mode_map": "Map", + "shockers_group_by_hub": "Group by Hub", + "shockers_global_limits": "Global Limits", + "shockers_logs_label": "Logs", + "shockers_empty_title": "No shockers yet", + "shockers_empty_no_hubs": "Create a hub first, then add shockers to it.", + "shockers_empty_has_hubs": "Add a shocker to one of your hubs to get started.", + "shockers_create_hub": "Create a Hub", + "shockers_count_one": "{{count}} shocker", + "shockers_count_other": "{{count}} shockers", + "shared_shockers_title": "Shared Shockers", + "shared_shockers_subtitle": "Shockers other users have shared with you.", + "shared_shockers_empty_title": "No shockers have been shared with you yet.", + "shared_shockers_empty_desc": "When someone shares their shockers with you, they'll appear here.", + "shocker_logs_title": "Shocker Logs", + "shocker_logs_subtitle": "Every control command sent to your shockers.", + "shocker_logs_live_title": "New logs appear in real time", + "shocker_logs_paused_title": "Live updates pause when sorting or viewing a page other than the first", + "shocker_logs_live": "Live", + "shocker_logs_col_time": "Time", + "shocker_logs_col_type": "Type", + "shocker_logs_col_by": "By", + "shocker_logs_filter_label": "Filter by shocker", + "shocker_logs_filter_placeholder": "Search shockers...", + "shocker_logs_filter_all": "All shockers", + "shocker_logs_filter_none": "No matching shockers", + "shocker_edit_title": "Edit Shocker", + "shocker_edit_subtitle": "Change this shocker's details or remove it.", + "shocker_edit_back": "Back to Shockers", + "shocker_edit_load_failed": "Failed to load shocker.", + "shocker_edit_loading": "Loading shocker...", + "shocker_edit_details_title": "Shocker Details", + "shocker_edit_details_desc": "Update the name, RF ID, and model for this shocker.", + "shocker_edit_pause_state": "Pause State", + "shocker_edit_is_paused": "Shocker is paused", + "shocker_edit_is_active": "Shocker is active", + "shocker_edit_toast_updated": "Shocker updated", + "shocker_edit_delete_desc": "Permanently delete this shocker. This action cannot be undone.", + "common_close": "Close", + "common_continue": "Continue", + "common_loading": "Loading...", + "common_previous": "Previous", + "common_next": "Next", + "common_steps": "Steps", + "common_step_label": "Step {{number}}: {{title}}", + "common_copy": "Copy", + "common_copied": "Copied", + "common_never": "Never", + "common_error": "Error: {{message}}", + "terminal_title": "Serial Terminal", + "terminal_connecting": "Connecting...", + "terminal_help_button": "I'm having trouble, help?", + "terminal_back_to_modes": "Back to mode picker", + "terminal_mode_configure": "Configure Device", + "terminal_mode_configure_desc": "Configure WiFi, authentication, and more. Includes an interactive serial console.", + "terminal_mode_flash": "Flash Firmware", + "terminal_mode_flash_desc": "Install or update firmware on a connected device.", + "terminal_mode_raw": "Serial Monitor", + "terminal_mode_raw_desc": "Just the console. Read device logs and send commands.", + "terminal_step_channel": "Select Channel", + "terminal_step_board": "Select Board", + "terminal_go_to_step": "Go to step {{number}}: {{title}}", + "terminal_erase": "Erase before flashing", + "terminal_erase_desc": "Clears all data on the device including existing configs", + "terminal_unsupported": "Your browser does not support this feature.", + "terminal_update_browser": "Please update your browser to the latest version.", + "terminal_use_browsers": "Please use one of the following browsers:", + "terminal_connect_failed_bootloader": "Could not enter bootloader mode", + "terminal_connect_failed": "Device connection failed", + "terminal_connect_failed_desc": "We couldn't establish a serial connection with the device.", + "terminal_quick_tries": "Quick things to try:", + "terminal_try_replug": "Unplug and replug the device.", + "terminal_try_cable": "Try a different USB cable or port.", + "terminal_try_driver": "Make sure the serial driver is installed.", + "terminal_open_troubleshooter": "Open troubleshooter", + "terminal_log_reset_no_device": "Host-side error during reset: no device!", + "terminal_log_reset_error": "Host-side error during reset: {{error}}", + "terminal_log_send_no_device": "Couldn't send: no device!", + "terminal_log_send_error": "Couldn't send: {{error}}", + "terminal_log_firmware_disconnected": "Firmware disconnected: {{error}}", + "terminal_log_erase_failed": "Failed to erase flash: {{error}}", + "terminal_log_hard_reset_failed": "Failed to hard reset: {{error}}", + "terminal_log_flash_complete": "Flash complete", + "terminal_log_flash_failed": "Failed to flash: {{error}}", + "terminal_log_command_failed": "Failed to write application command: {{error}}", + "terminal_help_title": "Troubleshooter", + "terminal_help_desc": "Work through these steps in order. Each one rules out a common cause.", + "terminal_help_step_cable": "USB cable", + "terminal_help_step_port": "USB port", + "terminal_help_step_driver": "Install driver", + "terminal_help_step_manual": "Manual driver update", + "terminal_help_step_discord": "Ask on Discord", + "terminal_help_cable_body": "Many USB-C and micro-USB cables are charge-only and don't carry data. Swap to a known-good data cable (one you've used to transfer files or connect other devices) and reconnect the hub.", + "terminal_help_port_body": "Plug the device directly into a USB port on your computer. Avoid USB hubs, docking stations, and front-panel ports if possible; these are common sources of power and signal issues. If you're on a desktop, try a port on the back of the machine.", + "terminal_help_driver_download": "Download the CP210x driver:", + "terminal_help_driver_extract": "Extract the contents of the zip file to a folder on your computer.", + "terminal_help_driver_run": "Open the folder and run {{installer}}. Follow the prompts to install.", + "terminal_help_driver_reconnect": "Reconnect the device.", + "terminal_help_manual_intro": "If the driver installer ran but the device still doesn't show up:", + "terminal_help_manual_open": "Open Device Manager (press Win + X and select Device Manager).", + "terminal_help_manual_ports": "Under Ports (COM & LPT), look for an entry like:", + "terminal_help_manual_missing": "If it's missing, the device isn't being detected by Windows at all; revisit the cable and port steps.", + "terminal_help_manual_update": "Right-click the device and pick Update Driver.", + "terminal_help_manual_browse": "Choose Browse my computer for drivers and select the folder you extracted the driver zip into. Make sure Include subfolders is checked.", + "terminal_help_manual_success": "On success, the entry should now read {{deviceName}}.", + "terminal_help_discord_intro": "Still stuck after all of the above? Hop into our Discord server and ask in the {{channel}} channel. Please include:", + "terminal_help_discord_os": "your operating system and browser", + "terminal_help_discord_device": "the device you're using (board model, where you got it)", + "terminal_help_discord_tried": "what you've already tried from the previous steps", + "terminal_help_discord_errors": "any error messages or relevant terminal output", + "terminal_help_discord_join": "Join our Discord server", + "terminal_risk_title": "⚠️ UNSTABLE FIRMWARE", + "terminal_risk_intro": "You are about to flash experimental firmware that is known to be unstable.", + "terminal_risk_brick": "This may permanently brick your device, require manual recovery, or render it unusable.", + "terminal_risk_no_support": "We will NOT provide support for issues caused by this firmware.", + "terminal_risk_acknowledge": "I understand this is entirely my responsibility", + "terminal_risk_abort": "Abort", + "terminal_risk_accept": "I ACCEPT FULL RESPONSIBILITY", + "firmware_channel_recommended": "This is the recommended channel.", + "firmware_channel_danger": "DO NOT USE THIS UNLESS YOU KNOW WHAT YOU ARE DOING", + "firmware_channel_stable": "Stable", + "firmware_channel_beta": "Beta", + "firmware_channel_develop": "Develop", + "terminal_board_select": "Select a board...", + "terminal_board_search": "Search boards...", + "terminal_board_none": "No board found.", + "terminal_flash_button": "Flash", + "terminal_flash_progress": "Flash Progress: {{status}}", + "terminal_flash_idle": "Idle", + "terminal_flash_no_device": "No device selected.", + "terminal_flash_resetting": "Resetting...", + "terminal_flash_downloading": "Downloading firmware...", + "terminal_flash_download_failed": "Failed to download firmware.", + "terminal_flash_flashing": "Flashing firmware...", + "terminal_flash_rebooting": "Rebooting device... (Reconnect to power manually if stuck)", + "terminal_flash_done": "Rebooted device! Flashing complete.", + "terminal_port_select": "Select Device", + "terminal_port_disconnect": "Disconnect Device", + "terminal_port_connected": "Device connected: {{id}}", + "terminal_console": "Console", + "terminal_connected_device": "Connected device", + "terminal_resize": "Resize terminal panel", + "terminal_reboot": "Reboot", + "terminal_disconnect": "Disconnect", + "terminal_fullscreen_exit_esc": "Exit fullscreen (Esc)", + "terminal_fullscreen_exit": "Exit fullscreen", + "terminal_fullscreen_fill": "Fill the window", + "terminal_command_label": "Serial command", + "terminal_command_placeholder": "Type a command...", + "terminal_command_send": "Send command", + "terminal_colors": "Colors", + "terminal_colors_menu": "Colors...", + "terminal_colors_label": "Console colors", + "terminal_colors_close": "Close colors", + "terminal_color_input": "{{name}} color", + "terminal_colors_reset": "Reset to defaults", + "terminal_color_bg": "Background", + "terminal_color_fg": "Text", + "terminal_color_ts": "Timestamp", + "terminal_color_error": "Error", + "terminal_color_warning": "Warning", + "terminal_color_info": "Info", + "terminal_color_debug": "Debug", + "terminal_color_verbose": "Verbose", + "terminal_options": "Options", + "terminal_options_label": "Console options", + "terminal_hide_system": "Hide system messages", + "terminal_stick_bottom": "Stick to bottom", + "terminal_raw_output": "Raw output", + "terminal_timestamps": "Timestamps", + "terminal_timestamp_uptime": "Uptime", + "terminal_timestamp_local": "Local", + "terminal_timestamp_ms": "Ms", + "terminal_timestamp_off": "Off", + "terminal_copy_settings": "Copy settings", + "terminal_import_settings": "Import settings", + "terminal_copy_selection": "Copy selection", + "terminal_copy_all": "Copy all output", + "terminal_toast_selection_copied": "Selection copied", + "terminal_toast_output_copied": "Console output copied", + "terminal_toast_settings_copied": "Console settings copied", + "terminal_toast_clipboard_unreadable": "Could not read the clipboard", + "terminal_toast_settings_imported": "Console settings imported", + "terminal_toast_settings_invalid": "Clipboard does not contain console settings", + "common_try_again": "Try again", + "terminal_cfg_intro": "Values are sent to the device via UART. Read the device's response in the console below. Commands without an argument act as getters; use the button next to each field to read the current value.", + "terminal_cfg_rf_title": "RF Transmitter", + "terminal_cfg_rf_desc": "Controls the shocker RF output.", + "terminal_cfg_tx_pin": "TX GPIO pin", + "terminal_cfg_example": "e.g. {{value}}", + "terminal_cfg_read_value": "Read current value", + "terminal_cfg_set": "Set", + "terminal_cfg_read": "Read", + "terminal_cfg_reading": "Reading…", + "terminal_cfg_apply": "Apply", + "terminal_cfg_keepalive": "Keepalive enabled", + "terminal_cfg_keepalive_desc": "Periodically pings paired shockers to keep them awake.", + "terminal_cfg_estop_title": "Emergency Stop", + "terminal_cfg_estop_desc": "Hardware button that halts all output.", + "terminal_cfg_estop_enabled": "EStop enabled", + "terminal_cfg_estop_pin": "EStop GPIO pin", + "terminal_cfg_estop_note": "Note: {{latching}} and {{active}} have no dedicated commands; set them via the JSON config below.", + "terminal_cfg_wifi_title": "WiFi", + "terminal_cfg_wifi_desc": "Station credentials and device hostname.", + "terminal_cfg_hostname": "Hostname", + "terminal_cfg_networks": "Networks (JSON array)", + "terminal_cfg_invalid_json_array": "Must be a valid JSON array", + "terminal_cfg_ap_note": "AP settings ({{ssid}}, {{password}}, {{disabled}}, {{staDisabled}}, {{offlineMode}}) have no dedicated commands; use the JSON config.", + "terminal_cfg_backend_title": "Backend", + "terminal_cfg_backend_desc": "OpenShock server and authentication.", + "terminal_cfg_domain": "Domain", + "terminal_cfg_domain_restart": "Setting the domain will restart the device.", + "terminal_cfg_auth_token": "Auth token", + "terminal_cfg_auth_token_placeholder": "Paste device token", + "terminal_cfg_hide": "Hide", + "terminal_cfg_show": "Show", + "terminal_cfg_serial_title": "Serial Input", + "terminal_cfg_echo": "Echo enabled", + "terminal_cfg_echo_desc": "Print typed characters back to the console.", + "terminal_cfg_advanced_title": "Advanced: full config", + "terminal_cfg_advanced_desc": "For fields without dedicated commands (captive portal, OTA, LAN, etc.), replace the entire config.", + "terminal_cfg_json_config": "JSON config", + "terminal_cfg_invalid_json": "Must be valid JSON", + "terminal_cfg_read_json": "Read current config as JSON", + "terminal_cfg_json_restart": "Applying a JSON config will restart the device.", + "terminal_cfg_raw_config": "Raw FlatBuffer config (base64)", + "terminal_cfg_invalid_base64": "Must be a valid base64 string", + "terminal_cfg_read_raw": "Read current config as base64", + "terminal_cfg_factory_reset": "Factory reset", + "terminal_cfg_factory_reset_desc": "Wipes the entire device configuration.", + "terminal_cfg_factory_reset_title": "Factory reset device?", + "terminal_cfg_factory_reset_action": "Wipe config", + "terminal_cfg_factory_reset_confirm": "This will erase all configuration on the device; WiFi networks, backend credentials, pins, and all other settings. The device will be reset to defaults.", + "terminal_cfg_read_failed_json_title": "Couldn't read the JSON config", + "terminal_cfg_read_failed_raw_title": "Couldn't read the raw config", + "terminal_cfg_read_failed_desc": "The device didn't respond after {{attempts}} attempts.", + "terminal_cfg_common_causes": "Common causes:", + "terminal_cfg_cause_busy": "The device is busy handling another command.", + "terminal_cfg_cause_disconnected": "The device disconnected or rebooted.", + "terminal_cfg_cause_unsupported": "The firmware version doesn't support this command.", + "common_status": "Status", + "common_version": "Version", + "common_created": "Created", + "common_create": "Create", + "common_done": "Done", + "common_enable": "Enable", + "common_disable": "Disable", + "common_are_you_sure": "Are you sure?", + "common_generating": "Generating...", + "hubs_title": "Hubs", + "hubs_subtitle": "Every hub registered to your account.", + "hubs_add": "Add Hub", + "hubs_load_failed": "Failed to load hubs.", + "hubs_empty_title": "No hubs yet", + "hubs_empty_desc": "A hub is the device that relays commands to your shockers. Add one to get started.", + "hubs_create_title": "Create hub", + "hubs_name_label": "Hub Name", + "hubs_name_placeholder": "My Hub", + "hub_toast_not_connected": "Not connected to the server", + "hub_toast_try_later": "Try again in a moment.", + "hub_reboot_title": "Reboot {{name}}?", + "hub_reboot_desc": "The hub will disconnect and restart. Any shockers paired to it stop responding until it comes back online.", + "hub_reboot": "Reboot", + "hub_hotspot_enable_title": "Enable Wi-Fi hotspot on {{name}}?", + "hub_hotspot_disable_title": "Disable Wi-Fi hotspot on {{name}}?", + "hub_hotspot_enable_desc": "The hub broadcasts its own setup network. It stays reachable on your Wi-Fi, but the hotspot is open to anyone in range until you turn it off.", + "hub_hotspot_disable_desc": "The setup hotspot shuts down. If the hub is not already on your Wi-Fi you will need physical access to set it up again.", + "hub_delete_desc": "You are about to delete hub {{name}}.", + "hub_delete_shockers": "This will also delete the following shockers:", + "hub_edit_title": "Edit hub", + "hub_edit_apply": "Apply", + "hub_pair_title_generate": "Generate pair code?", + "hub_pair_title_generated": "Pair code generated", + "hub_pair_title_paired": "Hub paired", + "hub_pair_consumed": "{{name}} consumed this pair code and is now paired.", + "hub_pair_used": "The code has been used and is no longer valid.", + "hub_pair_generated_for": "Pair code generated for {{name}}.", + "hub_copy_now": "The code below will not be accessible later, please copy it now and update clients with it.", + "hub_pair_generate_for": "You are about to generate a pair code for {{name}}.", + "hub_pair_valid_for": "It will be valid for 15 minutes after its creation.", + "hub_pair_one_active": "There is only one active pair code per hub, newly generated ones will override the older active ones.", + "hub_pair_complete": "Pairing complete", + "hub_pair_code_label": "Pair code:", + "hub_pair_copied_close": "Code has been copied, close", + "hub_pair_get": "Get Pair Code", + "hub_token_generated": "Token generated", + "hub_token_generated_for": "New token generated for {{name}}.", + "hub_token_regenerate_for": "You are about to regenerate the token for {{name}}.", + "hub_token_invalidate": "This action will invalidate the current token and disconnect clients using it.", + "hub_token_confirm": "Are you sure you want to do this?", + "hub_token_label": "New token:", + "hub_token_copied_close": "Token has been copied, close", + "hub_token_regenerate": "Regenerate Token", + "hub_menu_update": "Update", + "hub_menu_label": "Hub", + "hub_menu_hotspot_enable": "Enable Wi-Fi hotspot", + "hub_menu_hotspot_disable": "Disable Wi-Fi hotspot", + "hub_menu_pair": "Pair", + "hub_menu_estop": "Emergency Stop", + "hub_update_breadcrumb": "Update", + "hub_update_unknown_hub": "Unknown Hub", + "hub_update_unknown_task": "Unknown Task", + "hub_update_task_metadata": "Fetching Metadata", + "hub_update_task_preparing": "Preparing for Update", + "hub_update_task_flash_fs": "Flashing Filesystem", + "hub_update_task_verify_fs": "Verifying Filesystem", + "hub_update_task_flash_app": "Flashing Application", + "hub_update_task_bootable": "Marking Application Bootable", + "hub_update_task_rebooting": "Rebooting", + "hub_update_status_started": "Started", + "hub_update_status_running": "Running", + "hub_update_status_finished": "Finished", + "hub_update_status_error": "Error", + "hub_update_status_timeout": "Timeout", + "hub_update_confirm_title": "Confirm firmware update", + "hub_update_confirm_desc": "Update {{name}} to version {{version}}?", + "hub_update_unstable_warning": "This version may not be from the stable channel and could contain bugs.", + "hub_update_title": "Update {{name}}", + "hub_update_subtitle": "Manage firmware updates for this hub.", + "hub_update_status_title": "Hub Status", + "hub_update_firmware": "Firmware: {{version}}", + "hub_update_confirm": "Update", + "hub_update_success": "Update completed successfully", + "hub_update_rolled_back": "Device rolled back to previous version", + "hub_update_back": "Back to Hubs", + "hub_update_flash_again": "Flash Again", + "hub_update_card_title": "Firmware Update", + "hub_update_card_desc": "Select a firmware channel and version to install.", + "hub_update_to": "Update to {{version}}", + "hub_update_must_be_online": "Hub must be online to start an update.", + "hub_update_updating_to": "Updating to {{version}}...", + "hub_update_total": "Total", + "hub_update_task": "Task", + "hub_update_history": "Update History", + "hub_update_no_history": "No update history found for this hub.", + "hub_update_col_id": "ID", + "hub_update_col_started": "Started", + "hub_update_col_message": "Message", + "hub_update_loading": "Loading hub information...", + "hub_update_not_found": "Hub not found.", + "home_breadcrumb": "Home", + "home_welcome": "Welcome back", + "home_welcome_name": "Welcome back, {{name}}", + "home_subtitle": "Here's an overview of your OpenShock setup.", + "home_hubs_online": "{{count}} online", + "home_hub_status": "Hub Status", + "home_no_hubs": "No hubs", + "home_all_online": "All online", + "home_all_offline": "All offline", + "home_some_online": "{{online}}/{{total}} online", + "home_quick_links": "Quick Links", + "home_my_shockers": "My Shockers", + "home_my_shockers_desc": "Control your shockers", + "home_hubs_desc": "Manage your hubs", + "home_shared_desc": "Shockers shared with you", + "home_public_desc": "Manage share links", + "home_get_started": "Get Started", + "home_get_started_desc": "You don't have any hubs yet. Create a hub to connect your first device, then add shockers to it.", + "home_set_up_hub": "Set Up a Hub", + "home_first_shocker": "Add Your First Shocker", + "home_first_shocker_desc_one": "You have {{count}} hub set up. Add a shocker to start controlling it.", + "home_first_shocker_desc_other": "You have {{count}} hubs set up. Add a shocker to start controlling it.", + "home_go_to_shockers": "Go to Shockers", + "profile_title": "Profile", + "profile_coming_soon": "Profile is coming soon", + "profile_coming_soon_desc": "Your public profile is not available yet. Account details live under Settings.", + "common_retry": "Retry", + "common_never_used": "Never used", + "common_expires": "Expires {{time}}", + "common_search_placeholder": "Search...", + "common_unknown": "Unknown", + "settings_breadcrumb_account": "Account", + "account_subtitle": "Your sign-in details and account actions.", + "account_change_username": "Change Username", + "account_change_email": "Change Email", + "account_change_password": "Change Password", + "account_username_label": "Username", + "account_email_label": "Email", + "account_password_label": "Password", + "account_new_password_label": "New Password", + "account_confirm_password_label": "Confirm New Password", + "account_oauth_only": "Not available for OAuth-only accounts", + "account_oauth_no_password": "This account signs in via OAuth and has no password.", + "account_diagnostics": "Diagnostics", + "account_diagnostics_desc": "Help us fix crashes and slow API calls. Reports include the error message, stack trace and your IP. Off by default.", + "account_diagnostics_level": "Diagnostics level", + "account_telemetry_off": "Off", + "account_telemetry_off_desc": "Send nothing.", + "account_telemetry_errors": "Errors", + "account_telemetry_errors_desc": "Send browser error reports only.", + "account_telemetry_full": "Full", + "account_telemetry_full_desc": "Error reports plus traces of API calls (no page navigations).", + "account_toast_deactivated": "Account deactivated successfully", + "account_deactivate_title": "Deactivate account", + "account_deactivate_desc": "Are you sure you want to deactivate your account?", + "account_deactivate": "Deactivate Account", + "account_email_title": "Change email", + "account_email_desc": "Enter your new email address and confirm with your current password.", + "account_email_toast_sent": "Verification email sent to {{email}}. Click the link in that email to apply the change.", + "account_new_email": "New Email", + "account_current_password": "Current Password", + "account_password_title": "Change password", + "account_password_desc": "Enter your current password and choose a new one.", + "account_password_toast": "Password has been changed", + "account_username_title": "Change username", + "account_username_desc": "Enter a new username.", + "account_new_username": "New Username", + "account_username_toast": "Username changed successfully", + "tokens_subtitle": "API Tokens are used to authenticate with the OpenShock API.", + "tokens_generate": "Generate Token", + "tokens_toast_refreshed": "Tokens refreshed successfully", + "tokens_empty_title": "No API tokens", + "tokens_empty_desc": "Generate a token to authenticate with the OpenShock API.", + "tokens_created_on": "Created {{date}}", + "tokens_last_used": "Last used {{time}}", + "tokens_never_expires": "Never expires", + "tokens_load_failed": "Failed to load API tokens.", + "token_toast_edited": "Token edited successfully", + "token_name_required": "Name is required", + "token_name_too_long": "Name is too long", + "token_edit_title": "Edit API token", + "token_name_label": "Token Name", + "token_name_placeholder": "Token name...", + "token_permissions": "Permissions", + "token_perm_category_shockers": "Shockers", + "token_perm_category_devices": "Hubs", + "token_perm_category_usershares": "User Shares", + "token_perm_category_publicshares": "Public Shares", + "token_perm_use": "Use", + "token_perm_edit": "Edit", + "token_perm_pause": "Pause", + "token_perm_auth": "Authenticate", + "token_shocker_control": "Shocker Control", + "token_toast_paused": "Token paused", + "token_toast_resumed": "Token resumed", + "token_delete_title": "Delete API token", + "token_delete_desc": "Are you sure you want to delete {{name}}?", + "token_delete_permanent": "This action cannot be undone. This will permanently delete the token.", + "token_toast_deleted": "Token deleted successfully", + "token_resume": "Resume token", + "token_pause": "Pause token", + "token_mode_clamp_desc": "Clamp: requests outside the allowed range are capped to the nearest limit (the min or the max).", + "token_mode_lerp_desc": "Lerp: the full input range is linearly rescaled so it fits within your allowed min–max range.", + "token_paused_desc": "A paused token may not send shocker control messages.", + "token_intensity_range": "Intensity range", + "token_duration_range": "Duration range", + "token_new_breadcrumb": "New", + "token_redirect_not_allowed": "The provided redirect_uri is not allowed. Only loopback addresses or custom application schemes are permitted.", + "token_params_missing": "Required get parameters are missing. Make sure name, redirect_uri, and permissions are provided.", + "token_invalid_permissions": "Invalid permissions provided: {{list}}", + "token_toast_created": "Token created successfully", + "token_request_title": "API Token Request", + "token_access_granted": "Access granted", + "token_shared_redirecting": "The token has been created and shared with the application. Redirecting you back to {{uri}}.", + "token_not_redirected": "If you are not redirected automatically, use the button below.", + "token_finish": "Finish", + "token_generated_title": "API Token Generated", + "token_copy_now": "Please copy your API Token now, you will not be able to view it again later!", + "token_new_title": "New API Token", + "token_external_desc": "An external application is requesting access to your account. Review and adjust the permissions below before allowing access.", + "token_new_desc": "Configure and generate a new API token for your account.", + "token_external_requesting": "{{name}} is requesting an API Token. Your token will be shared with the application at {{uri}}.", + "token_allow": "Allow", + "token_generate": "Generate", + "token_deny": "Deny", + "sessions_subtitle": "Every active session on your account. Revoke any you do not recognize.", + "sessions_unknown_device": "Unknown device", + "sessions_toast_refreshed": "Sessions refreshed successfully", + "sessions_load_failed": "Failed to load sessions.", + "sessions_empty_title": "No active sessions", + "sessions_empty_desc": "Sessions appear here once you sign in from a browser or app.", + "sessions_last_seen": "Last seen {{time}}", + "sessions_signed_in": "Signed in {{time}}", + "session_toast_revoked": "Session revoked successfully", + "session_revoke_title": "Revoke session", + "session_revoke": "Revoke", + "session_revoke_desc": "Are you sure you want to revoke this session?", + "session_revoke_from": "Session logged in from {{ip}} using {{agent}}", + "connections_title": "OAuth Connections", + "connections_subtitle": "Link or unlink third-party accounts to sign in faster and keep your profile in sync.", + "connections_toast_linked": "Account linked.", + "connections_toast_cancelled": "Link flow cancelled.", + "connections_toast_failed": "Linking failed.", + "connections_toast_removed": "Connection removed", + "connections_refreshing": "Refreshing…", + "connections_link_new": "Link new provider", + "connections_empty_title": "No connections yet", + "connections_empty_desc": "Choose “Link new provider” above to connect available providers.", + "connections_unlink": "Unlink", + "connections_load_failed": "Failed to load OAuth connections.", + "connections_unlink_title": "Unlink {{name}}?", + "connections_unlink_title_generic": "Unlink this account?", + "connections_unlink_desc": "You'll no longer be able to sign in with this provider unless you link it again.", + "provider_starting": "Starting {{name}}...", + "provider_link": "Link {{name}}", + "audit_subtitle": "Security-relevant activity on your account. Review anything you do not recognize.", + "audit_col_time": "Time", + "audit_col_action": "Action", + "audit_col_details": "Details", + "audit_col_reason": "Reason", + "audit_col_ip": "IP address", + "audit_col_device": "Device", + "audit_action_login": "Signed in", + "audit_action_logout": "Signed out", + "audit_action_password_changed": "Password changed", + "audit_action_email_change_requested": "Email change requested", + "audit_action_email_changed": "Email changed", + "audit_action_username_changed": "Username changed", + "audit_action_api_token_created": "API token created", + "audit_action_api_token_deleted": "API token deleted", + "audit_action_oauth_connected": "Connection added", + "audit_action_oauth_disconnected": "Connection removed", + "audit_action_account_deactivated": "Account deactivated", + "audit_action_account_reactivated": "Account reactivated", + "audit_action_account_deleted": "Account deleted", + "audit_action_automation_token_created": "Automation token created", + "audit_action_automation_token_updated": "Automation token updated", + "audit_action_automation_token_rotated": "Automation token rotated", + "audit_action_automation_token_deleted": "Automation token deleted", + "audit_action_automation_token_used": "Automation token used", + "audit_meta_session": "Session {{id}}", + "audit_meta_changed": "{{old}} to {{new}}", + "audit_meta_email_requested": "Requested change to {{email}}", + "audit_meta_accounts_removed_one": "{{name}} ({{count}} account removed)", + "audit_meta_accounts_removed_other": "{{name}} ({{count}} accounts removed)", + "audit_meta_scheduled_deletion": "Scheduled for deletion", + "audit_meta_kept": "Kept for reactivation", + "common_view": "View", + "common_save": "Save", + "common_saving": "Saving...", + "common_back": "Back", + "common_shared_by": "Shared by", + "common_user_avatar": "User Avatar", + "common_toast_saved": "Changes saved successfully", + "pause_reason_shocker": "Paused at shocker level", + "pause_reason_shocker_user_share": "Paused at shocker and user share level", + "pause_reason_shocker_public_share": "Paused at shocker and public share level", + "pause_reason_user_share": "Paused at user share level", + "pause_reason_public_share": "Paused at public share level", + "public_shares_subtitle": "A link anyone can use, no account required.", + "public_shares_new": "New Share", + "public_share_never_expires": "Never expires", + "public_shares_empty_title": "No public shares yet", + "public_shares_empty_desc": "Create a link that anyone can use to control your shockers.", + "public_share_expired": "Expired", + "public_share_no_expiry": "No expiry", + "public_share_label": "Public Share", + "public_share_toast_created": "Created new public share", + "public_share_create_title": "Create public share", + "public_share_toast_deleted": "Deleted public share", + "public_share_delete_title": "Delete public share", + "public_share_delete_desc": "Are you sure you want to delete public share {{name}}?", + "public_share_edit_title": "Public Share: {{name}}", + "public_share_edit_subtitle": "Editing: changes apply when you save.", + "public_share_add_shocker": "Add Shocker", + "public_share_toast_added_one": "Added {{count}} shocker to share", + "public_share_toast_added_other": "Added {{count}} shockers to share", + "public_share_empty_shockers_title": "No shockers in this share", + "public_share_empty_shockers_desc": "Add a shocker and anyone with the link will be able to control it.", + "public_share_load_failed": "Error fetching public share details", + "public_share_paused_here": "Paused for this share", + "public_share_resume_shocker": "Resume shocker", + "public_share_pause_shocker": "Pause shocker", + "public_share_remove": "Remove from share", + "public_share_toast_removed": "Shocker removed from share", + "public_share_add_title": "Add shockers", + "public_share_add_desc": "Add shockers to this public share. You can set their limits once they are added.", + "public_share_add_placeholder": "Select shockers to share...", + "public_share_add_no_match": "No matching shockers", + "public_share_add_submit": "Add Shockers", + "public_share_view_loading": "Loading share details...", + "public_share_view_title": "Public Share Link", + "public_share_view_desc": "Enter as a guest or login with your OpenShock account", + "public_share_view_guest_name": "Guest Name", + "public_share_view_enter": "Enter", + "public_share_view_enter_guest": "Enter as Guest", + "public_share_login": "Login", + "perm_shock_on": "Shock enabled", + "perm_shock_off": "Shock disabled", + "perm_vibrate_on": "Vibrate enabled", + "perm_vibrate_off": "Vibrate disabled", + "perm_sound_on": "Sound enabled", + "perm_sound_off": "Sound disabled", + "perm_live_on": "Live enabled", + "perm_live_off": "Live disabled", + "perm_live_control": "Live Control", + "user_selector_avatar_of": "{{name}}'s avatar", + "user_selector_placeholder": "Enter user name", + "user_selector_aria": "Username to search", + "user_selector_search": "Search user", + "user_selector_found": "User found", + "common_remove": "Remove", + "user_shares_subtitle": "Direct permanent shares with other users.", + "user_shares_toast_invited": "Sent a shocker invite to {{name}}", + "user_shares_redeem": "Redeem Code", + "user_shares_new": "New Share", + "user_shares_tab_shares": "Shares", + "user_shares_tab_incoming": "Shared with Me", + "user_shares_tab_invites": "Invites", + "share_code_create_title": "New share code", + "share_code_create_desc": "Create a Share Code or Invite", + "share_code_shocker_placeholder": "Select shockers to share...", + "share_code_no_match": "No matching shockers", + "share_code_send_invite": "Send Share Invite", + "share_code_create": "Create Share Code", + "share_code_created_title": "Share code generated", + "share_code_created_desc": "Please copy share code or code link!", + "share_code_redeem_title": "Redeem share code", + "share_code_redeem_desc": "Enter the share code to redeem", + "share_code_redeem_placeholder": "Enter share code", + "share_code_redeemed": "Redeemed successfully!", + "share_code_shared_shockers": "Shared shockers", + "share_code_redeeming": "Redeeming...", + "share_code_redeem": "Redeem", + "incoming_shares_empty_title": "Nothing shared with you", + "incoming_shares_empty_desc": "No one has shared a shocker with you yet.", + "incoming_share_toast_removed": "Removed share for {{name}}", + "incoming_share_remove_title": "Remove Share", + "incoming_share_remove_desc": "Are you sure you want to remove the share for {{name}}?", + "incoming_share_toast_removed_shocker": "Removed {{shocker}} shared by {{name}}", + "incoming_share_remove_shocker_title": "Remove this shared shocker?", + "incoming_share_remove_shocker_desc": "Are you sure you want to remove the shocker share {{shocker}} by {{name}}?", + "incoming_share_manage_from": "Manage shares from", + "share_remove": "Remove share", + "invites_empty_title": "No invites yet", + "invites_empty_desc": "You have no incoming or outgoing share invites.", + "invites_outgoing": "Outgoing", + "invites_outgoing_empty_title": "No outgoing invites", + "invites_outgoing_empty_desc": "You have no outgoing share invites.", + "invites_incoming": "Incoming", + "invites_incoming_empty_title": "No incoming invites", + "invites_incoming_empty_desc": "You have no incoming share invites.", + "invite_toast_accepted": "Accepted share invite from {{name}}", + "invite_toast_declined": "Declined share invite from {{name}}", + "invite_deny_title": "Deny Invite", + "invite_deny_label": "Deny Invite", + "invite_deny": "Deny", + "invite_deny_desc": "Are you sure you want to deny the invite from {{name}}?", + "invite_accept": "Accept Invite", + "invite_toast_cancelled_for": "Cancelled invite for {{name}} ({{id}})", + "invite_toast_cancelled": "Cancelled invite {{id}}", + "invite_cancel_title": "Cancel Invite", + "invite_cancel": "Cancel", + "invite_cancel_for_desc": "Are you sure you want to cancel the invite for {{name}}?", + "invite_cancel_code_desc": "Are you sure you want to cancel the invite with code {{code}}?", + "invite_cancel_outstanding": "Cancel Outstanding Invite", + "outgoing_shares_empty_title": "No shared shockers", + "outgoing_shares_empty_desc": "You haven't shared any shockers with other users yet.", + "outgoing_share_toast_removed": "Removed shocker share {{name}}", + "outgoing_share_remove_title": "Stop sharing this shocker?", + "outgoing_share_editing_for": "Editing shares for", + "outgoing_share_limits": "Limits & Permissions", + "outgoing_share_same": "Same restrictions on every shocker", + "outgoing_share_per_desc": "Tune restrictions per shocker", + "outgoing_share_all": "All", + "outgoing_share_per": "Per shocker", + "outgoing_share_remove_desc": "Are you sure you want to stop sharing {{shocker}} with {{name}}?", + "report_breadcrumb": "Report API Tokens", + "report_toast_clipboard_failed": "Failed to read clipboard: {{error}}", + "report_title": "Report Leaked API Tokens", + "report_paste": "Paste from clipboard", + "report_warning": "This form is only for reporting accidentally leaked API tokens.", + "report_abuse_warning": "Intentional abuse will result in bans or severe endpoint restrictions.", + "report_detected": "Detected Tokens", + "report_invalid": "One or more tokens appear to be invalid. Please check for formatting issues.", + "report_acknowledge": "I confirm I understand what this feature is for and accept responsibility.", + "report_submit": "Submit Report", + "turnstile_disabled": "Turnstile disabled", + "common_internal_error": "Internal error", + "resend_toast_sent": "Activation email sent. Check your inbox and spam folder.", + "resend_toast_throttled": "Too many activation emails have been requested. Please try again later.", + "resend_toast_unavailable": "No activation email can be resent from this browser. If your account isn't activated yet, logging in sends a new link.", + "resend_button": "Didn't get the email? Resend", + "expiration_label": "Expiration", + "expiration_never": "Never", + "expiration_custom": "Custom", + "expiration_days_one": "{{count}} Day", + "expiration_days_other": "{{count}} Days", + "expiration_required": "Expire date is required", + "expiration_never_desc": "This will never expire", + "expiration_expires_at": "Expires {{time}} ({{date}})", + "date_picker_placeholder": "Pick a date", + "telemetry_toast_title": "Help improve OpenShock?", + "telemetry_toast_desc": "Send diagnostics to help us fix crashes and slow API calls. Reports include the error message, stack trace and your IP. You can change this any time in Account settings.", + "telemetry_toast_no": "No thanks", + "telemetry_toast_errors": "Errors only", + "telemetry_toast_full": "Full", + "table_show_details": "Show details", + "table_hide_details": "Hide details", + "table_no_results": "No results.", + "table_sort_asc": "Sort by {{name}}, ascending", + "table_sort_desc": "Sort by {{name}}, descending", + "table_sort_none": "Sort by {{name}}, unsorted", + "cell_na": "N/A", + "cell_not_applicable": "Not applicable", + "cell_invalid": "Invalid", + "cell_unavailable": "Unavailable", + "cell_none": "None", + "oauth_login_with": "Login with {{provider}}", + "oauth_signup_with": "Signup with {{provider}}", + "signalr_connect_failed": "Failed to connect to server!", + "signalr_disconnect_failed": "Encountered error while disconnecting from server!", + "signalr_invalid_update": "Received invalid update from server!", + "signalr_invalid_log": "Received invalid log data from server!", + "signalr_invalid_ota": "Received invalid firmware update data from server!", + "ota_toast_failed": "Hub firmware update failed: {{message}}", + "ota_toast_succeeded": "Hub firmware update completed successfully!", + "ota_toast_rolled_back": "Hub firmware rolled back to previous version", + "lcg_connect_failed": "Failed to connect to live control gateway", + "terminal_toast_bootloader_failed": "Failed to enter bootloader: {{error}}", + "terminal_toast_app_mode_failed": "Failed to enter application mode: {{error}}", + "problem_account_account_not_activated_title": "Account not activated", + "problem_account_account_not_activated_desc": "Check your inbox for the activation email.", + "problem_account_activation_not_found_title": "Activation link is invalid", + "problem_account_activation_not_found_desc": "The link may have expired or already been used.", + "problem_account_activation_resend_too_many_title": "Too many activation emails requested", + "problem_account_activation_resend_too_many_desc": "Please wait a while before trying again.", + "problem_account_activation_resend_unavailable_title": "Cannot resend activation email", + "problem_account_activation_resend_unavailable_desc": "Log in again to request a new activation link.", + "problem_account_deactivate_already_deactivated_title": "Account is already deactivated", + "problem_account_deactivate_denied_privileged_title": "Privileged accounts cannot be deactivated", + "problem_account_deactivate_unauthorized_title": "You are not allowed to do this", + "problem_account_deactivated_title": "This account has been deactivated", + "problem_account_email_already_in_use_title": "That email address is already in use", + "problem_account_email_invalid_title": "That email address is not valid", + "problem_account_email_taken_title": "That email address is already in use", + "problem_account_email_too_many_requests_title": "Too many email change requests", + "problem_account_email_too_many_requests_desc": "Please wait a while before trying again.", + "problem_account_email_unchanged_title": "That is already your email address", + "problem_account_email_verify_not_found_title": "Verification link is invalid", + "problem_account_email_verify_not_found_desc": "The link may have expired or already been used.", + "problem_account_o_auth_only_title": "This account has no password", + "problem_account_o_auth_only_desc": "Sign in with the provider you signed up with.", + "problem_account_password_not_set_title": "No password set", + "problem_account_password_not_set_desc": "This account signs in through an external provider.", + "problem_account_password_old_password_invalid_title": "Current password is incorrect", + "problem_account_username_invalid_title": "That username is not allowed", + "problem_account_username_recently_changed_title": "Username changed too recently", + "problem_account_username_recently_changed_desc": "You can change your username once every 7 days.", + "problem_account_username_taken_title": "That username is already taken", + "problem_admin_user_deactivated_title": "This user is deactivated", + "problem_admin_user_not_activated_title": "This user has not been activated yet", + "problem_api_token_can_only_delete_self_title": "An API token can only delete itself", + "problem_api_token_not_found_title": "API token not found", + "problem_api_token_paused_title": "This API token is paused", + "problem_assign_lcg_bad_schema_version_title": "Unsupported hub protocol version", + "problem_assign_lcg_bad_schema_version_desc": "Update the hub firmware to connect.", + "problem_assign_lcg_no_lcg_available_title": "No gateway available", + "problem_assign_lcg_no_lcg_available_desc": "No live control gateway is available right now. Please try again later.", + "problem_authentication_account_deactivated_title": "This account has been deactivated", + "problem_authentication_account_not_activated_title": "This account has not been activated", + "problem_authentication_cookie_missing_or_invalid_title": "You are not logged in", + "problem_authentication_cookie_missing_or_invalid_desc": "Your session may have expired. Please log in again.", + "problem_authentication_header_missing_or_invalid_title": "Invalid API token", + "problem_authentication_session_invalid_title": "Session expired", + "problem_authentication_session_invalid_desc": "Please log in again.", + "problem_authentication_token_invalid_title": "Invalid API token", + "problem_authentication_unknown_error_title": "Authentication failed", + "problem_authorization_policy_not_met_title": "You do not have permission to do this", + "problem_authorization_token_only_title": "This action requires an API token", + "problem_authorization_token_permission_missing_title": "This API token is missing a required permission", + "problem_authorization_unknown_error_title": "Authorization failed", + "problem_authorization_user_session_only_title": "This action requires a logged-in session", + "problem_automation_token_not_allowed_for_account_title": "Automation tokens cannot be used with privileged accounts", + "problem_configuration_already_exists_title": "A configuration entry with that name already exists", + "problem_configuration_invalid_name_format_title": "Invalid configuration name", + "problem_configuration_invalid_name_format_desc": "Only A to Z and underscores are allowed.", + "problem_configuration_invalid_value_format_title": "Value does not match the configuration type", + "problem_configuration_not_found_title": "Configuration entry not found", + "problem_control_stats_invalid_range_title": "The from date must not be after the to date", + "problem_control_stats_invalid_time_zone_title": "Unknown time zone", + "problem_control_stats_missing_capability_title": "Control statistics are not available on this server", + "problem_device_not_found_title": "Hub not found", + "problem_device_not_online_title": "Hub is offline", + "problem_device_too_many_hubs_title": "You have reached the maximum number of hubs", + "problem_device_too_many_shockers_title": "This hub has reached its maximum number of shockers", + "problem_endpoint_retired_title": "This feature is no longer available", + "problem_expression_error_title": "Invalid filter expression", + "problem_internal_server_error_title": "Something went wrong on our end", + "problem_login_invalid_credentials_title": "Invalid username or password", + "problem_login_invalid_domain_title": "Logging in from this address is not allowed", + "problem_o_auth_connection_already_exists_title": "Your account is already connected to this provider", + "problem_o_auth_connection_already_linked_title": "This external account is already linked to another user", + "problem_o_auth_flow_anonymous_only_title": "You are already signed in", + "problem_o_auth_flow_mismatch_title": "Sign-in attempt does not match", + "problem_o_auth_flow_mismatch_desc": "Please start over.", + "problem_o_auth_flow_missing_data_title": "The provider did not return your account details", + "problem_o_auth_flow_missing_data_desc": "Please try again.", + "problem_o_auth_flow_not_found_title": "Sign-in attempt expired", + "problem_o_auth_flow_not_found_desc": "Please start over.", + "problem_o_auth_flow_unsupported_title": "Unsupported sign-in flow", + "problem_o_auth_internal_error_title": "Something went wrong during sign-in", + "problem_o_auth_internal_error_desc": "Please try again in a moment.", + "problem_o_auth_link_authenticated_user_only_title": "You must be signed in to link an external account", + "problem_o_auth_provider_mismatch_title": "Sign-in attempt does not match the provider", + "problem_o_auth_provider_mismatch_desc": "Please start over.", + "problem_o_auth_provider_unsupported_title": "This sign-in provider is not supported", + "problem_pair_code_not_found_title": "Pair code not found", + "problem_password_reset_not_found_title": "Password reset link is invalid", + "problem_password_reset_not_found_desc": "The link may have expired or already been used.", + "problem_session_not_found_title": "Session not found", + "problem_share_get_no_shares_title": "You have no shares with this user", + "problem_share_request_create_cannot_share_with_self_title": "You cannot share with yourself", + "problem_share_request_create_shocker_not_found_title": "One or more shockers were not found", + "problem_share_request_create_shocker_not_found_desc": "They may have been removed or do not belong to you.", + "problem_share_request_not_found_title": "Share invite not found", + "problem_share_user_not_found_title": "Share not found", + "problem_share_code_already_linked_title": "Shocker is already linked to your account", + "problem_share_code_cant_link_own_share_code_title": "You cannot redeem your own share code", + "problem_share_code_not_found_title": "Share code not found", + "problem_share_link_expiry_date_in_past_title": "Expiry date cannot be in the past", + "problem_share_link_not_found_title": "Public share not found", + "problem_share_link_shocker_already_in_share_link_title": "Shocker is already in this public share", + "problem_share_link_shocker_not_in_share_link_title": "Shocker is not in this public share", + "problem_shocker_control_no_permission_title": "You do not have permission to control this shocker", + "problem_shocker_control_not_found_title": "Shocker not found", + "problem_shocker_control_paused_title": "Shocker is paused", + "problem_shocker_not_found_title": "Shocker not found", + "problem_signup_registration_disabled_title": "Registration is currently disabled", + "problem_signup_username_or_email_exists_title": "That username or email is already in use", + "problem_turnstile_invalid_title": "Verification failed", + "problem_turnstile_invalid_desc": "Please complete the challenge again and retry.", + "problem_user_not_found_title": "User not found", + "problem_user_privileged_delete_denied_title": "Privileged users cannot be deleted", + "problem_validation_error_title": "Some fields are invalid", + "problem_webhook_not_found_title": "Webhook not found", + "problem_webhook_unsupported_title": "Only Discord webhooks are supported", + "problem_webhook_unsupported_desc": "Use a discord.com URL, not canary or ptb.", + "error_too_many_requests": "Too many requests", + "error_retry_after_one": "Try again in {{count}} second.", + "error_retry_after_other": "Try again in {{count}} seconds.", + "error_unexpected_response": "Unexpected server response", + "error_internal": "Internal error occurred", + "error_network": "Network error occurred", + "dev_banner": "This is the OpenShock DEVELOPMENT environment. No data is saved, and it is regularly overwritten by production data.", + "firmware_channel_bugs_warning": "This channel might contain bugs." +} From f74cf90b878260927fe6feda003b228de77c3597 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Luc=20=E2=99=A5?= Date: Thu, 12 Nov 2026 17:43:21 +0100 Subject: [PATCH 15/27] New translations en.json (Japanese) [ci skip] --- messages/ja.json | 302 ++++++++++++++++++----------------------------- 1 file changed, 117 insertions(+), 185 deletions(-) diff --git a/messages/ja.json b/messages/ja.json index 7825148f..4f3ea8e5 100644 --- a/messages/ja.json +++ b/messages/ja.json @@ -1,15 +1,13 @@ { - "$schema": "https://inlang.com/schema/inlang-message-format", - "landing_tagline": "安全で信頼性の高い、低遅延のショッカー遠隔操作プラットフォームです。", "landing_section_label": "ホーム", "landing_hubs_online": "現在オンラインのハブ数:", "landing_learn_more": "詳しく見る", "landing_wiki": "Wiki", "landing_meta_description": "OpenShockへようこそ。OpenShockは、さまざまなショッカーをインターネット経由で操作できる、無料でオープンソースのエコシステムです。", - "instance_meta_description": "{siteName}へようこそ。ここはOpenShockの独立したインスタンスです。OpenShockは、さまざまなショッカーをインターネット経由で操作できる、無料でオープンソースのエコシステムです。", + "instance_meta_description": "{{siteName}}へようこそ。ここはOpenShockの独立したインスタンスです。OpenShockは、さまざまなショッカーをインターネット経由で操作できる、無料でオープンソースのエコシステムです。", "header_sidebar_toggle": "サイドバーの切り替え", - "header_avatar_alt": "{name}のアバター", + "header_avatar_alt": "{{name}}のアバター", "header_menu_profile": "プロフィール", "header_menu_settings": "設定", "header_menu_logout": "ログアウト", @@ -17,16 +15,14 @@ "header_signup": "新規登録", "header_github_title": "GitHub の OpenShock", "header_discord_title": "コミュニティ Discord", - - "footer_made_with": "{#team}OpenShock チーム{/team}が{#heart/}を込めて制作", + "footer_made_with": "OpenShock チームがを込めて制作", "footer_connection_status_label": "サーバー接続状態", "footer_signalr_state": "SignalR 状態", "footer_frontend_version": "フロントエンドのバージョン", - "footer_frontend_commit_title": "コミット {commit}", + "footer_frontend_commit_title": "コミット {{commit}}", "footer_backend_version": "バックエンドのバージョン", - "footer_backend_commit_title": "コミット {commit}", + "footer_backend_commit_title": "コミット {{commit}}", "footer_language_label": "言語", - "sidebar_home_link_label": "OpenShock ホーム", "sidebar_group_general": "一般", "sidebar_home": "ホーム", @@ -53,7 +49,6 @@ "sidebar_settings_audit_log": "監査ログ", "sidebar_settings_connections": "連携", "sidebar_settings_account": "アカウント設定", - "error_meta_title": "サービス利用不可", "error_meta_description": "OpenShock は現在ご利用いただけません", "error_meta_logo_alt": "OpenShock ロゴ", @@ -62,10 +57,8 @@ "error_not_found_description": "お探しのページは存在しません。", "error_unexpected_description": "予期しないエラーが発生しました。", "error_go_back": "戻る", - "auth_layout_logo_alt": "OpenShock ロゴ", "auth_layout_invalid_redirect_removed": "安全のため、無効なリダイレクト URL を削除しました。", - "auth_activate_breadcrumb": "アカウントの有効化", "auth_activate_title": "アカウントの有効化", "auth_activate_activating": "アカウントを有効化しています...", @@ -74,17 +67,15 @@ "auth_activate_missing_token": "有効化トークンがありません", "auth_activate_continue": "ログインへ進む", "auth_activate_toast_success": "アカウントを有効化しました", - "auth_forgot_breadcrumb": "パスワードを忘れた場合", "auth_forgot_title": "パスワードを忘れた場合", "auth_forgot_description": "パスワードをリセットするにはメールアドレスを入力してください", "auth_forgot_email_label": "メールアドレス", "auth_forgot_email_placeholder": "メールアドレス", "auth_forgot_submit": "パスワードをリセット", - "auth_forgot_signin_prompt": "パスワードを思い出しましたか?{#signin}ログイン{/signin}", + "auth_forgot_signin_prompt": "パスワードを思い出しましたか?ログイン", "auth_forgot_mail_disabled": "このインスタンスにはメールプロバイダーが設定されていないため、パスワードのリセットはご利用いただけません。アカウントの復旧については管理者にお問い合わせください。", "auth_forgot_toast_sent": "入力されたメールアドレスにパスワードリセットのリクエストを送信しました", - "auth_login_breadcrumb": "ログイン", "auth_login_title": "おかえりなさい", "auth_login_loading_methods": "利用可能なログイン方法を読み込んでいます", @@ -98,23 +89,20 @@ "auth_login_username_label": "ユーザー名またはメールアドレス", "auth_login_password_label": "パスワード", "auth_login_submit": "ログイン", - "auth_login_signup_prompt": "アカウントをお持ちでないですか?{#signup}新規登録{/signup}", - "auth_login_legal": "「ログイン」をクリックすると、{#tos}利用規約{/tos}と{#privacy}プライバシーポリシー{/privacy}に同意したものとみなされます。", - - "auth_oauth_create_breadcrumb": "{provider} で新規登録", - "auth_oauth_create_title": "{#provider}{provider}{/provider} で新規登録", + "auth_login_signup_prompt": "アカウントをお持ちでないですか?新規登録", + "auth_login_legal": "「ログイン」をクリックすると、利用規約とプライバシーポリシーに同意したものとみなされます。", + "auth_oauth_create_breadcrumb": "{{provider}} で新規登録", + "auth_oauth_create_title": "{{provider}} で新規登録", "auth_oauth_create_description": "アカウント情報を入力してください", "auth_oauth_create_username_label": "ユーザー名", "auth_oauth_create_username_placeholder": "ユーザー名", "auth_oauth_create_email_label": "メールアドレス", "auth_oauth_create_email_placeholder": "メールアドレス", "auth_oauth_create_submit": "新規登録", - "auth_oauth_create_legal": "「新規登録」をクリックすると、{#tos}利用規約{/tos}と{#privacy}プライバシーポリシー{/privacy}に同意したものとみなされます。", - + "auth_oauth_create_legal": "「新規登録」をクリックすると、利用規約とプライバシーポリシーに同意したものとみなされます。", "auth_oauth_error_breadcrumb": "認証エラー", "auth_oauth_error_title": "認証エラー", "auth_oauth_error_back": "ログインに戻る", - "auth_reset_breadcrumb": "パスワードのリセット", "auth_reset_title": "パスワードのリセット", "auth_reset_checking": "リセットリンクを確認しています...", @@ -127,7 +115,6 @@ "auth_reset_submit": "パスワードをリセット", "auth_reset_request_new": "新しいリセットリンクをリクエスト", "auth_reset_toast_success": "パスワードをリセットしました", - "auth_signup_breadcrumb": "新規登録", "auth_signup_toast_created_mail": "アカウントを作成しました。メールを確認してアカウントを認証してください。", "auth_signup_toast_created_no_mail": "アカウントを作成しました。今すぐログインできます。", @@ -150,11 +137,10 @@ "auth_signup_confirm_label": "パスワード(確認)", "auth_signup_confirm_placeholder": "パスワード(確認)", "auth_signup_submit": "アカウントを作成", - "auth_signup_signin_prompt": "すでにアカウントをお持ちですか?{#signin}ログイン{/signin}", + "auth_signup_signin_prompt": "すでにアカウントをお持ちですか?ログイン", "auth_signup_or": "または", "auth_signup_with_email": "メールアドレスで登録", - "auth_signup_legal": "「アカウントを作成」をクリックすると、{#tos}利用規約{/tos}と{#privacy}プライバシーポリシー{/privacy}に同意したものとみなされます。", - + "auth_signup_legal": "「アカウントを作成」をクリックすると、利用規約とプライバシーポリシーに同意したものとみなされます。", "auth_verify_breadcrumb": "メールアドレスの認証", "auth_verify_title": "メールアドレスの認証", "auth_verify_verifying": "メールアドレスを認証しています...", @@ -163,7 +149,6 @@ "auth_verify_missing_token": "認証トークンがありません", "auth_verify_continue": "ログインへ進む", "auth_verify_toast_success": "メールアドレスを認証しました", - "common_cancel": "キャンセル", "common_delete": "削除", "common_edit": "編集", @@ -194,7 +179,7 @@ "control_type_shock": "ショック", "control_type_vibrate": "振動", "control_type_sound": "音", - "live_tooltip_active": "{gateway}({country})経由でライブ接続中、{latency}ms", + "live_tooltip_active": "{{gateway}}({{country}})経由でライブ接続中、{{latency}}ms", "live_tooltip_connecting": "接続しています...", "live_tooltip_connect": "ライブコントロールに接続", "live_tooltip_hub_start": "Ctrl+クリックでハブ全体を開始", @@ -207,14 +192,14 @@ "shocker_hub": "ハブ", "shocker_select_hub": "ハブを選択", "shocker_rf_id": "RF ID", - "shocker_rf_id_invalid": "RF ID は {min} から {max} までの整数で指定してください。", + "shocker_rf_id_invalid": "RF ID は {{min}} から {{max}} までの整数で指定してください。", "shocker_model": "モデル", "shocker_select_model": "モデルを選択", "shocker_name_placeholder": "ショッカー名", "shocker_menu_view_logs": "ログを表示", "shocker_delete_title": "ショッカーを削除", - "shocker_delete_desc": "「{name}」を削除してもよろしいですか?この操作は元に戻せません。", - "shocker_toast_deleted": "ショッカー「{name}」を削除しました", + "shocker_delete_desc": "「{{name}}」を削除してもよろしいですか?この操作は元に戻せません。", + "shocker_toast_deleted": "ショッカー「{{name}}」を削除しました", "shocker_toast_paused": "ショッカーを一時停止しました", "shocker_toast_resumed": "ショッカーを再開しました", "shocker_add_desc": "ハブに新しいショッカーを登録します。", @@ -239,15 +224,8 @@ "shockers_empty_no_hubs": "まずハブを作成してから、ショッカーを追加してください。", "shockers_empty_has_hubs": "ハブにショッカーを追加して始めましょう。", "shockers_create_hub": "ハブを作成", - "shockers_count": [ - { - "declarations": ["input count", "local countPlural = count: plural"], - "selectors": ["countPlural"], - "match": { - "countPlural=other": "{count} 台のショッカー" - } - } - ], + "shockers_count_one": "{{count}} shocker", + "shockers_count_other": "{{count}} 台のショッカー", "shared_shockers_title": "共有ショッカー", "shared_shockers_subtitle": "他のユーザーがあなたと共有したショッカーです。", "shared_shockers_empty_title": "共有されたショッカーはまだありません。", @@ -276,18 +254,17 @@ "shocker_edit_is_active": "ショッカーは有効です", "shocker_edit_toast_updated": "ショッカーを更新しました", "shocker_edit_delete_desc": "このショッカーを完全に削除します。この操作は元に戻せません。", - "common_close": "閉じる", "common_continue": "続行", "common_loading": "読み込んでいます...", "common_previous": "前へ", "common_next": "次へ", "common_steps": "手順", - "common_step_label": "手順 {number}: {title}", + "common_step_label": "手順 {{number}}: {{title}}", "common_copy": "コピー", "common_copied": "コピーしました", "common_never": "なし", - "common_error": "エラー: {message}", + "common_error": "エラー: {{message}}", "terminal_title": "シリアルターミナル", "terminal_connecting": "接続しています...", "terminal_help_button": "うまくいかない場合はこちら", @@ -300,7 +277,7 @@ "terminal_mode_raw_desc": "コンソールのみです。デバイスのログを読み、コマンドを送信します。", "terminal_step_channel": "チャンネルを選択", "terminal_step_board": "ボードを選択", - "terminal_go_to_step": "手順 {number} に移動: {title}", + "terminal_go_to_step": "手順 {{number}} に移動: {{title}}", "terminal_erase": "書き込み前に消去", "terminal_erase_desc": "既存の設定を含め、デバイス上のすべてのデータを消去します", "terminal_unsupported": "お使いのブラウザーはこの機能に対応していません。", @@ -315,15 +292,15 @@ "terminal_try_driver": "シリアルドライバーがインストールされているか確認してください。", "terminal_open_troubleshooter": "トラブルシューティングを開く", "terminal_log_reset_no_device": "リセット中にホスト側でエラー: デバイスがありません!", - "terminal_log_reset_error": "リセット中にホスト側でエラー: {error}", + "terminal_log_reset_error": "リセット中にホスト側でエラー: {{error}}", "terminal_log_send_no_device": "送信できません: デバイスがありません!", - "terminal_log_send_error": "送信できません: {error}", - "terminal_log_firmware_disconnected": "ファームウェアが切断されました: {error}", - "terminal_log_erase_failed": "フラッシュを消去できませんでした: {error}", - "terminal_log_hard_reset_failed": "ハードリセットに失敗しました: {error}", + "terminal_log_send_error": "送信できません: {{error}}", + "terminal_log_firmware_disconnected": "ファームウェアが切断されました: {{error}}", + "terminal_log_erase_failed": "フラッシュを消去できませんでした: {{error}}", + "terminal_log_hard_reset_failed": "ハードリセットに失敗しました: {{error}}", "terminal_log_flash_complete": "書き込み完了", - "terminal_log_flash_failed": "書き込みに失敗しました: {error}", - "terminal_log_command_failed": "アプリケーションコマンドを書き込めませんでした: {error}", + "terminal_log_flash_failed": "書き込みに失敗しました: {{error}}", + "terminal_log_command_failed": "アプリケーションコマンドを書き込めませんでした: {{error}}", "terminal_help_title": "トラブルシューティング", "terminal_help_desc": "以下の手順を順番に試してください。それぞれ一般的な原因を切り分けます。", "terminal_help_step_cable": "USB ケーブル", @@ -335,23 +312,23 @@ "terminal_help_port_body": "デバイスをコンピューターの USB ポートに直接接続してください。USB ハブ、ドッキングステーション、前面ポートは電源や信号の問題が起きやすいため、できるだけ避けてください。デスクトップの場合は背面のポートをお試しください。", "terminal_help_driver_download": "CP210x ドライバーをダウンロード:", "terminal_help_driver_extract": "zip ファイルの内容をコンピューター上のフォルダーに展開します。", - "terminal_help_driver_run": "フォルダーを開き、{#code}{installer}{/code} を実行します。画面の指示に従ってインストールしてください。", + "terminal_help_driver_run": "フォルダーを開き、{{installer}} を実行します。画面の指示に従ってインストールしてください。", "terminal_help_driver_reconnect": "デバイスを再接続します。", "terminal_help_manual_intro": "ドライバーのインストーラーを実行してもデバイスが表示されない場合:", - "terminal_help_manual_open": "デバイスマネージャーを開きます({#key}Win{/key} + {#key}X{/key} を押して {#code}Device Manager{/code} を選択)。", - "terminal_help_manual_ports": "{#code}Ports (COM & LPT){/code} の下で、次のような項目を探します:", + "terminal_help_manual_open": "デバイスマネージャーを開きます(Win + X を押して Device Manager を選択)。", + "terminal_help_manual_ports": "Ports (COM & LPT) の下で、次のような項目を探します:", "terminal_help_manual_missing": "見つからない場合、デバイスは Windows にまったく検出されていません。ケーブルとポートの手順をもう一度確認してください。", - "terminal_help_manual_update": "デバイスを右クリックし、{#code}Update Driver{/code} を選択します。", - "terminal_help_manual_browse": "{#code}Browse my computer for drivers{/code} を選び、ドライバーの zip を展開したフォルダーを選択します。{#code}Include subfolders{/code} にチェックが入っていることを確認してください。", - "terminal_help_manual_success": "成功すると、項目が {#code}{deviceName}{/code} と表示されます。", - "terminal_help_discord_intro": "それでも解決しない場合は、Discord サーバーの {#code}{channel}{/code} チャンネルで質問してください。次の情報を含めてください:", + "terminal_help_manual_update": "デバイスを右クリックし、Update Driver を選択します。", + "terminal_help_manual_browse": "Browse my computer for drivers を選び、ドライバーの zip を展開したフォルダーを選択します。Include subfolders にチェックが入っていることを確認してください。", + "terminal_help_manual_success": "成功すると、項目が {{deviceName}} と表示されます。", + "terminal_help_discord_intro": "それでも解決しない場合は、Discord サーバーの {{channel}} チャンネルで質問してください。次の情報を含めてください:", "terminal_help_discord_os": "お使いの OS とブラウザー", "terminal_help_discord_device": "使用しているデバイス(ボードのモデル、入手先)", "terminal_help_discord_tried": "これまでの手順で試したこと", "terminal_help_discord_errors": "エラーメッセージや関連するターミナル出力", "terminal_help_discord_join": "Discord サーバーに参加", "terminal_risk_title": "⚠️ 不安定なファームウェア", - "terminal_risk_intro": "{#strong}不安定であることが判明している{/strong}{#strong}実験的なファームウェア{/strong}を書き込もうとしています。", + "terminal_risk_intro": "不安定であることが判明している実験的なファームウェアを書き込もうとしています。", "terminal_risk_brick": "デバイスが完全に起動しなくなる、手動での復旧が必要になる、または使用できなくなる可能性があります。", "terminal_risk_no_support": "このファームウェアが原因の問題についてはサポートを提供しません。", "terminal_risk_acknowledge": "これはすべて自己責任であることを理解しました", @@ -366,7 +343,7 @@ "terminal_board_search": "ボードを検索...", "terminal_board_none": "ボードが見つかりません。", "terminal_flash_button": "書き込み", - "terminal_flash_progress": "書き込みの進行状況: {status}", + "terminal_flash_progress": "書き込みの進行状況: {{status}}", "terminal_flash_idle": "待機中", "terminal_flash_no_device": "デバイスが選択されていません。", "terminal_flash_resetting": "リセットしています...", @@ -377,7 +354,7 @@ "terminal_flash_done": "デバイスを再起動しました。書き込み完了です。", "terminal_port_select": "デバイスを選択", "terminal_port_disconnect": "デバイスを切断", - "terminal_port_connected": "接続中のデバイス: {#strong}{id}{/strong}", + "terminal_port_connected": "接続中のデバイス: {{id}}", "terminal_console": "コンソール", "terminal_connected_device": "接続中のデバイス", "terminal_resize": "ターミナルパネルのサイズを変更", @@ -393,7 +370,7 @@ "terminal_colors_menu": "色...", "terminal_colors_label": "コンソールの色", "terminal_colors_close": "色設定を閉じる", - "terminal_color_input": "{name}の色", + "terminal_color_input": "{{name}}の色", "terminal_colors_reset": "デフォルトに戻す", "terminal_color_bg": "背景", "terminal_color_fg": "テキスト", @@ -423,13 +400,12 @@ "terminal_toast_clipboard_unreadable": "クリップボードを読み取れませんでした", "terminal_toast_settings_imported": "コンソール設定をインポートしました", "terminal_toast_settings_invalid": "クリップボードにコンソール設定が含まれていません", - "common_try_again": "再試行", - "terminal_cfg_intro": "値は UART 経由でデバイスに送信されます。デバイスの応答は下のコンソールで確認できます。引数なしのコマンドは値の取得として動作します。各フィールドの横にある {#eye/} ボタンで現在の値を読み取れます。", + "terminal_cfg_intro": "値は UART 経由でデバイスに送信されます。デバイスの応答は下のコンソールで確認できます。引数なしのコマンドは値の取得として動作します。各フィールドの横にある ボタンで現在の値を読み取れます。", "terminal_cfg_rf_title": "RF 送信機", "terminal_cfg_rf_desc": "ショッカーの RF 出力を制御します。", "terminal_cfg_tx_pin": "TX GPIO ピン", - "terminal_cfg_example": "例: {value}", + "terminal_cfg_example": "例: {{value}}", "terminal_cfg_read_value": "現在の値を読み取る", "terminal_cfg_set": "設定", "terminal_cfg_read": "読み取り", @@ -441,13 +417,13 @@ "terminal_cfg_estop_desc": "すべての出力を停止するハードウェアボタンです。", "terminal_cfg_estop_enabled": "EStop を有効化", "terminal_cfg_estop_pin": "EStop GPIO ピン", - "terminal_cfg_estop_note": "注: {#code}{latching}{/code} と {#code}{active}{/code} には専用コマンドがありません。下の JSON 設定で指定してください。", + "terminal_cfg_estop_note": "注: {{latching}} と {{active}} には専用コマンドがありません。下の JSON 設定で指定してください。", "terminal_cfg_wifi_title": "WiFi", "terminal_cfg_wifi_desc": "ステーションの認証情報とデバイスのホスト名です。", "terminal_cfg_hostname": "ホスト名", "terminal_cfg_networks": "ネットワーク(JSON 配列)", "terminal_cfg_invalid_json_array": "有効な JSON 配列である必要があります", - "terminal_cfg_ap_note": "AP 設定({#code}{ssid}{/code}、{#code}{password}{/code}、{#code}{disabled}{/code}、{#code}{staDisabled}{/code}、{#code}{offlineMode}{/code})には専用コマンドがありません。JSON 設定を使用してください。", + "terminal_cfg_ap_note": "AP 設定({{ssid}}、{{password}}、{{disabled}}、{{staDisabled}}、{{offlineMode}})には専用コマンドがありません。JSON 設定を使用してください。", "terminal_cfg_backend_title": "バックエンド", "terminal_cfg_backend_desc": "OpenShock サーバーと認証です。", "terminal_cfg_domain": "ドメイン", @@ -475,12 +451,11 @@ "terminal_cfg_factory_reset_confirm": "WiFi ネットワーク、バックエンドの認証情報、ピンなど、デバイス上のすべての設定が消去されます。デバイスはデフォルトにリセットされます。", "terminal_cfg_read_failed_json_title": "JSON 設定を読み取れませんでした", "terminal_cfg_read_failed_raw_title": "生の設定を読み取れませんでした", - "terminal_cfg_read_failed_desc": "{attempts} 回試行しましたが、デバイスが応答しませんでした。", + "terminal_cfg_read_failed_desc": "{{attempts}} 回試行しましたが、デバイスが応答しませんでした。", "terminal_cfg_common_causes": "主な原因:", "terminal_cfg_cause_busy": "デバイスが別のコマンドを処理中です。", "terminal_cfg_cause_disconnected": "デバイスが切断されたか、再起動しました。", "terminal_cfg_cause_unsupported": "このファームウェアバージョンはこのコマンドに対応していません。", - "common_status": "状態", "common_version": "バージョン", "common_created": "作成日", @@ -501,25 +476,25 @@ "hubs_name_placeholder": "マイハブ", "hub_toast_not_connected": "サーバーに接続されていません", "hub_toast_try_later": "しばらくしてからもう一度お試しください。", - "hub_reboot_title": "{name} を再起動しますか?", + "hub_reboot_title": "{{name}} を再起動しますか?", "hub_reboot_desc": "ハブは切断されて再起動します。オンラインに戻るまで、ペアリングされたショッカーは応答しなくなります。", "hub_reboot": "再起動", - "hub_hotspot_enable_title": "{name} の Wi-Fi ホットスポットを有効にしますか?", - "hub_hotspot_disable_title": "{name} の Wi-Fi ホットスポットを無効にしますか?", + "hub_hotspot_enable_title": "{{name}} の Wi-Fi ホットスポットを有効にしますか?", + "hub_hotspot_disable_title": "{{name}} の Wi-Fi ホットスポットを無効にしますか?", "hub_hotspot_enable_desc": "ハブが独自のセットアップ用ネットワークを発信します。Wi-Fi 経由での接続は維持されますが、オフにするまでホットスポットは範囲内の誰でも利用できます。", "hub_hotspot_disable_desc": "セットアップ用ホットスポットが停止します。ハブがまだ Wi-Fi に接続されていない場合、再設定には実機の操作が必要になります。", - "hub_delete_desc": "ハブ {#strong}{name}{/strong} を削除しようとしています。", + "hub_delete_desc": "ハブ {{name}} を削除しようとしています。", "hub_delete_shockers": "次のショッカーも削除されます:", "hub_edit_title": "ハブを編集", "hub_edit_apply": "適用", "hub_pair_title_generate": "ペアコードを生成しますか?", "hub_pair_title_generated": "ペアコードを生成しました", "hub_pair_title_paired": "ハブをペアリングしました", - "hub_pair_consumed": "{#strong}{name}{/strong} がこのペアコードを使用し、ペアリングされました。", + "hub_pair_consumed": "{{name}} がこのペアコードを使用し、ペアリングされました。", "hub_pair_used": "このコードは使用済みのため、無効になりました。", - "hub_pair_generated_for": "{#strong}{name}{/strong} のペアコードを生成しました。", + "hub_pair_generated_for": "{{name}} のペアコードを生成しました。", "hub_copy_now": "以下のコードは後で確認できません。今すぐコピーして、クライアントを更新してください。", - "hub_pair_generate_for": "{#strong}{name}{/strong} のペアコードを生成しようとしています。", + "hub_pair_generate_for": "{{name}} のペアコードを生成しようとしています。", "hub_pair_valid_for": "作成後 15 分間有効です。", "hub_pair_one_active": "有効なペアコードはハブごとに 1 つだけです。新しく生成すると、古いコードは置き換えられます。", "hub_pair_complete": "ペアリング完了", @@ -527,8 +502,8 @@ "hub_pair_copied_close": "コピーしたので閉じる", "hub_pair_get": "ペアコードを取得", "hub_token_generated": "トークンを生成しました", - "hub_token_generated_for": "{#strong}{name}{/strong} の新しいトークンを生成しました。", - "hub_token_regenerate_for": "{#strong}{name}{/strong} のトークンを再生成しようとしています。", + "hub_token_generated_for": "{{name}} の新しいトークンを生成しました。", + "hub_token_regenerate_for": "{{name}} のトークンを再生成しようとしています。", "hub_token_invalidate": "現在のトークンは無効になり、それを使用しているクライアントは切断されます。", "hub_token_confirm": "実行してもよろしいですか?", "hub_token_label": "新しいトークン:", @@ -556,12 +531,12 @@ "hub_update_status_error": "エラー", "hub_update_status_timeout": "タイムアウト", "hub_update_confirm_title": "ファームウェアのアップデートの確認", - "hub_update_confirm_desc": "{#strong}{name}{/strong} をバージョン {#strong}{version}{/strong} にアップデートしますか?", + "hub_update_confirm_desc": "{{name}} をバージョン {{version}} にアップデートしますか?", "hub_update_unstable_warning": "このバージョンは安定版チャンネルのものではない可能性があり、不具合を含むおそれがあります。", - "hub_update_title": "{name} のアップデート", + "hub_update_title": "{{name}} のアップデート", "hub_update_subtitle": "このハブのファームウェアアップデートを管理します。", "hub_update_status_title": "ハブの状態", - "hub_update_firmware": "ファームウェア: {#mono}{version}{/mono}", + "hub_update_firmware": "ファームウェア: {{version}}", "hub_update_confirm": "アップデート", "hub_update_success": "アップデートが正常に完了しました", "hub_update_rolled_back": "デバイスは以前のバージョンにロールバックされました", @@ -569,9 +544,9 @@ "hub_update_flash_again": "再書き込み", "hub_update_card_title": "ファームウェアのアップデート", "hub_update_card_desc": "インストールするファームウェアのチャンネルとバージョンを選択してください。", - "hub_update_to": "{version} にアップデート", + "hub_update_to": "{{version}} にアップデート", "hub_update_must_be_online": "アップデートを開始するには、ハブがオンラインである必要があります。", - "hub_update_updating_to": "{version} にアップデートしています...", + "hub_update_updating_to": "{{version}} にアップデートしています...", "hub_update_total": "全体", "hub_update_task": "タスク", "hub_update_history": "アップデート履歴", @@ -583,14 +558,14 @@ "hub_update_not_found": "ハブが見つかりません。", "home_breadcrumb": "ホーム", "home_welcome": "おかえりなさい", - "home_welcome_name": "おかえりなさい、{name} さん", + "home_welcome_name": "おかえりなさい、{{name}} さん", "home_subtitle": "OpenShock のセットアップの概要です。", - "home_hubs_online": "{count} 台オンライン", + "home_hubs_online": "{{count}} 台オンライン", "home_hub_status": "ハブの状態", "home_no_hubs": "ハブなし", "home_all_online": "すべてオンライン", "home_all_offline": "すべてオフライン", - "home_some_online": "{online}/{total} 台オンライン", + "home_some_online": "{{online}}/{{total}} 台オンライン", "home_quick_links": "クイックリンク", "home_my_shockers": "マイショッカー", "home_my_shockers_desc": "ショッカーを操作", @@ -601,23 +576,15 @@ "home_get_started_desc": "ハブがまだありません。ハブを作成して最初のデバイスを接続し、ショッカーを追加してください。", "home_set_up_hub": "ハブをセットアップ", "home_first_shocker": "最初のショッカーを追加", - "home_first_shocker_desc": [ - { - "declarations": ["input count", "local countPlural = count: plural"], - "selectors": ["countPlural"], - "match": { - "countPlural=other": "{count} 台のハブがセットアップ済みです。ショッカーを追加して操作を始めましょう。" - } - } - ], + "home_first_shocker_desc_one": "You have {{count}} hub set up. Add a shocker to start controlling it.", + "home_first_shocker_desc_other": "{{count}} 台のハブがセットアップ済みです。ショッカーを追加して操作を始めましょう。", "home_go_to_shockers": "ショッカーへ移動", "profile_title": "プロフィール", "profile_coming_soon": "プロフィールは近日公開予定です", "profile_coming_soon_desc": "公開プロフィールはまだご利用いただけません。アカウントの詳細は設定にあります。", - "common_retry": "再試行", "common_never_used": "未使用", - "common_expires": "有効期限: {time}", + "common_expires": "有効期限: {{time}}", "common_search_placeholder": "検索...", "common_unknown": "不明", "settings_breadcrumb_account": "アカウント", @@ -647,7 +614,7 @@ "account_deactivate": "アカウントを無効化", "account_email_title": "メールアドレスの変更", "account_email_desc": "新しいメールアドレスを入力し、現在のパスワードで確認してください。", - "account_email_toast_sent": "{email} に確認メールを送信しました。メール内のリンクをクリックすると変更が適用されます。", + "account_email_toast_sent": "{{email}} に確認メールを送信しました。メール内のリンクをクリックすると変更が適用されます。", "account_new_email": "新しいメールアドレス", "account_current_password": "現在のパスワード", "account_password_title": "パスワードの変更", @@ -662,8 +629,8 @@ "tokens_toast_refreshed": "トークンを更新しました", "tokens_empty_title": "API トークンはありません", "tokens_empty_desc": "OpenShock API で認証するためのトークンを生成してください。", - "tokens_created_on": "作成日: {date}", - "tokens_last_used": "最終使用: {time}", + "tokens_created_on": "作成日: {{date}}", + "tokens_last_used": "最終使用: {{time}}", "tokens_never_expires": "無期限", "tokens_load_failed": "API トークンを読み込めませんでした。", "token_toast_edited": "トークンを編集しました", @@ -685,7 +652,7 @@ "token_toast_paused": "トークンを一時停止しました", "token_toast_resumed": "トークンを再開しました", "token_delete_title": "API トークンの削除", - "token_delete_desc": "{#strong}{name}{/strong} を削除してもよろしいですか?", + "token_delete_desc": "{{name}} を削除してもよろしいですか?", "token_delete_permanent": "この操作は元に戻せません。トークンは完全に削除されます。", "token_toast_deleted": "トークンを削除しました", "token_resume": "トークンを再開", @@ -698,11 +665,11 @@ "token_new_breadcrumb": "新規", "token_redirect_not_allowed": "指定された redirect_uri は許可されていません。ループバックアドレスまたはカスタムアプリケーションスキームのみ使用できます。", "token_params_missing": "必要な GET パラメーターがありません。name、redirect_uri、permissions が指定されているか確認してください。", - "token_invalid_permissions": "無効な権限が指定されました: {list}", + "token_invalid_permissions": "無効な権限が指定されました: {{list}}", "token_toast_created": "トークンを作成しました", "token_request_title": "API トークンのリクエスト", "token_access_granted": "アクセスを許可しました", - "token_shared_redirecting": "トークンが作成され、アプリケーションと共有されました。{#b}{uri}{/b} にリダイレクトしています。", + "token_shared_redirecting": "トークンが作成され、アプリケーションと共有されました。{{uri}} にリダイレクトしています。", "token_not_redirected": "自動的にリダイレクトされない場合は、下のボタンを使用してください。", "token_finish": "完了", "token_generated_title": "API トークンを生成しました", @@ -710,7 +677,7 @@ "token_new_title": "新しい API トークン", "token_external_desc": "外部アプリケーションがアカウントへのアクセスを求めています。許可する前に、以下の権限を確認・調整してください。", "token_new_desc": "アカウント用の新しい API トークンを設定して生成します。", - "token_external_requesting": "{#b}{name}{/b} が API トークンを求めています。トークンは {#b}{uri}{/b} のアプリケーションと共有されます。", + "token_external_requesting": "{{name}} が API トークンを求めています。トークンは {{uri}} のアプリケーションと共有されます。", "token_allow": "許可", "token_generate": "生成", "token_deny": "拒否", @@ -720,13 +687,13 @@ "sessions_load_failed": "セッションを読み込めませんでした。", "sessions_empty_title": "有効なセッションはありません", "sessions_empty_desc": "ブラウザーやアプリからログインすると、ここにセッションが表示されます。", - "sessions_last_seen": "最終アクセス: {time}", - "sessions_signed_in": "ログイン: {time}", + "sessions_last_seen": "最終アクセス: {{time}}", + "sessions_signed_in": "ログイン: {{time}}", "session_toast_revoked": "セッションを取り消しました", "session_revoke_title": "セッションの取り消し", "session_revoke": "取り消し", "session_revoke_desc": "このセッションを取り消してもよろしいですか?", - "session_revoke_from": "{#strong}{ip}{/strong} から {#strong}{agent}{/strong} でログインしたセッション", + "session_revoke_from": "{{ip}} から {{agent}} でログインしたセッション", "connections_title": "OAuth 連携", "connections_subtitle": "外部アカウントを連携または解除して、すばやくログインし、プロフィールを同期できます。", "connections_toast_linked": "アカウントを連携しました。", @@ -739,11 +706,11 @@ "connections_empty_desc": "上の「新しいプロバイダーを連携」から、利用可能なプロバイダーを連携してください。", "connections_unlink": "連携解除", "connections_load_failed": "OAuth 連携を読み込めませんでした。", - "connections_unlink_title": "{name} の連携を解除しますか?", + "connections_unlink_title": "{{name}} の連携を解除しますか?", "connections_unlink_title_generic": "このアカウントの連携を解除しますか?", "connections_unlink_desc": "再度連携しない限り、このプロバイダーではログインできなくなります。", - "provider_starting": "{name} を開始しています...", - "provider_link": "{name} を連携", + "provider_starting": "{{name}} を開始しています...", + "provider_link": "{{name}} を連携", "audit_subtitle": "アカウントのセキュリティに関わるアクティビティです。心当たりのないものがないか確認してください。", "audit_col_time": "時刻", "audit_col_action": "操作", @@ -769,21 +736,13 @@ "audit_action_automation_token_rotated": "自動化トークンのローテーション", "audit_action_automation_token_deleted": "自動化トークンの削除", "audit_action_automation_token_used": "自動化トークンの使用", - "audit_meta_session": "セッション {id}", - "audit_meta_changed": "{old} から {new} へ", - "audit_meta_email_requested": "{email} への変更をリクエスト", - "audit_meta_accounts_removed": [ - { - "declarations": ["input count", "local countPlural = count: plural"], - "selectors": ["countPlural"], - "match": { - "countPlural=other": "{name}({count} 件のアカウントを削除)" - } - } - ], + "audit_meta_session": "セッション {{id}}", + "audit_meta_changed": "{{old}} から {{new}} へ", + "audit_meta_email_requested": "{{email}} への変更をリクエスト", + "audit_meta_accounts_removed_one": "{{name}} ({{count}} account removed)", + "audit_meta_accounts_removed_other": "{{name}}({{count}} 件のアカウントを削除)", "audit_meta_scheduled_deletion": "削除予定", "audit_meta_kept": "再有効化のため保持", - "common_view": "表示", "common_save": "保存", "common_saving": "保存しています...", @@ -808,19 +767,12 @@ "public_share_create_title": "公開共有を作成", "public_share_toast_deleted": "公開共有を削除しました", "public_share_delete_title": "公開共有を削除", - "public_share_delete_desc": "公開共有 {#strong}{name}{/strong} を削除してもよろしいですか?", - "public_share_edit_title": "公開共有: {name}", + "public_share_delete_desc": "公開共有 {{name}} を削除してもよろしいですか?", + "public_share_edit_title": "公開共有: {{name}}", "public_share_edit_subtitle": "編集中: 変更は保存時に適用されます。", "public_share_add_shocker": "ショッカーを追加", - "public_share_toast_added": [ - { - "declarations": ["input count", "local countPlural = count: plural"], - "selectors": ["countPlural"], - "match": { - "countPlural=other": "{count} 台のショッカーを共有に追加しました" - } - } - ], + "public_share_toast_added_one": "Added {{count}} shocker to share", + "public_share_toast_added_other": "{{count}} 台のショッカーを共有に追加しました", "public_share_empty_shockers_title": "この共有にショッカーはありません", "public_share_empty_shockers_desc": "ショッカーを追加すると、リンクを持つ誰もが操作できるようになります。", "public_share_load_failed": "公開共有の詳細を取得できませんでした", @@ -850,15 +802,14 @@ "perm_live_on": "ライブ有効", "perm_live_off": "ライブ無効", "perm_live_control": "ライブコントロール", - "user_selector_avatar_of": "{name}のアバター", + "user_selector_avatar_of": "{{name}}のアバター", "user_selector_placeholder": "ユーザー名を入力", "user_selector_aria": "検索するユーザー名", "user_selector_search": "ユーザーを検索", "user_selector_found": "ユーザーが見つかりました", - "common_remove": "削除", "user_shares_subtitle": "他のユーザーとの直接の恒久的な共有です。", - "user_shares_toast_invited": "{name} にショッカーの招待を送信しました", + "user_shares_toast_invited": "{{name}} にショッカーの招待を送信しました", "user_shares_redeem": "コードを使用", "user_shares_new": "新しい共有", "user_shares_tab_shares": "共有", @@ -881,12 +832,12 @@ "share_code_redeem": "使用", "incoming_shares_empty_title": "共有されたものはありません", "incoming_shares_empty_desc": "まだ誰もショッカーを共有していません。", - "incoming_share_toast_removed": "{name} の共有を削除しました", + "incoming_share_toast_removed": "{{name}} の共有を削除しました", "incoming_share_remove_title": "共有を削除", - "incoming_share_remove_desc": "{#strong}{name}{/strong} の共有を削除してもよろしいですか?", - "incoming_share_toast_removed_shocker": "{name} が共有した {shocker} を削除しました", + "incoming_share_remove_desc": "{{name}} の共有を削除してもよろしいですか?", + "incoming_share_toast_removed_shocker": "{{name}} が共有した {{shocker}} を削除しました", "incoming_share_remove_shocker_title": "この共有ショッカーを削除しますか?", - "incoming_share_remove_shocker_desc": "{#strong}{name}{/strong} が共有したショッカー {#strong}{shocker}{/strong} を削除してもよろしいですか?", + "incoming_share_remove_shocker_desc": "{{name}} が共有したショッカー {{shocker}} を削除してもよろしいですか?", "incoming_share_manage_from": "共有の管理元", "share_remove": "共有を削除", "invites_empty_title": "招待はまだありません", @@ -897,23 +848,23 @@ "invites_incoming": "受信", "invites_incoming_empty_title": "受信した招待はありません", "invites_incoming_empty_desc": "受信した共有の招待はありません。", - "invite_toast_accepted": "{name} からの共有の招待を承認しました", - "invite_toast_declined": "{name} からの共有の招待を辞退しました", + "invite_toast_accepted": "{{name}} からの共有の招待を承認しました", + "invite_toast_declined": "{{name}} からの共有の招待を辞退しました", "invite_deny_title": "招待を拒否", "invite_deny_label": "招待を拒否", "invite_deny": "拒否", - "invite_deny_desc": "{#strong}{name}{/strong} からの招待を拒否してもよろしいですか?", + "invite_deny_desc": "{{name}} からの招待を拒否してもよろしいですか?", "invite_accept": "招待を承認", - "invite_toast_cancelled_for": "{name}({id})への招待を取り消しました", - "invite_toast_cancelled": "招待 {id} を取り消しました", + "invite_toast_cancelled_for": "{{name}}({{id}})への招待を取り消しました", + "invite_toast_cancelled": "招待 {{id}} を取り消しました", "invite_cancel_title": "招待を取り消す", "invite_cancel": "取り消し", - "invite_cancel_for_desc": "{#strong}{name}{/strong} への招待を取り消してもよろしいですか?", - "invite_cancel_code_desc": "コード {#strong}{code}{/strong} の招待を取り消してもよろしいですか?", + "invite_cancel_for_desc": "{{name}} への招待を取り消してもよろしいですか?", + "invite_cancel_code_desc": "コード {{code}} の招待を取り消してもよろしいですか?", "invite_cancel_outstanding": "未処理の招待を取り消す", "outgoing_shares_empty_title": "共有中のショッカーはありません", "outgoing_shares_empty_desc": "まだ他のユーザーとショッカーを共有していません。", - "outgoing_share_toast_removed": "ショッカーの共有 {name} を削除しました", + "outgoing_share_toast_removed": "ショッカーの共有 {{name}} を削除しました", "outgoing_share_remove_title": "このショッカーの共有を停止しますか?", "outgoing_share_editing_for": "共有を編集中:", "outgoing_share_limits": "上限と権限", @@ -921,11 +872,9 @@ "outgoing_share_per_desc": "ショッカーごとに制限を調整", "outgoing_share_all": "すべて", "outgoing_share_per": "ショッカーごと", - - "outgoing_share_remove_desc": "{#strong}{name}{/strong} との {#strong}{shocker}{/strong} の共有を停止してもよろしいですか?", - + "outgoing_share_remove_desc": "{{name}} との {{shocker}} の共有を停止してもよろしいですか?", "report_breadcrumb": "API トークンの報告", - "report_toast_clipboard_failed": "クリップボードを読み取れませんでした: {error}", + "report_toast_clipboard_failed": "クリップボードを読み取れませんでした: {{error}}", "report_title": "流出した API トークンの報告", "report_paste": "クリップボードから貼り付け", "report_warning": "このフォームは、誤って流出した API トークンの報告専用です。", @@ -943,18 +892,11 @@ "expiration_label": "有効期限", "expiration_never": "なし", "expiration_custom": "カスタム", - "expiration_days": [ - { - "declarations": ["input count", "local countPlural = count: plural"], - "selectors": ["countPlural"], - "match": { - "countPlural=other": "{count} 日" - } - } - ], + "expiration_days_one": "{{count}} Day", + "expiration_days_other": "{{count}} 日", "expiration_required": "有効期限は必須です", "expiration_never_desc": "期限切れになりません", - "expiration_expires_at": "有効期限: {time}({date})", + "expiration_expires_at": "有効期限: {{time}}({{date}})", "date_picker_placeholder": "日付を選択", "telemetry_toast_title": "OpenShock の改善にご協力いただけますか?", "telemetry_toast_desc": "診断情報を送信して、クラッシュや遅い API 呼び出しの修正にご協力ください。レポートにはエラーメッセージ、スタックトレース、IP アドレスが含まれます。この設定はアカウント設定でいつでも変更できます。", @@ -964,28 +906,27 @@ "table_show_details": "詳細を表示", "table_hide_details": "詳細を非表示", "table_no_results": "結果はありません。", - "table_sort_asc": "{name}で昇順に並べ替え", - "table_sort_desc": "{name}で降順に並べ替え", - "table_sort_none": "{name}で並べ替え、未ソート", + "table_sort_asc": "{{name}}で昇順に並べ替え", + "table_sort_desc": "{{name}}で降順に並べ替え", + "table_sort_none": "{{name}}で並べ替え、未ソート", "cell_na": "N/A", "cell_not_applicable": "該当なし", "cell_invalid": "無効", "cell_unavailable": "利用不可", "cell_none": "なし", - "oauth_login_with": "{provider} でログイン", - "oauth_signup_with": "{provider} で登録", + "oauth_login_with": "{{provider}} でログイン", + "oauth_signup_with": "{{provider}} で登録", "signalr_connect_failed": "サーバーに接続できませんでした!", "signalr_disconnect_failed": "サーバーからの切断中にエラーが発生しました!", "signalr_invalid_update": "サーバーから無効な更新を受信しました!", "signalr_invalid_log": "サーバーから無効なログデータを受信しました!", "signalr_invalid_ota": "サーバーから無効なファームウェア更新データを受信しました!", - "ota_toast_failed": "ハブのファームウェアアップデートに失敗しました: {message}", + "ota_toast_failed": "ハブのファームウェアアップデートに失敗しました: {{message}}", "ota_toast_succeeded": "ハブのファームウェアアップデートが完了しました!", "ota_toast_rolled_back": "ハブのファームウェアが以前のバージョンにロールバックされました", "lcg_connect_failed": "ライブコントロールゲートウェイに接続できませんでした", - "terminal_toast_bootloader_failed": "ブートローダーに入れませんでした: {error}", - "terminal_toast_app_mode_failed": "アプリケーションモードに入れませんでした: {error}", - + "terminal_toast_bootloader_failed": "ブートローダーに入れませんでした: {{error}}", + "terminal_toast_app_mode_failed": "アプリケーションモードに入れませんでした: {{error}}", "problem_account_account_not_activated_title": "アカウントが有効化されていません", "problem_account_account_not_activated_desc": "受信トレイで有効化メールをご確認ください。", "problem_account_activation_not_found_title": "有効化リンクが無効です", @@ -1103,21 +1044,12 @@ "problem_webhook_not_found_title": "Webhook が見つかりません", "problem_webhook_unsupported_title": "Discord の Webhook のみサポートしています", "problem_webhook_unsupported_desc": "canary や ptb ではなく、discord.com の URL を使用してください。", - "error_too_many_requests": "リクエストが多すぎます", - "error_retry_after": [ - { - "declarations": ["input seconds", "local secondsPlural = seconds: plural"], - "selectors": ["secondsPlural"], - "match": { - "secondsPlural=other": "{seconds} 秒後にもう一度お試しください。" - } - } - ], + "error_retry_after_one": "Try again in {{count}} second.", + "error_retry_after_other": "{{count}} 秒後にもう一度お試しください。", "error_unexpected_response": "予期しないサーバー応答です", "error_internal": "内部エラーが発生しました", "error_network": "ネットワークエラーが発生しました", - - "dev_banner": "これは OpenShock の{#b}開発{/b}環境です。{#u}データは保存されず{/u}、定期的に本番環境のデータで上書きされます。", + "dev_banner": "これは OpenShock の開発環境です。データは保存されず、定期的に本番環境のデータで上書きされます。", "firmware_channel_bugs_warning": "このチャンネルには不具合が含まれる可能性があります。" } From 6e338f3f138d974ae8b4f6f2b50458e5972c2fe1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Luc=20=E2=99=A5?= Date: Thu, 12 Nov 2026 17:43:22 +0100 Subject: [PATCH 16/27] New translations en.json (Korean) [ci skip] --- messages/ko.json | 1055 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 1055 insertions(+) create mode 100644 messages/ko.json diff --git a/messages/ko.json b/messages/ko.json new file mode 100644 index 00000000..ef4df56c --- /dev/null +++ b/messages/ko.json @@ -0,0 +1,1055 @@ +{ + "landing_tagline": "The go-to platform for safe, reliable, real low-latency remote shocking.", + "landing_section_label": "Home", + "landing_hubs_online": "Hubs online right now: ", + "landing_learn_more": "Learn More", + "landing_wiki": "Wiki", + "landing_meta_description": "Welcome to OpenShock, a free and open-source ecosystem to control various shock collars over the internet.", + "instance_meta_description": "Welcome to {{siteName}}, an independent instance of OpenShock, a free and open-source ecosystem to control various shock collars over the internet.", + "header_sidebar_toggle": "Toggle Sidebar", + "header_avatar_alt": "{{name}}'s avatar", + "header_menu_profile": "Profile", + "header_menu_settings": "Settings", + "header_menu_logout": "Logout", + "header_login": "Login", + "header_signup": "Sign Up", + "header_github_title": "OpenShock on GitHub", + "header_discord_title": "Community Discord", + "footer_made_with": "Made with by the OpenShock Team", + "footer_connection_status_label": "Server connection status", + "footer_signalr_state": "SignalR State", + "footer_frontend_version": "Frontend Version", + "footer_frontend_commit_title": "Commit {{commit}}", + "footer_backend_version": "Backend Version", + "footer_backend_commit_title": "Commit {{commit}}", + "footer_language_label": "Language", + "sidebar_home_link_label": "OpenShock home", + "sidebar_group_general": "General", + "sidebar_home": "Home", + "sidebar_shockers": "Shockers", + "sidebar_shared_shockers": "Shared Shockers", + "sidebar_hubs": "Hubs", + "sidebar_user_shares": "User Shares", + "sidebar_public_shares": "Public Shares", + "sidebar_serial_terminal": "Serial Terminal", + "sidebar_group_admin": "Admin", + "sidebar_admin_monitoring": "Monitoring", + "sidebar_admin_online_hubs": "Online Hubs", + "sidebar_admin_online_gateways": "Online Gateways", + "sidebar_admin_management": "Management", + "sidebar_admin_users": "Users", + "sidebar_admin_blacklists": "Blacklists", + "sidebar_admin_webhooks": "Webhooks", + "sidebar_admin_mail": "Mail", + "sidebar_admin_automation_tokens": "Automation Tokens", + "sidebar_admin_configuration": "Configuration", + "sidebar_group_settings": "Settings", + "sidebar_settings_api_tokens": "API Tokens", + "sidebar_settings_sessions": "Sessions", + "sidebar_settings_audit_log": "Audit Log", + "sidebar_settings_connections": "Connections", + "sidebar_settings_account": "Account Settings", + "error_meta_title": "Service Unavailable", + "error_meta_description": "OpenShock is currently unavailable", + "error_meta_logo_alt": "OpenShock Logo", + "error_fallback_message": "Something went wrong.", + "error_not_found_message": "Page not found", + "error_not_found_description": "The page you're looking for doesn't exist.", + "error_unexpected_description": "An unexpected error occurred.", + "error_go_back": "Go back", + "auth_layout_logo_alt": "OpenShock Logo", + "auth_layout_invalid_redirect_removed": "An invalid redirect URL was removed for your safety.", + "auth_activate_breadcrumb": "Activate Account", + "auth_activate_title": "Activate Account", + "auth_activate_activating": "Activating your account...", + "auth_activate_success": "Your account has been activated", + "auth_activate_failed": "This activation link is invalid or has expired", + "auth_activate_missing_token": "Missing activation token", + "auth_activate_continue": "Continue to login", + "auth_activate_toast_success": "Account activated", + "auth_forgot_breadcrumb": "Forgot Password", + "auth_forgot_title": "Forgot Password", + "auth_forgot_description": "Enter your email to reset your password", + "auth_forgot_email_label": "Email", + "auth_forgot_email_placeholder": "Email", + "auth_forgot_submit": "Reset Password", + "auth_forgot_signin_prompt": "Remember your password? Sign in", + "auth_forgot_mail_disabled": "Password resets are unavailable on this instance because it has no mail provider configured. Please contact your administrator for help recovering your account.", + "auth_forgot_toast_sent": "Reset password request has been sent to the given email", + "auth_login_breadcrumb": "Login", + "auth_login_title": "Welcome back", + "auth_login_loading_methods": "Loading available login methods", + "auth_login_choose_method": "Login with one of these methods", + "auth_login_with_account": "Login with your OpenShock Account", + "auth_login_activation_after_signup": "Your account has been created. We've sent an activation link to your email address. Check your inbox and spam folder.", + "auth_login_activation_pending": "Your account isn't activated yet. We've sent an activation link to your email address. Check your inbox and spam folder. If nothing arrives, try logging in again later to get a new link.", + "auth_login_oauth_only": "This account has no password. Sign in with the provider you signed up with.", + "auth_login_oauth_only_with_buttons": "This account has no password. Sign in with the provider you signed up with using the buttons above.", + "auth_login_or_continue_with": "Or continue with", + "auth_login_username_label": "Username or Email", + "auth_login_password_label": "Password", + "auth_login_submit": "Login", + "auth_login_signup_prompt": "Don't have an account? Sign up", + "auth_login_legal": "By clicking Login, you agree to our Terms of Service and Privacy Policy.", + "auth_oauth_create_breadcrumb": "Sign Up With {{provider}}", + "auth_oauth_create_title": "Sign Up With {{provider}}", + "auth_oauth_create_description": "Complete your account details", + "auth_oauth_create_username_label": "Username", + "auth_oauth_create_username_placeholder": "Username", + "auth_oauth_create_email_label": "Email", + "auth_oauth_create_email_placeholder": "Email", + "auth_oauth_create_submit": "Sign Up", + "auth_oauth_create_legal": "By clicking Sign Up, you agree to our Terms of Service and Privacy Policy.", + "auth_oauth_error_breadcrumb": "Authentication Error", + "auth_oauth_error_title": "Authentication Error", + "auth_oauth_error_back": "Back to login", + "auth_reset_breadcrumb": "Reset Password", + "auth_reset_title": "Reset Password", + "auth_reset_checking": "Verifying reset link...", + "auth_reset_choose_password": "Choose a new password for your account", + "auth_reset_invalid": "This reset link is invalid or has expired", + "auth_reset_password_label": "New Password", + "auth_reset_password_placeholder": "New Password", + "auth_reset_confirm_label": "Confirm New Password", + "auth_reset_confirm_placeholder": "Confirm New Password", + "auth_reset_submit": "Reset Password", + "auth_reset_request_new": "Request a new reset link", + "auth_reset_toast_success": "Password has been reset", + "auth_signup_breadcrumb": "Sign Up", + "auth_signup_toast_created_mail": "Account created successfully. Please check your email to verify your account.", + "auth_signup_toast_created_no_mail": "Account created successfully. You can log in now.", + "auth_signup_dialog_title": "Welcome! Thank you for signing up! ❤️", + "auth_signup_dialog_created_mail": "Your account has been created. 🎉 Please check your email to verify your account.", + "auth_signup_dialog_verify_then_login": "After verifying your email, you can log in to your account.", + "auth_signup_dialog_created_no_mail": "Your account has been created and is ready to use. 🎉", + "auth_signup_dialog_login_now": "You can log in to your account now.", + "auth_signup_title": "Create your account", + "auth_signup_loading_methods": "Loading available sign-up methods", + "auth_signup_using_email": "Signing up using email", + "auth_signup_choose_method": "Choose your preferred sign-up method", + "auth_signup_back": "Back", + "auth_signup_username_label": "Username", + "auth_signup_username_placeholder": "John OpenShock", + "auth_signup_email_label": "Email", + "auth_signup_email_placeholder": "john@example.com", + "auth_signup_password_label": "Password", + "auth_signup_password_placeholder": "Password", + "auth_signup_confirm_label": "Confirm Password", + "auth_signup_confirm_placeholder": "Confirm Password", + "auth_signup_submit": "Create Account", + "auth_signup_signin_prompt": "Already have an account? Sign in", + "auth_signup_or": "Or", + "auth_signup_with_email": "Signup with Email", + "auth_signup_legal": "By clicking Create Account, you agree to our Terms of Service and Privacy Policy.", + "auth_verify_breadcrumb": "Verify Email", + "auth_verify_title": "Verify Email", + "auth_verify_verifying": "Verifying your email address...", + "auth_verify_success": "Your email has been verified", + "auth_verify_failed": "This verification link is invalid or has expired", + "auth_verify_missing_token": "Missing verification token", + "auth_verify_continue": "Continue to login", + "auth_verify_toast_success": "Email verified", + "common_cancel": "Cancel", + "common_delete": "Delete", + "common_edit": "Edit", + "common_share": "Share", + "common_copy_id": "Copy ID", + "common_id_copied": "ID copied to clipboard", + "common_open_menu": "Open menu", + "common_refresh": "Refresh", + "common_settings": "Settings", + "common_clear": "Clear", + "common_online": "Online", + "common_offline": "Offline", + "common_paused": "Paused", + "common_resume": "Resume", + "common_resuming": "Resuming...", + "common_coming_soon": "(Coming soon)", + "common_save_changes": "Save Changes", + "common_danger_zone": "Danger Zone", + "common_name": "Name", + "control_intensity": "Intensity", + "control_duration": "Duration", + "control_max_intensity": "Max Intensity", + "control_max_duration": "Max Duration", + "control_vibration": "Vibration", + "control_value": "Value", + "control_live_intensity": "Live intensity", + "control_type_stop": "Stop", + "control_type_shock": "Shock", + "control_type_vibrate": "Vibrate", + "control_type_sound": "Sound", + "live_tooltip_active": "Live via {{gateway}} ({{country}}), {{latency}}ms", + "live_tooltip_connecting": "Connecting...", + "live_tooltip_connect": "Connect to Live Control", + "live_tooltip_hub_start": "Ctrl+click to start the whole hub", + "live_tooltip_hub_stop": "Ctrl+click to stop the whole hub", + "pause_resume_shocker": "Resume shocker", + "pause_pause_shocker": "Pause shocker", + "pause_resume_all": "Resume all shockers", + "pause_pause_all": "Pause all shockers", + "shocker_label": "Shocker", + "shocker_hub": "Hub", + "shocker_select_hub": "Select hub", + "shocker_rf_id": "RF ID", + "shocker_rf_id_invalid": "RF ID must be a whole number between {{min}} and {{max}}.", + "shocker_model": "Model", + "shocker_select_model": "Select model", + "shocker_name_placeholder": "Shocker name", + "shocker_menu_view_logs": "View Logs", + "shocker_delete_title": "Delete Shocker", + "shocker_delete_desc": "Are you sure you want to delete \"{{name}}\"? This action cannot be undone.", + "shocker_toast_deleted": "Shocker \"{{name}}\" deleted", + "shocker_toast_paused": "Shocker paused", + "shocker_toast_resumed": "Shocker resumed", + "shocker_add_desc": "Register a new shocker to one of your hubs.", + "shocker_add_name_placeholder": "My Shocker", + "shockers_title": "Shockers", + "shockers_subtitle": "Every shocker paired to your hubs.", + "shockers_loading": "Loading shockers...", + "shockers_toast_refreshed": "Shockers refreshed", + "shockers_toast_need_hub": "You need to create a hub before adding shockers.", + "shockers_toast_added": "Shocker added", + "shockers_unknown_module": "Unknown module type", + "shockers_add": "Add Shocker", + "shockers_view_mode": "View mode", + "shockers_mode_classic": "Classic", + "shockers_mode_rich": "Rich", + "shockers_mode_simple": "Simple", + "shockers_mode_map": "Map", + "shockers_group_by_hub": "Group by Hub", + "shockers_global_limits": "Global Limits", + "shockers_logs_label": "Logs", + "shockers_empty_title": "No shockers yet", + "shockers_empty_no_hubs": "Create a hub first, then add shockers to it.", + "shockers_empty_has_hubs": "Add a shocker to one of your hubs to get started.", + "shockers_create_hub": "Create a Hub", + "shockers_count_one": "{{count}} shocker", + "shockers_count_other": "{{count}} shockers", + "shared_shockers_title": "Shared Shockers", + "shared_shockers_subtitle": "Shockers other users have shared with you.", + "shared_shockers_empty_title": "No shockers have been shared with you yet.", + "shared_shockers_empty_desc": "When someone shares their shockers with you, they'll appear here.", + "shocker_logs_title": "Shocker Logs", + "shocker_logs_subtitle": "Every control command sent to your shockers.", + "shocker_logs_live_title": "New logs appear in real time", + "shocker_logs_paused_title": "Live updates pause when sorting or viewing a page other than the first", + "shocker_logs_live": "Live", + "shocker_logs_col_time": "Time", + "shocker_logs_col_type": "Type", + "shocker_logs_col_by": "By", + "shocker_logs_filter_label": "Filter by shocker", + "shocker_logs_filter_placeholder": "Search shockers...", + "shocker_logs_filter_all": "All shockers", + "shocker_logs_filter_none": "No matching shockers", + "shocker_edit_title": "Edit Shocker", + "shocker_edit_subtitle": "Change this shocker's details or remove it.", + "shocker_edit_back": "Back to Shockers", + "shocker_edit_load_failed": "Failed to load shocker.", + "shocker_edit_loading": "Loading shocker...", + "shocker_edit_details_title": "Shocker Details", + "shocker_edit_details_desc": "Update the name, RF ID, and model for this shocker.", + "shocker_edit_pause_state": "Pause State", + "shocker_edit_is_paused": "Shocker is paused", + "shocker_edit_is_active": "Shocker is active", + "shocker_edit_toast_updated": "Shocker updated", + "shocker_edit_delete_desc": "Permanently delete this shocker. This action cannot be undone.", + "common_close": "Close", + "common_continue": "Continue", + "common_loading": "Loading...", + "common_previous": "Previous", + "common_next": "Next", + "common_steps": "Steps", + "common_step_label": "Step {{number}}: {{title}}", + "common_copy": "Copy", + "common_copied": "Copied", + "common_never": "Never", + "common_error": "Error: {{message}}", + "terminal_title": "Serial Terminal", + "terminal_connecting": "Connecting...", + "terminal_help_button": "I'm having trouble, help?", + "terminal_back_to_modes": "Back to mode picker", + "terminal_mode_configure": "Configure Device", + "terminal_mode_configure_desc": "Configure WiFi, authentication, and more. Includes an interactive serial console.", + "terminal_mode_flash": "Flash Firmware", + "terminal_mode_flash_desc": "Install or update firmware on a connected device.", + "terminal_mode_raw": "Serial Monitor", + "terminal_mode_raw_desc": "Just the console. Read device logs and send commands.", + "terminal_step_channel": "Select Channel", + "terminal_step_board": "Select Board", + "terminal_go_to_step": "Go to step {{number}}: {{title}}", + "terminal_erase": "Erase before flashing", + "terminal_erase_desc": "Clears all data on the device including existing configs", + "terminal_unsupported": "Your browser does not support this feature.", + "terminal_update_browser": "Please update your browser to the latest version.", + "terminal_use_browsers": "Please use one of the following browsers:", + "terminal_connect_failed_bootloader": "Could not enter bootloader mode", + "terminal_connect_failed": "Device connection failed", + "terminal_connect_failed_desc": "We couldn't establish a serial connection with the device.", + "terminal_quick_tries": "Quick things to try:", + "terminal_try_replug": "Unplug and replug the device.", + "terminal_try_cable": "Try a different USB cable or port.", + "terminal_try_driver": "Make sure the serial driver is installed.", + "terminal_open_troubleshooter": "Open troubleshooter", + "terminal_log_reset_no_device": "Host-side error during reset: no device!", + "terminal_log_reset_error": "Host-side error during reset: {{error}}", + "terminal_log_send_no_device": "Couldn't send: no device!", + "terminal_log_send_error": "Couldn't send: {{error}}", + "terminal_log_firmware_disconnected": "Firmware disconnected: {{error}}", + "terminal_log_erase_failed": "Failed to erase flash: {{error}}", + "terminal_log_hard_reset_failed": "Failed to hard reset: {{error}}", + "terminal_log_flash_complete": "Flash complete", + "terminal_log_flash_failed": "Failed to flash: {{error}}", + "terminal_log_command_failed": "Failed to write application command: {{error}}", + "terminal_help_title": "Troubleshooter", + "terminal_help_desc": "Work through these steps in order. Each one rules out a common cause.", + "terminal_help_step_cable": "USB cable", + "terminal_help_step_port": "USB port", + "terminal_help_step_driver": "Install driver", + "terminal_help_step_manual": "Manual driver update", + "terminal_help_step_discord": "Ask on Discord", + "terminal_help_cable_body": "Many USB-C and micro-USB cables are charge-only and don't carry data. Swap to a known-good data cable (one you've used to transfer files or connect other devices) and reconnect the hub.", + "terminal_help_port_body": "Plug the device directly into a USB port on your computer. Avoid USB hubs, docking stations, and front-panel ports if possible; these are common sources of power and signal issues. If you're on a desktop, try a port on the back of the machine.", + "terminal_help_driver_download": "Download the CP210x driver:", + "terminal_help_driver_extract": "Extract the contents of the zip file to a folder on your computer.", + "terminal_help_driver_run": "Open the folder and run {{installer}}. Follow the prompts to install.", + "terminal_help_driver_reconnect": "Reconnect the device.", + "terminal_help_manual_intro": "If the driver installer ran but the device still doesn't show up:", + "terminal_help_manual_open": "Open Device Manager (press Win + X and select Device Manager).", + "terminal_help_manual_ports": "Under Ports (COM & LPT), look for an entry like:", + "terminal_help_manual_missing": "If it's missing, the device isn't being detected by Windows at all; revisit the cable and port steps.", + "terminal_help_manual_update": "Right-click the device and pick Update Driver.", + "terminal_help_manual_browse": "Choose Browse my computer for drivers and select the folder you extracted the driver zip into. Make sure Include subfolders is checked.", + "terminal_help_manual_success": "On success, the entry should now read {{deviceName}}.", + "terminal_help_discord_intro": "Still stuck after all of the above? Hop into our Discord server and ask in the {{channel}} channel. Please include:", + "terminal_help_discord_os": "your operating system and browser", + "terminal_help_discord_device": "the device you're using (board model, where you got it)", + "terminal_help_discord_tried": "what you've already tried from the previous steps", + "terminal_help_discord_errors": "any error messages or relevant terminal output", + "terminal_help_discord_join": "Join our Discord server", + "terminal_risk_title": "⚠️ UNSTABLE FIRMWARE", + "terminal_risk_intro": "You are about to flash experimental firmware that is known to be unstable.", + "terminal_risk_brick": "This may permanently brick your device, require manual recovery, or render it unusable.", + "terminal_risk_no_support": "We will NOT provide support for issues caused by this firmware.", + "terminal_risk_acknowledge": "I understand this is entirely my responsibility", + "terminal_risk_abort": "Abort", + "terminal_risk_accept": "I ACCEPT FULL RESPONSIBILITY", + "firmware_channel_recommended": "This is the recommended channel.", + "firmware_channel_danger": "DO NOT USE THIS UNLESS YOU KNOW WHAT YOU ARE DOING", + "firmware_channel_stable": "Stable", + "firmware_channel_beta": "Beta", + "firmware_channel_develop": "Develop", + "terminal_board_select": "Select a board...", + "terminal_board_search": "Search boards...", + "terminal_board_none": "No board found.", + "terminal_flash_button": "Flash", + "terminal_flash_progress": "Flash Progress: {{status}}", + "terminal_flash_idle": "Idle", + "terminal_flash_no_device": "No device selected.", + "terminal_flash_resetting": "Resetting...", + "terminal_flash_downloading": "Downloading firmware...", + "terminal_flash_download_failed": "Failed to download firmware.", + "terminal_flash_flashing": "Flashing firmware...", + "terminal_flash_rebooting": "Rebooting device... (Reconnect to power manually if stuck)", + "terminal_flash_done": "Rebooted device! Flashing complete.", + "terminal_port_select": "Select Device", + "terminal_port_disconnect": "Disconnect Device", + "terminal_port_connected": "Device connected: {{id}}", + "terminal_console": "Console", + "terminal_connected_device": "Connected device", + "terminal_resize": "Resize terminal panel", + "terminal_reboot": "Reboot", + "terminal_disconnect": "Disconnect", + "terminal_fullscreen_exit_esc": "Exit fullscreen (Esc)", + "terminal_fullscreen_exit": "Exit fullscreen", + "terminal_fullscreen_fill": "Fill the window", + "terminal_command_label": "Serial command", + "terminal_command_placeholder": "Type a command...", + "terminal_command_send": "Send command", + "terminal_colors": "Colors", + "terminal_colors_menu": "Colors...", + "terminal_colors_label": "Console colors", + "terminal_colors_close": "Close colors", + "terminal_color_input": "{{name}} color", + "terminal_colors_reset": "Reset to defaults", + "terminal_color_bg": "Background", + "terminal_color_fg": "Text", + "terminal_color_ts": "Timestamp", + "terminal_color_error": "Error", + "terminal_color_warning": "Warning", + "terminal_color_info": "Info", + "terminal_color_debug": "Debug", + "terminal_color_verbose": "Verbose", + "terminal_options": "Options", + "terminal_options_label": "Console options", + "terminal_hide_system": "Hide system messages", + "terminal_stick_bottom": "Stick to bottom", + "terminal_raw_output": "Raw output", + "terminal_timestamps": "Timestamps", + "terminal_timestamp_uptime": "Uptime", + "terminal_timestamp_local": "Local", + "terminal_timestamp_ms": "Ms", + "terminal_timestamp_off": "Off", + "terminal_copy_settings": "Copy settings", + "terminal_import_settings": "Import settings", + "terminal_copy_selection": "Copy selection", + "terminal_copy_all": "Copy all output", + "terminal_toast_selection_copied": "Selection copied", + "terminal_toast_output_copied": "Console output copied", + "terminal_toast_settings_copied": "Console settings copied", + "terminal_toast_clipboard_unreadable": "Could not read the clipboard", + "terminal_toast_settings_imported": "Console settings imported", + "terminal_toast_settings_invalid": "Clipboard does not contain console settings", + "common_try_again": "Try again", + "terminal_cfg_intro": "Values are sent to the device via UART. Read the device's response in the console below. Commands without an argument act as getters; use the button next to each field to read the current value.", + "terminal_cfg_rf_title": "RF Transmitter", + "terminal_cfg_rf_desc": "Controls the shocker RF output.", + "terminal_cfg_tx_pin": "TX GPIO pin", + "terminal_cfg_example": "e.g. {{value}}", + "terminal_cfg_read_value": "Read current value", + "terminal_cfg_set": "Set", + "terminal_cfg_read": "Read", + "terminal_cfg_reading": "Reading…", + "terminal_cfg_apply": "Apply", + "terminal_cfg_keepalive": "Keepalive enabled", + "terminal_cfg_keepalive_desc": "Periodically pings paired shockers to keep them awake.", + "terminal_cfg_estop_title": "Emergency Stop", + "terminal_cfg_estop_desc": "Hardware button that halts all output.", + "terminal_cfg_estop_enabled": "EStop enabled", + "terminal_cfg_estop_pin": "EStop GPIO pin", + "terminal_cfg_estop_note": "Note: {{latching}} and {{active}} have no dedicated commands; set them via the JSON config below.", + "terminal_cfg_wifi_title": "WiFi", + "terminal_cfg_wifi_desc": "Station credentials and device hostname.", + "terminal_cfg_hostname": "Hostname", + "terminal_cfg_networks": "Networks (JSON array)", + "terminal_cfg_invalid_json_array": "Must be a valid JSON array", + "terminal_cfg_ap_note": "AP settings ({{ssid}}, {{password}}, {{disabled}}, {{staDisabled}}, {{offlineMode}}) have no dedicated commands; use the JSON config.", + "terminal_cfg_backend_title": "Backend", + "terminal_cfg_backend_desc": "OpenShock server and authentication.", + "terminal_cfg_domain": "Domain", + "terminal_cfg_domain_restart": "Setting the domain will restart the device.", + "terminal_cfg_auth_token": "Auth token", + "terminal_cfg_auth_token_placeholder": "Paste device token", + "terminal_cfg_hide": "Hide", + "terminal_cfg_show": "Show", + "terminal_cfg_serial_title": "Serial Input", + "terminal_cfg_echo": "Echo enabled", + "terminal_cfg_echo_desc": "Print typed characters back to the console.", + "terminal_cfg_advanced_title": "Advanced: full config", + "terminal_cfg_advanced_desc": "For fields without dedicated commands (captive portal, OTA, LAN, etc.), replace the entire config.", + "terminal_cfg_json_config": "JSON config", + "terminal_cfg_invalid_json": "Must be valid JSON", + "terminal_cfg_read_json": "Read current config as JSON", + "terminal_cfg_json_restart": "Applying a JSON config will restart the device.", + "terminal_cfg_raw_config": "Raw FlatBuffer config (base64)", + "terminal_cfg_invalid_base64": "Must be a valid base64 string", + "terminal_cfg_read_raw": "Read current config as base64", + "terminal_cfg_factory_reset": "Factory reset", + "terminal_cfg_factory_reset_desc": "Wipes the entire device configuration.", + "terminal_cfg_factory_reset_title": "Factory reset device?", + "terminal_cfg_factory_reset_action": "Wipe config", + "terminal_cfg_factory_reset_confirm": "This will erase all configuration on the device; WiFi networks, backend credentials, pins, and all other settings. The device will be reset to defaults.", + "terminal_cfg_read_failed_json_title": "Couldn't read the JSON config", + "terminal_cfg_read_failed_raw_title": "Couldn't read the raw config", + "terminal_cfg_read_failed_desc": "The device didn't respond after {{attempts}} attempts.", + "terminal_cfg_common_causes": "Common causes:", + "terminal_cfg_cause_busy": "The device is busy handling another command.", + "terminal_cfg_cause_disconnected": "The device disconnected or rebooted.", + "terminal_cfg_cause_unsupported": "The firmware version doesn't support this command.", + "common_status": "Status", + "common_version": "Version", + "common_created": "Created", + "common_create": "Create", + "common_done": "Done", + "common_enable": "Enable", + "common_disable": "Disable", + "common_are_you_sure": "Are you sure?", + "common_generating": "Generating...", + "hubs_title": "Hubs", + "hubs_subtitle": "Every hub registered to your account.", + "hubs_add": "Add Hub", + "hubs_load_failed": "Failed to load hubs.", + "hubs_empty_title": "No hubs yet", + "hubs_empty_desc": "A hub is the device that relays commands to your shockers. Add one to get started.", + "hubs_create_title": "Create hub", + "hubs_name_label": "Hub Name", + "hubs_name_placeholder": "My Hub", + "hub_toast_not_connected": "Not connected to the server", + "hub_toast_try_later": "Try again in a moment.", + "hub_reboot_title": "Reboot {{name}}?", + "hub_reboot_desc": "The hub will disconnect and restart. Any shockers paired to it stop responding until it comes back online.", + "hub_reboot": "Reboot", + "hub_hotspot_enable_title": "Enable Wi-Fi hotspot on {{name}}?", + "hub_hotspot_disable_title": "Disable Wi-Fi hotspot on {{name}}?", + "hub_hotspot_enable_desc": "The hub broadcasts its own setup network. It stays reachable on your Wi-Fi, but the hotspot is open to anyone in range until you turn it off.", + "hub_hotspot_disable_desc": "The setup hotspot shuts down. If the hub is not already on your Wi-Fi you will need physical access to set it up again.", + "hub_delete_desc": "You are about to delete hub {{name}}.", + "hub_delete_shockers": "This will also delete the following shockers:", + "hub_edit_title": "Edit hub", + "hub_edit_apply": "Apply", + "hub_pair_title_generate": "Generate pair code?", + "hub_pair_title_generated": "Pair code generated", + "hub_pair_title_paired": "Hub paired", + "hub_pair_consumed": "{{name}} consumed this pair code and is now paired.", + "hub_pair_used": "The code has been used and is no longer valid.", + "hub_pair_generated_for": "Pair code generated for {{name}}.", + "hub_copy_now": "The code below will not be accessible later, please copy it now and update clients with it.", + "hub_pair_generate_for": "You are about to generate a pair code for {{name}}.", + "hub_pair_valid_for": "It will be valid for 15 minutes after its creation.", + "hub_pair_one_active": "There is only one active pair code per hub, newly generated ones will override the older active ones.", + "hub_pair_complete": "Pairing complete", + "hub_pair_code_label": "Pair code:", + "hub_pair_copied_close": "Code has been copied, close", + "hub_pair_get": "Get Pair Code", + "hub_token_generated": "Token generated", + "hub_token_generated_for": "New token generated for {{name}}.", + "hub_token_regenerate_for": "You are about to regenerate the token for {{name}}.", + "hub_token_invalidate": "This action will invalidate the current token and disconnect clients using it.", + "hub_token_confirm": "Are you sure you want to do this?", + "hub_token_label": "New token:", + "hub_token_copied_close": "Token has been copied, close", + "hub_token_regenerate": "Regenerate Token", + "hub_menu_update": "Update", + "hub_menu_label": "Hub", + "hub_menu_hotspot_enable": "Enable Wi-Fi hotspot", + "hub_menu_hotspot_disable": "Disable Wi-Fi hotspot", + "hub_menu_pair": "Pair", + "hub_menu_estop": "Emergency Stop", + "hub_update_breadcrumb": "Update", + "hub_update_unknown_hub": "Unknown Hub", + "hub_update_unknown_task": "Unknown Task", + "hub_update_task_metadata": "Fetching Metadata", + "hub_update_task_preparing": "Preparing for Update", + "hub_update_task_flash_fs": "Flashing Filesystem", + "hub_update_task_verify_fs": "Verifying Filesystem", + "hub_update_task_flash_app": "Flashing Application", + "hub_update_task_bootable": "Marking Application Bootable", + "hub_update_task_rebooting": "Rebooting", + "hub_update_status_started": "Started", + "hub_update_status_running": "Running", + "hub_update_status_finished": "Finished", + "hub_update_status_error": "Error", + "hub_update_status_timeout": "Timeout", + "hub_update_confirm_title": "Confirm firmware update", + "hub_update_confirm_desc": "Update {{name}} to version {{version}}?", + "hub_update_unstable_warning": "This version may not be from the stable channel and could contain bugs.", + "hub_update_title": "Update {{name}}", + "hub_update_subtitle": "Manage firmware updates for this hub.", + "hub_update_status_title": "Hub Status", + "hub_update_firmware": "Firmware: {{version}}", + "hub_update_confirm": "Update", + "hub_update_success": "Update completed successfully", + "hub_update_rolled_back": "Device rolled back to previous version", + "hub_update_back": "Back to Hubs", + "hub_update_flash_again": "Flash Again", + "hub_update_card_title": "Firmware Update", + "hub_update_card_desc": "Select a firmware channel and version to install.", + "hub_update_to": "Update to {{version}}", + "hub_update_must_be_online": "Hub must be online to start an update.", + "hub_update_updating_to": "Updating to {{version}}...", + "hub_update_total": "Total", + "hub_update_task": "Task", + "hub_update_history": "Update History", + "hub_update_no_history": "No update history found for this hub.", + "hub_update_col_id": "ID", + "hub_update_col_started": "Started", + "hub_update_col_message": "Message", + "hub_update_loading": "Loading hub information...", + "hub_update_not_found": "Hub not found.", + "home_breadcrumb": "Home", + "home_welcome": "Welcome back", + "home_welcome_name": "Welcome back, {{name}}", + "home_subtitle": "Here's an overview of your OpenShock setup.", + "home_hubs_online": "{{count}} online", + "home_hub_status": "Hub Status", + "home_no_hubs": "No hubs", + "home_all_online": "All online", + "home_all_offline": "All offline", + "home_some_online": "{{online}}/{{total}} online", + "home_quick_links": "Quick Links", + "home_my_shockers": "My Shockers", + "home_my_shockers_desc": "Control your shockers", + "home_hubs_desc": "Manage your hubs", + "home_shared_desc": "Shockers shared with you", + "home_public_desc": "Manage share links", + "home_get_started": "Get Started", + "home_get_started_desc": "You don't have any hubs yet. Create a hub to connect your first device, then add shockers to it.", + "home_set_up_hub": "Set Up a Hub", + "home_first_shocker": "Add Your First Shocker", + "home_first_shocker_desc_one": "You have {{count}} hub set up. Add a shocker to start controlling it.", + "home_first_shocker_desc_other": "You have {{count}} hubs set up. Add a shocker to start controlling it.", + "home_go_to_shockers": "Go to Shockers", + "profile_title": "Profile", + "profile_coming_soon": "Profile is coming soon", + "profile_coming_soon_desc": "Your public profile is not available yet. Account details live under Settings.", + "common_retry": "Retry", + "common_never_used": "Never used", + "common_expires": "Expires {{time}}", + "common_search_placeholder": "Search...", + "common_unknown": "Unknown", + "settings_breadcrumb_account": "Account", + "account_subtitle": "Your sign-in details and account actions.", + "account_change_username": "Change Username", + "account_change_email": "Change Email", + "account_change_password": "Change Password", + "account_username_label": "Username", + "account_email_label": "Email", + "account_password_label": "Password", + "account_new_password_label": "New Password", + "account_confirm_password_label": "Confirm New Password", + "account_oauth_only": "Not available for OAuth-only accounts", + "account_oauth_no_password": "This account signs in via OAuth and has no password.", + "account_diagnostics": "Diagnostics", + "account_diagnostics_desc": "Help us fix crashes and slow API calls. Reports include the error message, stack trace and your IP. Off by default.", + "account_diagnostics_level": "Diagnostics level", + "account_telemetry_off": "Off", + "account_telemetry_off_desc": "Send nothing.", + "account_telemetry_errors": "Errors", + "account_telemetry_errors_desc": "Send browser error reports only.", + "account_telemetry_full": "Full", + "account_telemetry_full_desc": "Error reports plus traces of API calls (no page navigations).", + "account_toast_deactivated": "Account deactivated successfully", + "account_deactivate_title": "Deactivate account", + "account_deactivate_desc": "Are you sure you want to deactivate your account?", + "account_deactivate": "Deactivate Account", + "account_email_title": "Change email", + "account_email_desc": "Enter your new email address and confirm with your current password.", + "account_email_toast_sent": "Verification email sent to {{email}}. Click the link in that email to apply the change.", + "account_new_email": "New Email", + "account_current_password": "Current Password", + "account_password_title": "Change password", + "account_password_desc": "Enter your current password and choose a new one.", + "account_password_toast": "Password has been changed", + "account_username_title": "Change username", + "account_username_desc": "Enter a new username.", + "account_new_username": "New Username", + "account_username_toast": "Username changed successfully", + "tokens_subtitle": "API Tokens are used to authenticate with the OpenShock API.", + "tokens_generate": "Generate Token", + "tokens_toast_refreshed": "Tokens refreshed successfully", + "tokens_empty_title": "No API tokens", + "tokens_empty_desc": "Generate a token to authenticate with the OpenShock API.", + "tokens_created_on": "Created {{date}}", + "tokens_last_used": "Last used {{time}}", + "tokens_never_expires": "Never expires", + "tokens_load_failed": "Failed to load API tokens.", + "token_toast_edited": "Token edited successfully", + "token_name_required": "Name is required", + "token_name_too_long": "Name is too long", + "token_edit_title": "Edit API token", + "token_name_label": "Token Name", + "token_name_placeholder": "Token name...", + "token_permissions": "Permissions", + "token_perm_category_shockers": "Shockers", + "token_perm_category_devices": "Hubs", + "token_perm_category_usershares": "User Shares", + "token_perm_category_publicshares": "Public Shares", + "token_perm_use": "Use", + "token_perm_edit": "Edit", + "token_perm_pause": "Pause", + "token_perm_auth": "Authenticate", + "token_shocker_control": "Shocker Control", + "token_toast_paused": "Token paused", + "token_toast_resumed": "Token resumed", + "token_delete_title": "Delete API token", + "token_delete_desc": "Are you sure you want to delete {{name}}?", + "token_delete_permanent": "This action cannot be undone. This will permanently delete the token.", + "token_toast_deleted": "Token deleted successfully", + "token_resume": "Resume token", + "token_pause": "Pause token", + "token_mode_clamp_desc": "Clamp: requests outside the allowed range are capped to the nearest limit (the min or the max).", + "token_mode_lerp_desc": "Lerp: the full input range is linearly rescaled so it fits within your allowed min–max range.", + "token_paused_desc": "A paused token may not send shocker control messages.", + "token_intensity_range": "Intensity range", + "token_duration_range": "Duration range", + "token_new_breadcrumb": "New", + "token_redirect_not_allowed": "The provided redirect_uri is not allowed. Only loopback addresses or custom application schemes are permitted.", + "token_params_missing": "Required get parameters are missing. Make sure name, redirect_uri, and permissions are provided.", + "token_invalid_permissions": "Invalid permissions provided: {{list}}", + "token_toast_created": "Token created successfully", + "token_request_title": "API Token Request", + "token_access_granted": "Access granted", + "token_shared_redirecting": "The token has been created and shared with the application. Redirecting you back to {{uri}}.", + "token_not_redirected": "If you are not redirected automatically, use the button below.", + "token_finish": "Finish", + "token_generated_title": "API Token Generated", + "token_copy_now": "Please copy your API Token now, you will not be able to view it again later!", + "token_new_title": "New API Token", + "token_external_desc": "An external application is requesting access to your account. Review and adjust the permissions below before allowing access.", + "token_new_desc": "Configure and generate a new API token for your account.", + "token_external_requesting": "{{name}} is requesting an API Token. Your token will be shared with the application at {{uri}}.", + "token_allow": "Allow", + "token_generate": "Generate", + "token_deny": "Deny", + "sessions_subtitle": "Every active session on your account. Revoke any you do not recognize.", + "sessions_unknown_device": "Unknown device", + "sessions_toast_refreshed": "Sessions refreshed successfully", + "sessions_load_failed": "Failed to load sessions.", + "sessions_empty_title": "No active sessions", + "sessions_empty_desc": "Sessions appear here once you sign in from a browser or app.", + "sessions_last_seen": "Last seen {{time}}", + "sessions_signed_in": "Signed in {{time}}", + "session_toast_revoked": "Session revoked successfully", + "session_revoke_title": "Revoke session", + "session_revoke": "Revoke", + "session_revoke_desc": "Are you sure you want to revoke this session?", + "session_revoke_from": "Session logged in from {{ip}} using {{agent}}", + "connections_title": "OAuth Connections", + "connections_subtitle": "Link or unlink third-party accounts to sign in faster and keep your profile in sync.", + "connections_toast_linked": "Account linked.", + "connections_toast_cancelled": "Link flow cancelled.", + "connections_toast_failed": "Linking failed.", + "connections_toast_removed": "Connection removed", + "connections_refreshing": "Refreshing…", + "connections_link_new": "Link new provider", + "connections_empty_title": "No connections yet", + "connections_empty_desc": "Choose “Link new provider” above to connect available providers.", + "connections_unlink": "Unlink", + "connections_load_failed": "Failed to load OAuth connections.", + "connections_unlink_title": "Unlink {{name}}?", + "connections_unlink_title_generic": "Unlink this account?", + "connections_unlink_desc": "You'll no longer be able to sign in with this provider unless you link it again.", + "provider_starting": "Starting {{name}}...", + "provider_link": "Link {{name}}", + "audit_subtitle": "Security-relevant activity on your account. Review anything you do not recognize.", + "audit_col_time": "Time", + "audit_col_action": "Action", + "audit_col_details": "Details", + "audit_col_reason": "Reason", + "audit_col_ip": "IP address", + "audit_col_device": "Device", + "audit_action_login": "Signed in", + "audit_action_logout": "Signed out", + "audit_action_password_changed": "Password changed", + "audit_action_email_change_requested": "Email change requested", + "audit_action_email_changed": "Email changed", + "audit_action_username_changed": "Username changed", + "audit_action_api_token_created": "API token created", + "audit_action_api_token_deleted": "API token deleted", + "audit_action_oauth_connected": "Connection added", + "audit_action_oauth_disconnected": "Connection removed", + "audit_action_account_deactivated": "Account deactivated", + "audit_action_account_reactivated": "Account reactivated", + "audit_action_account_deleted": "Account deleted", + "audit_action_automation_token_created": "Automation token created", + "audit_action_automation_token_updated": "Automation token updated", + "audit_action_automation_token_rotated": "Automation token rotated", + "audit_action_automation_token_deleted": "Automation token deleted", + "audit_action_automation_token_used": "Automation token used", + "audit_meta_session": "Session {{id}}", + "audit_meta_changed": "{{old}} to {{new}}", + "audit_meta_email_requested": "Requested change to {{email}}", + "audit_meta_accounts_removed_one": "{{name}} ({{count}} account removed)", + "audit_meta_accounts_removed_other": "{{name}} ({{count}} accounts removed)", + "audit_meta_scheduled_deletion": "Scheduled for deletion", + "audit_meta_kept": "Kept for reactivation", + "common_view": "View", + "common_save": "Save", + "common_saving": "Saving...", + "common_back": "Back", + "common_shared_by": "Shared by", + "common_user_avatar": "User Avatar", + "common_toast_saved": "Changes saved successfully", + "pause_reason_shocker": "Paused at shocker level", + "pause_reason_shocker_user_share": "Paused at shocker and user share level", + "pause_reason_shocker_public_share": "Paused at shocker and public share level", + "pause_reason_user_share": "Paused at user share level", + "pause_reason_public_share": "Paused at public share level", + "public_shares_subtitle": "A link anyone can use, no account required.", + "public_shares_new": "New Share", + "public_share_never_expires": "Never expires", + "public_shares_empty_title": "No public shares yet", + "public_shares_empty_desc": "Create a link that anyone can use to control your shockers.", + "public_share_expired": "Expired", + "public_share_no_expiry": "No expiry", + "public_share_label": "Public Share", + "public_share_toast_created": "Created new public share", + "public_share_create_title": "Create public share", + "public_share_toast_deleted": "Deleted public share", + "public_share_delete_title": "Delete public share", + "public_share_delete_desc": "Are you sure you want to delete public share {{name}}?", + "public_share_edit_title": "Public Share: {{name}}", + "public_share_edit_subtitle": "Editing: changes apply when you save.", + "public_share_add_shocker": "Add Shocker", + "public_share_toast_added_one": "Added {{count}} shocker to share", + "public_share_toast_added_other": "Added {{count}} shockers to share", + "public_share_empty_shockers_title": "No shockers in this share", + "public_share_empty_shockers_desc": "Add a shocker and anyone with the link will be able to control it.", + "public_share_load_failed": "Error fetching public share details", + "public_share_paused_here": "Paused for this share", + "public_share_resume_shocker": "Resume shocker", + "public_share_pause_shocker": "Pause shocker", + "public_share_remove": "Remove from share", + "public_share_toast_removed": "Shocker removed from share", + "public_share_add_title": "Add shockers", + "public_share_add_desc": "Add shockers to this public share. You can set their limits once they are added.", + "public_share_add_placeholder": "Select shockers to share...", + "public_share_add_no_match": "No matching shockers", + "public_share_add_submit": "Add Shockers", + "public_share_view_loading": "Loading share details...", + "public_share_view_title": "Public Share Link", + "public_share_view_desc": "Enter as a guest or login with your OpenShock account", + "public_share_view_guest_name": "Guest Name", + "public_share_view_enter": "Enter", + "public_share_view_enter_guest": "Enter as Guest", + "public_share_login": "Login", + "perm_shock_on": "Shock enabled", + "perm_shock_off": "Shock disabled", + "perm_vibrate_on": "Vibrate enabled", + "perm_vibrate_off": "Vibrate disabled", + "perm_sound_on": "Sound enabled", + "perm_sound_off": "Sound disabled", + "perm_live_on": "Live enabled", + "perm_live_off": "Live disabled", + "perm_live_control": "Live Control", + "user_selector_avatar_of": "{{name}}'s avatar", + "user_selector_placeholder": "Enter user name", + "user_selector_aria": "Username to search", + "user_selector_search": "Search user", + "user_selector_found": "User found", + "common_remove": "Remove", + "user_shares_subtitle": "Direct permanent shares with other users.", + "user_shares_toast_invited": "Sent a shocker invite to {{name}}", + "user_shares_redeem": "Redeem Code", + "user_shares_new": "New Share", + "user_shares_tab_shares": "Shares", + "user_shares_tab_incoming": "Shared with Me", + "user_shares_tab_invites": "Invites", + "share_code_create_title": "New share code", + "share_code_create_desc": "Create a Share Code or Invite", + "share_code_shocker_placeholder": "Select shockers to share...", + "share_code_no_match": "No matching shockers", + "share_code_send_invite": "Send Share Invite", + "share_code_create": "Create Share Code", + "share_code_created_title": "Share code generated", + "share_code_created_desc": "Please copy share code or code link!", + "share_code_redeem_title": "Redeem share code", + "share_code_redeem_desc": "Enter the share code to redeem", + "share_code_redeem_placeholder": "Enter share code", + "share_code_redeemed": "Redeemed successfully!", + "share_code_shared_shockers": "Shared shockers", + "share_code_redeeming": "Redeeming...", + "share_code_redeem": "Redeem", + "incoming_shares_empty_title": "Nothing shared with you", + "incoming_shares_empty_desc": "No one has shared a shocker with you yet.", + "incoming_share_toast_removed": "Removed share for {{name}}", + "incoming_share_remove_title": "Remove Share", + "incoming_share_remove_desc": "Are you sure you want to remove the share for {{name}}?", + "incoming_share_toast_removed_shocker": "Removed {{shocker}} shared by {{name}}", + "incoming_share_remove_shocker_title": "Remove this shared shocker?", + "incoming_share_remove_shocker_desc": "Are you sure you want to remove the shocker share {{shocker}} by {{name}}?", + "incoming_share_manage_from": "Manage shares from", + "share_remove": "Remove share", + "invites_empty_title": "No invites yet", + "invites_empty_desc": "You have no incoming or outgoing share invites.", + "invites_outgoing": "Outgoing", + "invites_outgoing_empty_title": "No outgoing invites", + "invites_outgoing_empty_desc": "You have no outgoing share invites.", + "invites_incoming": "Incoming", + "invites_incoming_empty_title": "No incoming invites", + "invites_incoming_empty_desc": "You have no incoming share invites.", + "invite_toast_accepted": "Accepted share invite from {{name}}", + "invite_toast_declined": "Declined share invite from {{name}}", + "invite_deny_title": "Deny Invite", + "invite_deny_label": "Deny Invite", + "invite_deny": "Deny", + "invite_deny_desc": "Are you sure you want to deny the invite from {{name}}?", + "invite_accept": "Accept Invite", + "invite_toast_cancelled_for": "Cancelled invite for {{name}} ({{id}})", + "invite_toast_cancelled": "Cancelled invite {{id}}", + "invite_cancel_title": "Cancel Invite", + "invite_cancel": "Cancel", + "invite_cancel_for_desc": "Are you sure you want to cancel the invite for {{name}}?", + "invite_cancel_code_desc": "Are you sure you want to cancel the invite with code {{code}}?", + "invite_cancel_outstanding": "Cancel Outstanding Invite", + "outgoing_shares_empty_title": "No shared shockers", + "outgoing_shares_empty_desc": "You haven't shared any shockers with other users yet.", + "outgoing_share_toast_removed": "Removed shocker share {{name}}", + "outgoing_share_remove_title": "Stop sharing this shocker?", + "outgoing_share_editing_for": "Editing shares for", + "outgoing_share_limits": "Limits & Permissions", + "outgoing_share_same": "Same restrictions on every shocker", + "outgoing_share_per_desc": "Tune restrictions per shocker", + "outgoing_share_all": "All", + "outgoing_share_per": "Per shocker", + "outgoing_share_remove_desc": "Are you sure you want to stop sharing {{shocker}} with {{name}}?", + "report_breadcrumb": "Report API Tokens", + "report_toast_clipboard_failed": "Failed to read clipboard: {{error}}", + "report_title": "Report Leaked API Tokens", + "report_paste": "Paste from clipboard", + "report_warning": "This form is only for reporting accidentally leaked API tokens.", + "report_abuse_warning": "Intentional abuse will result in bans or severe endpoint restrictions.", + "report_detected": "Detected Tokens", + "report_invalid": "One or more tokens appear to be invalid. Please check for formatting issues.", + "report_acknowledge": "I confirm I understand what this feature is for and accept responsibility.", + "report_submit": "Submit Report", + "turnstile_disabled": "Turnstile disabled", + "common_internal_error": "Internal error", + "resend_toast_sent": "Activation email sent. Check your inbox and spam folder.", + "resend_toast_throttled": "Too many activation emails have been requested. Please try again later.", + "resend_toast_unavailable": "No activation email can be resent from this browser. If your account isn't activated yet, logging in sends a new link.", + "resend_button": "Didn't get the email? Resend", + "expiration_label": "Expiration", + "expiration_never": "Never", + "expiration_custom": "Custom", + "expiration_days_one": "{{count}} Day", + "expiration_days_other": "{{count}} Days", + "expiration_required": "Expire date is required", + "expiration_never_desc": "This will never expire", + "expiration_expires_at": "Expires {{time}} ({{date}})", + "date_picker_placeholder": "Pick a date", + "telemetry_toast_title": "Help improve OpenShock?", + "telemetry_toast_desc": "Send diagnostics to help us fix crashes and slow API calls. Reports include the error message, stack trace and your IP. You can change this any time in Account settings.", + "telemetry_toast_no": "No thanks", + "telemetry_toast_errors": "Errors only", + "telemetry_toast_full": "Full", + "table_show_details": "Show details", + "table_hide_details": "Hide details", + "table_no_results": "No results.", + "table_sort_asc": "Sort by {{name}}, ascending", + "table_sort_desc": "Sort by {{name}}, descending", + "table_sort_none": "Sort by {{name}}, unsorted", + "cell_na": "N/A", + "cell_not_applicable": "Not applicable", + "cell_invalid": "Invalid", + "cell_unavailable": "Unavailable", + "cell_none": "None", + "oauth_login_with": "Login with {{provider}}", + "oauth_signup_with": "Signup with {{provider}}", + "signalr_connect_failed": "Failed to connect to server!", + "signalr_disconnect_failed": "Encountered error while disconnecting from server!", + "signalr_invalid_update": "Received invalid update from server!", + "signalr_invalid_log": "Received invalid log data from server!", + "signalr_invalid_ota": "Received invalid firmware update data from server!", + "ota_toast_failed": "Hub firmware update failed: {{message}}", + "ota_toast_succeeded": "Hub firmware update completed successfully!", + "ota_toast_rolled_back": "Hub firmware rolled back to previous version", + "lcg_connect_failed": "Failed to connect to live control gateway", + "terminal_toast_bootloader_failed": "Failed to enter bootloader: {{error}}", + "terminal_toast_app_mode_failed": "Failed to enter application mode: {{error}}", + "problem_account_account_not_activated_title": "Account not activated", + "problem_account_account_not_activated_desc": "Check your inbox for the activation email.", + "problem_account_activation_not_found_title": "Activation link is invalid", + "problem_account_activation_not_found_desc": "The link may have expired or already been used.", + "problem_account_activation_resend_too_many_title": "Too many activation emails requested", + "problem_account_activation_resend_too_many_desc": "Please wait a while before trying again.", + "problem_account_activation_resend_unavailable_title": "Cannot resend activation email", + "problem_account_activation_resend_unavailable_desc": "Log in again to request a new activation link.", + "problem_account_deactivate_already_deactivated_title": "Account is already deactivated", + "problem_account_deactivate_denied_privileged_title": "Privileged accounts cannot be deactivated", + "problem_account_deactivate_unauthorized_title": "You are not allowed to do this", + "problem_account_deactivated_title": "This account has been deactivated", + "problem_account_email_already_in_use_title": "That email address is already in use", + "problem_account_email_invalid_title": "That email address is not valid", + "problem_account_email_taken_title": "That email address is already in use", + "problem_account_email_too_many_requests_title": "Too many email change requests", + "problem_account_email_too_many_requests_desc": "Please wait a while before trying again.", + "problem_account_email_unchanged_title": "That is already your email address", + "problem_account_email_verify_not_found_title": "Verification link is invalid", + "problem_account_email_verify_not_found_desc": "The link may have expired or already been used.", + "problem_account_o_auth_only_title": "This account has no password", + "problem_account_o_auth_only_desc": "Sign in with the provider you signed up with.", + "problem_account_password_not_set_title": "No password set", + "problem_account_password_not_set_desc": "This account signs in through an external provider.", + "problem_account_password_old_password_invalid_title": "Current password is incorrect", + "problem_account_username_invalid_title": "That username is not allowed", + "problem_account_username_recently_changed_title": "Username changed too recently", + "problem_account_username_recently_changed_desc": "You can change your username once every 7 days.", + "problem_account_username_taken_title": "That username is already taken", + "problem_admin_user_deactivated_title": "This user is deactivated", + "problem_admin_user_not_activated_title": "This user has not been activated yet", + "problem_api_token_can_only_delete_self_title": "An API token can only delete itself", + "problem_api_token_not_found_title": "API token not found", + "problem_api_token_paused_title": "This API token is paused", + "problem_assign_lcg_bad_schema_version_title": "Unsupported hub protocol version", + "problem_assign_lcg_bad_schema_version_desc": "Update the hub firmware to connect.", + "problem_assign_lcg_no_lcg_available_title": "No gateway available", + "problem_assign_lcg_no_lcg_available_desc": "No live control gateway is available right now. Please try again later.", + "problem_authentication_account_deactivated_title": "This account has been deactivated", + "problem_authentication_account_not_activated_title": "This account has not been activated", + "problem_authentication_cookie_missing_or_invalid_title": "You are not logged in", + "problem_authentication_cookie_missing_or_invalid_desc": "Your session may have expired. Please log in again.", + "problem_authentication_header_missing_or_invalid_title": "Invalid API token", + "problem_authentication_session_invalid_title": "Session expired", + "problem_authentication_session_invalid_desc": "Please log in again.", + "problem_authentication_token_invalid_title": "Invalid API token", + "problem_authentication_unknown_error_title": "Authentication failed", + "problem_authorization_policy_not_met_title": "You do not have permission to do this", + "problem_authorization_token_only_title": "This action requires an API token", + "problem_authorization_token_permission_missing_title": "This API token is missing a required permission", + "problem_authorization_unknown_error_title": "Authorization failed", + "problem_authorization_user_session_only_title": "This action requires a logged-in session", + "problem_automation_token_not_allowed_for_account_title": "Automation tokens cannot be used with privileged accounts", + "problem_configuration_already_exists_title": "A configuration entry with that name already exists", + "problem_configuration_invalid_name_format_title": "Invalid configuration name", + "problem_configuration_invalid_name_format_desc": "Only A to Z and underscores are allowed.", + "problem_configuration_invalid_value_format_title": "Value does not match the configuration type", + "problem_configuration_not_found_title": "Configuration entry not found", + "problem_control_stats_invalid_range_title": "The from date must not be after the to date", + "problem_control_stats_invalid_time_zone_title": "Unknown time zone", + "problem_control_stats_missing_capability_title": "Control statistics are not available on this server", + "problem_device_not_found_title": "Hub not found", + "problem_device_not_online_title": "Hub is offline", + "problem_device_too_many_hubs_title": "You have reached the maximum number of hubs", + "problem_device_too_many_shockers_title": "This hub has reached its maximum number of shockers", + "problem_endpoint_retired_title": "This feature is no longer available", + "problem_expression_error_title": "Invalid filter expression", + "problem_internal_server_error_title": "Something went wrong on our end", + "problem_login_invalid_credentials_title": "Invalid username or password", + "problem_login_invalid_domain_title": "Logging in from this address is not allowed", + "problem_o_auth_connection_already_exists_title": "Your account is already connected to this provider", + "problem_o_auth_connection_already_linked_title": "This external account is already linked to another user", + "problem_o_auth_flow_anonymous_only_title": "You are already signed in", + "problem_o_auth_flow_mismatch_title": "Sign-in attempt does not match", + "problem_o_auth_flow_mismatch_desc": "Please start over.", + "problem_o_auth_flow_missing_data_title": "The provider did not return your account details", + "problem_o_auth_flow_missing_data_desc": "Please try again.", + "problem_o_auth_flow_not_found_title": "Sign-in attempt expired", + "problem_o_auth_flow_not_found_desc": "Please start over.", + "problem_o_auth_flow_unsupported_title": "Unsupported sign-in flow", + "problem_o_auth_internal_error_title": "Something went wrong during sign-in", + "problem_o_auth_internal_error_desc": "Please try again in a moment.", + "problem_o_auth_link_authenticated_user_only_title": "You must be signed in to link an external account", + "problem_o_auth_provider_mismatch_title": "Sign-in attempt does not match the provider", + "problem_o_auth_provider_mismatch_desc": "Please start over.", + "problem_o_auth_provider_unsupported_title": "This sign-in provider is not supported", + "problem_pair_code_not_found_title": "Pair code not found", + "problem_password_reset_not_found_title": "Password reset link is invalid", + "problem_password_reset_not_found_desc": "The link may have expired or already been used.", + "problem_session_not_found_title": "Session not found", + "problem_share_get_no_shares_title": "You have no shares with this user", + "problem_share_request_create_cannot_share_with_self_title": "You cannot share with yourself", + "problem_share_request_create_shocker_not_found_title": "One or more shockers were not found", + "problem_share_request_create_shocker_not_found_desc": "They may have been removed or do not belong to you.", + "problem_share_request_not_found_title": "Share invite not found", + "problem_share_user_not_found_title": "Share not found", + "problem_share_code_already_linked_title": "Shocker is already linked to your account", + "problem_share_code_cant_link_own_share_code_title": "You cannot redeem your own share code", + "problem_share_code_not_found_title": "Share code not found", + "problem_share_link_expiry_date_in_past_title": "Expiry date cannot be in the past", + "problem_share_link_not_found_title": "Public share not found", + "problem_share_link_shocker_already_in_share_link_title": "Shocker is already in this public share", + "problem_share_link_shocker_not_in_share_link_title": "Shocker is not in this public share", + "problem_shocker_control_no_permission_title": "You do not have permission to control this shocker", + "problem_shocker_control_not_found_title": "Shocker not found", + "problem_shocker_control_paused_title": "Shocker is paused", + "problem_shocker_not_found_title": "Shocker not found", + "problem_signup_registration_disabled_title": "Registration is currently disabled", + "problem_signup_username_or_email_exists_title": "That username or email is already in use", + "problem_turnstile_invalid_title": "Verification failed", + "problem_turnstile_invalid_desc": "Please complete the challenge again and retry.", + "problem_user_not_found_title": "User not found", + "problem_user_privileged_delete_denied_title": "Privileged users cannot be deleted", + "problem_validation_error_title": "Some fields are invalid", + "problem_webhook_not_found_title": "Webhook not found", + "problem_webhook_unsupported_title": "Only Discord webhooks are supported", + "problem_webhook_unsupported_desc": "Use a discord.com URL, not canary or ptb.", + "error_too_many_requests": "Too many requests", + "error_retry_after_one": "Try again in {{count}} second.", + "error_retry_after_other": "Try again in {{count}} seconds.", + "error_unexpected_response": "Unexpected server response", + "error_internal": "Internal error occurred", + "error_network": "Network error occurred", + "dev_banner": "This is the OpenShock DEVELOPMENT environment. No data is saved, and it is regularly overwritten by production data.", + "firmware_channel_bugs_warning": "This channel might contain bugs." +} From 3d2c6e643327edaac8f9ce6ce176e1a77107bb69 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Luc=20=E2=99=A5?= Date: Thu, 12 Nov 2026 17:43:24 +0100 Subject: [PATCH 17/27] New translations en.json (Dutch) [ci skip] --- messages/nl.json | 308 ++++++++++++++++++----------------------------- 1 file changed, 117 insertions(+), 191 deletions(-) diff --git a/messages/nl.json b/messages/nl.json index 1e62d7db..ebf2a7e6 100644 --- a/messages/nl.json +++ b/messages/nl.json @@ -1,15 +1,13 @@ { - "$schema": "https://inlang.com/schema/inlang-message-format", - "landing_tagline": "Het platform voor veilige, betrouwbare afstandsbediening van shockers met echt weinig vertraging.", "landing_section_label": "Start", "landing_hubs_online": "Hubs nu online: ", "landing_learn_more": "Meer informatie", "landing_wiki": "Wiki", "landing_meta_description": "Welkom bij OpenShock, een gratis open-source-ecosysteem om verschillende shockers via internet te bedienen.", - "instance_meta_description": "Welkom bij {siteName}, een onafhankelijke instantie van OpenShock, een gratis open-source-ecosysteem om verschillende shockers via internet te bedienen.", + "instance_meta_description": "Welkom bij {{siteName}}, een onafhankelijke instantie van OpenShock, een gratis open-source-ecosysteem om verschillende shockers via internet te bedienen.", "header_sidebar_toggle": "Zijbalk tonen/verbergen", - "header_avatar_alt": "Avatar van {name}", + "header_avatar_alt": "Avatar van {{name}}", "header_menu_profile": "Profiel", "header_menu_settings": "Instellingen", "header_menu_logout": "Uitloggen", @@ -17,16 +15,14 @@ "header_signup": "Registreren", "header_github_title": "OpenShock op GitHub", "header_discord_title": "Community-Discord", - - "footer_made_with": "Gemaakt met {#heart/} door het {#team}OpenShock-team{/team}", + "footer_made_with": "Gemaakt met door het OpenShock-team", "footer_connection_status_label": "Status serververbinding", "footer_signalr_state": "SignalR-status", "footer_frontend_version": "Frontendversie", - "footer_frontend_commit_title": "Commit {commit}", + "footer_frontend_commit_title": "Commit {{commit}}", "footer_backend_version": "Backendversie", - "footer_backend_commit_title": "Commit {commit}", + "footer_backend_commit_title": "Commit {{commit}}", "footer_language_label": "Taal", - "sidebar_home_link_label": "OpenShock-startpagina", "sidebar_group_general": "Algemeen", "sidebar_home": "Start", @@ -53,7 +49,6 @@ "sidebar_settings_audit_log": "Activiteitenlog", "sidebar_settings_connections": "Koppelingen", "sidebar_settings_account": "Accountinstellingen", - "error_meta_title": "Dienst niet beschikbaar", "error_meta_description": "OpenShock is momenteel niet beschikbaar", "error_meta_logo_alt": "OpenShock-logo", @@ -62,10 +57,8 @@ "error_not_found_description": "De pagina die je zoekt bestaat niet.", "error_unexpected_description": "Er is een onverwachte fout opgetreden.", "error_go_back": "Terug", - "auth_layout_logo_alt": "OpenShock-logo", "auth_layout_invalid_redirect_removed": "Een ongeldige doorverwijzings-URL is voor je veiligheid verwijderd.", - "auth_activate_breadcrumb": "Account activeren", "auth_activate_title": "Account activeren", "auth_activate_activating": "Je account wordt geactiveerd...", @@ -74,17 +67,15 @@ "auth_activate_missing_token": "Activatietoken ontbreekt", "auth_activate_continue": "Door naar inloggen", "auth_activate_toast_success": "Account geactiveerd", - "auth_forgot_breadcrumb": "Wachtwoord vergeten", "auth_forgot_title": "Wachtwoord vergeten", "auth_forgot_description": "Voer je e-mailadres in om je wachtwoord opnieuw in te stellen", "auth_forgot_email_label": "E-mail", "auth_forgot_email_placeholder": "E-mail", "auth_forgot_submit": "Wachtwoord resetten", - "auth_forgot_signin_prompt": "Weet je je wachtwoord weer? {#signin}Inloggen{/signin}", + "auth_forgot_signin_prompt": "Weet je je wachtwoord weer? Inloggen", "auth_forgot_mail_disabled": "Wachtwoorden resetten is niet mogelijk op deze instantie, omdat er geen e-mailprovider is ingesteld. Neem contact op met je beheerder om weer toegang tot je account te krijgen.", "auth_forgot_toast_sent": "Het verzoek om je wachtwoord te resetten is naar het opgegeven e-mailadres verzonden", - "auth_login_breadcrumb": "Inloggen", "auth_login_title": "Welkom terug", "auth_login_loading_methods": "Beschikbare inlogmethoden laden", @@ -98,23 +89,20 @@ "auth_login_username_label": "Gebruikersnaam of e-mail", "auth_login_password_label": "Wachtwoord", "auth_login_submit": "Inloggen", - "auth_login_signup_prompt": "Nog geen account? {#signup}Registreren{/signup}", - "auth_login_legal": "Door op Inloggen te klikken, ga je akkoord met onze {#tos}Servicevoorwaarden{/tos} en ons {#privacy}Privacybeleid{/privacy}.", - - "auth_oauth_create_breadcrumb": "Registreren met {provider}", - "auth_oauth_create_title": "Registreren met {#provider}{provider}{/provider}", + "auth_login_signup_prompt": "Nog geen account? Registreren", + "auth_login_legal": "Door op Inloggen te klikken, ga je akkoord met onze Servicevoorwaarden en ons Privacybeleid.", + "auth_oauth_create_breadcrumb": "Registreren met {{provider}}", + "auth_oauth_create_title": "Registreren met {{provider}}", "auth_oauth_create_description": "Vul je accountgegevens aan", "auth_oauth_create_username_label": "Gebruikersnaam", "auth_oauth_create_username_placeholder": "Gebruikersnaam", "auth_oauth_create_email_label": "E-mail", "auth_oauth_create_email_placeholder": "E-mail", "auth_oauth_create_submit": "Registreren", - "auth_oauth_create_legal": "Door op Registreren te klikken, ga je akkoord met onze {#tos}Servicevoorwaarden{/tos} en ons {#privacy}Privacybeleid{/privacy}.", - + "auth_oauth_create_legal": "Door op Registreren te klikken, ga je akkoord met onze Servicevoorwaarden en ons Privacybeleid.", "auth_oauth_error_breadcrumb": "Authenticatiefout", "auth_oauth_error_title": "Authenticatiefout", "auth_oauth_error_back": "Terug naar inloggen", - "auth_reset_breadcrumb": "Wachtwoord resetten", "auth_reset_title": "Wachtwoord resetten", "auth_reset_checking": "Resetlink controleren...", @@ -127,7 +115,6 @@ "auth_reset_submit": "Wachtwoord resetten", "auth_reset_request_new": "Nieuwe resetlink aanvragen", "auth_reset_toast_success": "Wachtwoord is gereset", - "auth_signup_breadcrumb": "Registreren", "auth_signup_toast_created_mail": "Account aangemaakt. Controleer je e-mail om je account te verifiëren.", "auth_signup_toast_created_no_mail": "Account aangemaakt. Je kunt nu inloggen.", @@ -150,11 +137,10 @@ "auth_signup_confirm_label": "Wachtwoord bevestigen", "auth_signup_confirm_placeholder": "Wachtwoord bevestigen", "auth_signup_submit": "Account aanmaken", - "auth_signup_signin_prompt": "Heb je al een account? {#signin}Inloggen{/signin}", + "auth_signup_signin_prompt": "Heb je al een account? Inloggen", "auth_signup_or": "Of", "auth_signup_with_email": "Registreren met e-mail", - "auth_signup_legal": "Door op Account aanmaken te klikken, ga je akkoord met onze {#tos}Servicevoorwaarden{/tos} en ons {#privacy}Privacybeleid{/privacy}.", - + "auth_signup_legal": "Door op Account aanmaken te klikken, ga je akkoord met onze Servicevoorwaarden en ons Privacybeleid.", "auth_verify_breadcrumb": "E-mail verifiëren", "auth_verify_title": "E-mail verifiëren", "auth_verify_verifying": "Je e-mailadres wordt geverifieerd...", @@ -163,7 +149,6 @@ "auth_verify_missing_token": "Verificatietoken ontbreekt", "auth_verify_continue": "Door naar inloggen", "auth_verify_toast_success": "E-mailadres geverifieerd", - "common_cancel": "Annuleren", "common_delete": "Verwijderen", "common_edit": "Bewerken", @@ -194,7 +179,7 @@ "control_type_shock": "Schok", "control_type_vibrate": "Trillen", "control_type_sound": "Geluid", - "live_tooltip_active": "Live via {gateway} ({country}), {latency} ms", + "live_tooltip_active": "Live via {{gateway}} ({{country}}), {{latency}} ms", "live_tooltip_connecting": "Verbinden...", "live_tooltip_connect": "Verbinden met Live Control", "live_tooltip_hub_start": "Ctrl+klik om de hele hub te starten", @@ -207,14 +192,14 @@ "shocker_hub": "Hub", "shocker_select_hub": "Hub kiezen", "shocker_rf_id": "RF-ID", - "shocker_rf_id_invalid": "De RF-ID moet een geheel getal tussen {min} en {max} zijn.", + "shocker_rf_id_invalid": "De RF-ID moet een geheel getal tussen {{min}} en {{max}} zijn.", "shocker_model": "Model", "shocker_select_model": "Model kiezen", "shocker_name_placeholder": "Naam shocker", "shocker_menu_view_logs": "Logs bekijken", "shocker_delete_title": "Shocker verwijderen", - "shocker_delete_desc": "Weet je zeker dat je \"{name}\" wilt verwijderen? Dit kan niet ongedaan worden gemaakt.", - "shocker_toast_deleted": "Shocker \"{name}\" verwijderd", + "shocker_delete_desc": "Weet je zeker dat je \"{{name}}\" wilt verwijderen? Dit kan niet ongedaan worden gemaakt.", + "shocker_toast_deleted": "Shocker \"{{name}}\" verwijderd", "shocker_toast_paused": "Shocker gepauzeerd", "shocker_toast_resumed": "Shocker hervat", "shocker_add_desc": "Registreer een nieuwe shocker bij een van je hubs.", @@ -239,16 +224,8 @@ "shockers_empty_no_hubs": "Maak eerst een hub aan en voeg er dan shockers aan toe.", "shockers_empty_has_hubs": "Voeg een shocker toe aan een van je hubs om te beginnen.", "shockers_create_hub": "Hub aanmaken", - "shockers_count": [ - { - "declarations": ["input count", "local countPlural = count: plural"], - "selectors": ["countPlural"], - "match": { - "countPlural=one": "{count} shocker", - "countPlural=other": "{count} shockers" - } - } - ], + "shockers_count_one": "{{count}} shocker", + "shockers_count_other": "{{count}} shockers", "shared_shockers_title": "Gedeelde shockers", "shared_shockers_subtitle": "Shockers die andere gebruikers met je hebben gedeeld.", "shared_shockers_empty_title": "Er zijn nog geen shockers met je gedeeld.", @@ -277,18 +254,17 @@ "shocker_edit_is_active": "Shocker is actief", "shocker_edit_toast_updated": "Shocker bijgewerkt", "shocker_edit_delete_desc": "Verwijder deze shocker definitief. Dit kan niet ongedaan worden gemaakt.", - "common_close": "Sluiten", "common_continue": "Doorgaan", "common_loading": "Laden...", "common_previous": "Vorige", "common_next": "Volgende", "common_steps": "Stappen", - "common_step_label": "Stap {number}: {title}", + "common_step_label": "Stap {{number}}: {{title}}", "common_copy": "Kopiëren", "common_copied": "Gekopieerd", "common_never": "Nooit", - "common_error": "Fout: {message}", + "common_error": "Fout: {{message}}", "terminal_title": "Seriële terminal", "terminal_connecting": "Verbinden...", "terminal_help_button": "Problemen? Hulp", @@ -301,7 +277,7 @@ "terminal_mode_raw_desc": "Alleen de console. Lees apparaatlogs en verstuur opdrachten.", "terminal_step_channel": "Kanaal kiezen", "terminal_step_board": "Board kiezen", - "terminal_go_to_step": "Ga naar stap {number}: {title}", + "terminal_go_to_step": "Ga naar stap {{number}}: {{title}}", "terminal_erase": "Wissen voor flashen", "terminal_erase_desc": "Wist alle gegevens op het apparaat, inclusief bestaande configuraties", "terminal_unsupported": "Je browser ondersteunt deze functie niet.", @@ -316,15 +292,15 @@ "terminal_try_driver": "Zorg dat de seriële driver is geïnstalleerd.", "terminal_open_troubleshooter": "Probleemoplosser openen", "terminal_log_reset_no_device": "Fout aan hostzijde bij reset: geen apparaat!", - "terminal_log_reset_error": "Fout aan hostzijde bij reset: {error}", + "terminal_log_reset_error": "Fout aan hostzijde bij reset: {{error}}", "terminal_log_send_no_device": "Kan niet verzenden: geen apparaat!", - "terminal_log_send_error": "Kan niet verzenden: {error}", - "terminal_log_firmware_disconnected": "Firmware losgekoppeld: {error}", - "terminal_log_erase_failed": "Flash wissen mislukt: {error}", - "terminal_log_hard_reset_failed": "Hard reset mislukt: {error}", + "terminal_log_send_error": "Kan niet verzenden: {{error}}", + "terminal_log_firmware_disconnected": "Firmware losgekoppeld: {{error}}", + "terminal_log_erase_failed": "Flash wissen mislukt: {{error}}", + "terminal_log_hard_reset_failed": "Hard reset mislukt: {{error}}", "terminal_log_flash_complete": "Flashen voltooid", - "terminal_log_flash_failed": "Flashen mislukt: {error}", - "terminal_log_command_failed": "Kan opdracht niet versturen: {error}", + "terminal_log_flash_failed": "Flashen mislukt: {{error}}", + "terminal_log_command_failed": "Kan opdracht niet versturen: {{error}}", "terminal_help_title": "Probleemoplosser", "terminal_help_desc": "Doorloop deze stappen op volgorde. Elke stap sluit een veelvoorkomende oorzaak uit.", "terminal_help_step_cable": "USB-kabel", @@ -336,23 +312,23 @@ "terminal_help_port_body": "Sluit het apparaat rechtstreeks aan op een USB-poort van je computer. Vermijd indien mogelijk USB-hubs, dockingstations en poorten aan de voorkant; die veroorzaken vaak stroom- en signaalproblemen. Gebruik je een desktop, probeer dan een poort aan de achterkant.", "terminal_help_driver_download": "Download de CP210x-driver:", "terminal_help_driver_extract": "Pak het zipbestand uit in een map op je computer.", - "terminal_help_driver_run": "Open de map en voer {#code}{installer}{/code} uit. Volg de instructies om te installeren.", + "terminal_help_driver_run": "Open de map en voer {{installer}} uit. Volg de instructies om te installeren.", "terminal_help_driver_reconnect": "Sluit het apparaat opnieuw aan.", "terminal_help_manual_intro": "Als de driver is geïnstalleerd maar het apparaat nog steeds niet verschijnt:", - "terminal_help_manual_open": "Open Apparaatbeheer (druk op {#key}Win{/key} + {#key}X{/key} en kies {#code}Device Manager{/code}).", - "terminal_help_manual_ports": "Zoek onder {#code}Ports (COM & LPT){/code} naar een item zoals:", + "terminal_help_manual_open": "Open Apparaatbeheer (druk op Win + X en kies Device Manager).", + "terminal_help_manual_ports": "Zoek onder Ports (COM & LPT) naar een item zoals:", "terminal_help_manual_missing": "Ontbreekt het, dan herkent Windows het apparaat helemaal niet; bekijk de stappen voor kabel en poort opnieuw.", - "terminal_help_manual_update": "Klik met rechts op het apparaat en kies {#code}Update Driver{/code}.", - "terminal_help_manual_browse": "Kies {#code}Browse my computer for drivers{/code} en selecteer de map waarin je de driver-zip hebt uitgepakt. Zorg dat {#code}Include subfolders{/code} is aangevinkt.", - "terminal_help_manual_success": "Als het gelukt is, staat er nu {#code}{deviceName}{/code}.", - "terminal_help_discord_intro": "Kom je er na dit alles nog steeds niet uit? Kom naar onze Discord-server en vraag het in het kanaal {#code}{channel}{/code}. Vermeld daarbij:", + "terminal_help_manual_update": "Klik met rechts op het apparaat en kies Update Driver.", + "terminal_help_manual_browse": "Kies Browse my computer for drivers en selecteer de map waarin je de driver-zip hebt uitgepakt. Zorg dat Include subfolders is aangevinkt.", + "terminal_help_manual_success": "Als het gelukt is, staat er nu {{deviceName}}.", + "terminal_help_discord_intro": "Kom je er na dit alles nog steeds niet uit? Kom naar onze Discord-server en vraag het in het kanaal {{channel}}. Vermeld daarbij:", "terminal_help_discord_os": "je besturingssysteem en browser", "terminal_help_discord_device": "het apparaat dat je gebruikt (boardmodel, waar je het vandaan hebt)", "terminal_help_discord_tried": "wat je van de vorige stappen al hebt geprobeerd", "terminal_help_discord_errors": "eventuele foutmeldingen of relevante terminaluitvoer", "terminal_help_discord_join": "Word lid van onze Discord-server", "terminal_risk_title": "⚠️ INSTABIELE FIRMWARE", - "terminal_risk_intro": "Je staat op het punt {#strong}experimentele firmware{/strong} te flashen die {#strong}bekend instabiel{/strong} is.", + "terminal_risk_intro": "Je staat op het punt experimentele firmware te flashen die bekend instabiel is.", "terminal_risk_brick": "Dit kan je apparaat permanent onbruikbaar maken of handmatig herstel vereisen.", "terminal_risk_no_support": "We bieden GEEN ondersteuning bij problemen die door deze firmware ontstaan.", "terminal_risk_acknowledge": "Ik begrijp dat dit volledig mijn eigen verantwoordelijkheid is", @@ -367,7 +343,7 @@ "terminal_board_search": "Boards zoeken...", "terminal_board_none": "Geen board gevonden.", "terminal_flash_button": "Flashen", - "terminal_flash_progress": "Voortgang: {status}", + "terminal_flash_progress": "Voortgang: {{status}}", "terminal_flash_idle": "Gereed", "terminal_flash_no_device": "Geen apparaat geselecteerd.", "terminal_flash_resetting": "Resetten...", @@ -378,7 +354,7 @@ "terminal_flash_done": "Apparaat herstart! Flashen voltooid.", "terminal_port_select": "Apparaat kiezen", "terminal_port_disconnect": "Apparaat loskoppelen", - "terminal_port_connected": "Apparaat verbonden: {#strong}{id}{/strong}", + "terminal_port_connected": "Apparaat verbonden: {{id}}", "terminal_console": "Console", "terminal_connected_device": "Verbonden apparaat", "terminal_resize": "Grootte terminalpaneel wijzigen", @@ -394,7 +370,7 @@ "terminal_colors_menu": "Kleuren...", "terminal_colors_label": "Consolekleuren", "terminal_colors_close": "Kleuren sluiten", - "terminal_color_input": "Kleur voor {name}", + "terminal_color_input": "Kleur voor {{name}}", "terminal_colors_reset": "Standaard herstellen", "terminal_color_bg": "Achtergrond", "terminal_color_fg": "Tekst", @@ -424,13 +400,12 @@ "terminal_toast_clipboard_unreadable": "Kan het klembord niet lezen", "terminal_toast_settings_imported": "Console-instellingen geïmporteerd", "terminal_toast_settings_invalid": "Het klembord bevat geen console-instellingen", - "common_try_again": "Opnieuw proberen", - "terminal_cfg_intro": "Waarden worden via UART naar het apparaat gestuurd. Het antwoord van het apparaat zie je in de console hieronder. Opdrachten zonder argument lezen de waarde uit; gebruik de {#eye/}-knop naast elk veld om de huidige waarde te lezen.", + "terminal_cfg_intro": "Waarden worden via UART naar het apparaat gestuurd. Het antwoord van het apparaat zie je in de console hieronder. Opdrachten zonder argument lezen de waarde uit; gebruik de -knop naast elk veld om de huidige waarde te lezen.", "terminal_cfg_rf_title": "RF-zender", "terminal_cfg_rf_desc": "Regelt de RF-uitvoer naar de shockers.", "terminal_cfg_tx_pin": "TX-GPIO-pin", - "terminal_cfg_example": "bijv. {value}", + "terminal_cfg_example": "bijv. {{value}}", "terminal_cfg_read_value": "Huidige waarde lezen", "terminal_cfg_set": "Instellen", "terminal_cfg_read": "Lezen", @@ -442,13 +417,13 @@ "terminal_cfg_estop_desc": "Hardwareknop die alle uitvoer stopt.", "terminal_cfg_estop_enabled": "Noodstop aan", "terminal_cfg_estop_pin": "Noodstop-GPIO-pin", - "terminal_cfg_estop_note": "Let op: {#code}{latching}{/code} en {#code}{active}{/code} hebben geen eigen opdrachten; stel ze in via de JSON-configuratie hieronder.", + "terminal_cfg_estop_note": "Let op: {{latching}} en {{active}} hebben geen eigen opdrachten; stel ze in via de JSON-configuratie hieronder.", "terminal_cfg_wifi_title": "Wifi", "terminal_cfg_wifi_desc": "Netwerkgegevens en hostnaam van het apparaat.", "terminal_cfg_hostname": "Hostnaam", "terminal_cfg_networks": "Netwerken (JSON-array)", "terminal_cfg_invalid_json_array": "Moet een geldige JSON-array zijn", - "terminal_cfg_ap_note": "AP-instellingen ({#code}{ssid}{/code}, {#code}{password}{/code}, {#code}{disabled}{/code}, {#code}{staDisabled}{/code}, {#code}{offlineMode}{/code}) hebben geen eigen opdrachten; gebruik de JSON-configuratie.", + "terminal_cfg_ap_note": "AP-instellingen ({{ssid}}, {{password}}, {{disabled}}, {{staDisabled}}, {{offlineMode}}) hebben geen eigen opdrachten; gebruik de JSON-configuratie.", "terminal_cfg_backend_title": "Backend", "terminal_cfg_backend_desc": "OpenShock-server en authenticatie.", "terminal_cfg_domain": "Domein", @@ -476,12 +451,11 @@ "terminal_cfg_factory_reset_confirm": "Hiermee wordt alle configuratie op het apparaat gewist: wifinetwerken, backendgegevens, pins en alle andere instellingen. Het apparaat wordt teruggezet naar de standaardwaarden.", "terminal_cfg_read_failed_json_title": "Kon de JSON-configuratie niet lezen", "terminal_cfg_read_failed_raw_title": "Kon de ruwe configuratie niet lezen", - "terminal_cfg_read_failed_desc": "Het apparaat reageerde niet na {attempts} pogingen.", + "terminal_cfg_read_failed_desc": "Het apparaat reageerde niet na {{attempts}} pogingen.", "terminal_cfg_common_causes": "Veelvoorkomende oorzaken:", "terminal_cfg_cause_busy": "Het apparaat is bezig met een andere opdracht.", "terminal_cfg_cause_disconnected": "Het apparaat is losgekoppeld of herstart.", "terminal_cfg_cause_unsupported": "Deze firmwareversie ondersteunt deze opdracht niet.", - "common_status": "Status", "common_version": "Versie", "common_created": "Aangemaakt", @@ -502,25 +476,25 @@ "hubs_name_placeholder": "Mijn hub", "hub_toast_not_connected": "Niet verbonden met de server", "hub_toast_try_later": "Probeer het zo opnieuw.", - "hub_reboot_title": "{name} herstarten?", + "hub_reboot_title": "{{name}} herstarten?", "hub_reboot_desc": "De hub verbreekt de verbinding en herstart. Gekoppelde shockers reageren pas weer als hij online is.", "hub_reboot": "Herstarten", - "hub_hotspot_enable_title": "Wifi-hotspot op {name} inschakelen?", - "hub_hotspot_disable_title": "Wifi-hotspot op {name} uitschakelen?", + "hub_hotspot_enable_title": "Wifi-hotspot op {{name}} inschakelen?", + "hub_hotspot_disable_title": "Wifi-hotspot op {{name}} uitschakelen?", "hub_hotspot_enable_desc": "De hub zendt een eigen installatienetwerk uit. Hij blijft bereikbaar via je wifi, maar de hotspot is open voor iedereen binnen bereik totdat je hem uitzet.", "hub_hotspot_disable_desc": "De installatiehotspot wordt uitgeschakeld. Als de hub nog niet op je wifi zit, heb je fysieke toegang nodig om hem opnieuw in te stellen.", - "hub_delete_desc": "Je staat op het punt hub {#strong}{name}{/strong} te verwijderen.", + "hub_delete_desc": "Je staat op het punt hub {{name}} te verwijderen.", "hub_delete_shockers": "Hiermee worden ook de volgende shockers verwijderd:", "hub_edit_title": "Hub bewerken", "hub_edit_apply": "Toepassen", "hub_pair_title_generate": "Koppelcode genereren?", "hub_pair_title_generated": "Koppelcode gegenereerd", "hub_pair_title_paired": "Hub gekoppeld", - "hub_pair_consumed": "{#strong}{name}{/strong} heeft deze koppelcode gebruikt en is nu gekoppeld.", + "hub_pair_consumed": "{{name}} heeft deze koppelcode gebruikt en is nu gekoppeld.", "hub_pair_used": "De code is gebruikt en niet meer geldig.", - "hub_pair_generated_for": "Koppelcode gegenereerd voor {#strong}{name}{/strong}.", + "hub_pair_generated_for": "Koppelcode gegenereerd voor {{name}}.", "hub_copy_now": "De code hieronder is later niet meer op te vragen. Kopieer hem nu en werk je clients ermee bij.", - "hub_pair_generate_for": "Je staat op het punt een koppelcode te genereren voor {#strong}{name}{/strong}.", + "hub_pair_generate_for": "Je staat op het punt een koppelcode te genereren voor {{name}}.", "hub_pair_valid_for": "Hij is 15 minuten geldig na het aanmaken.", "hub_pair_one_active": "Er is maar één actieve koppelcode per hub; een nieuwe code vervangt de oudere.", "hub_pair_complete": "Koppelen voltooid", @@ -528,8 +502,8 @@ "hub_pair_copied_close": "Code gekopieerd, sluiten", "hub_pair_get": "Koppelcode ophalen", "hub_token_generated": "Token gegenereerd", - "hub_token_generated_for": "Nieuw token gegenereerd voor {#strong}{name}{/strong}.", - "hub_token_regenerate_for": "Je staat op het punt het token voor {#strong}{name}{/strong} opnieuw te genereren.", + "hub_token_generated_for": "Nieuw token gegenereerd voor {{name}}.", + "hub_token_regenerate_for": "Je staat op het punt het token voor {{name}} opnieuw te genereren.", "hub_token_invalidate": "Hierdoor wordt het huidige token ongeldig en worden clients die het gebruiken losgekoppeld.", "hub_token_confirm": "Weet je zeker dat je dit wilt doen?", "hub_token_label": "Nieuw token:", @@ -557,12 +531,12 @@ "hub_update_status_error": "Fout", "hub_update_status_timeout": "Time-out", "hub_update_confirm_title": "Firmware-update bevestigen", - "hub_update_confirm_desc": "{#strong}{name}{/strong} bijwerken naar versie {#strong}{version}{/strong}?", + "hub_update_confirm_desc": "{{name}} bijwerken naar versie {{version}}?", "hub_update_unstable_warning": "Deze versie komt mogelijk niet uit het stabiele kanaal en kan bugs bevatten.", - "hub_update_title": "{name} bijwerken", + "hub_update_title": "{{name}} bijwerken", "hub_update_subtitle": "Beheer firmware-updates voor deze hub.", "hub_update_status_title": "Hubstatus", - "hub_update_firmware": "Firmware: {#mono}{version}{/mono}", + "hub_update_firmware": "Firmware: {{version}}", "hub_update_confirm": "Updaten", "hub_update_success": "Update voltooid", "hub_update_rolled_back": "Apparaat teruggezet naar vorige versie", @@ -570,9 +544,9 @@ "hub_update_flash_again": "Opnieuw flashen", "hub_update_card_title": "Firmware-update", "hub_update_card_desc": "Kies een firmwarekanaal en een versie om te installeren.", - "hub_update_to": "Bijwerken naar {version}", + "hub_update_to": "Bijwerken naar {{version}}", "hub_update_must_be_online": "De hub moet online zijn om een update te starten.", - "hub_update_updating_to": "Bijwerken naar {version}...", + "hub_update_updating_to": "Bijwerken naar {{version}}...", "hub_update_total": "Totaal", "hub_update_task": "Taak", "hub_update_history": "Updategeschiedenis", @@ -584,14 +558,14 @@ "hub_update_not_found": "Hub niet gevonden.", "home_breadcrumb": "Start", "home_welcome": "Welkom terug", - "home_welcome_name": "Welkom terug, {name}", + "home_welcome_name": "Welkom terug, {{name}}", "home_subtitle": "Hier is een overzicht van je OpenShock-setup.", - "home_hubs_online": "{count} online", + "home_hubs_online": "{{count}} online", "home_hub_status": "Hubstatus", "home_no_hubs": "Geen hubs", "home_all_online": "Alles online", "home_all_offline": "Alles offline", - "home_some_online": "{online}/{total} online", + "home_some_online": "{{online}}/{{total}} online", "home_quick_links": "Snelkoppelingen", "home_my_shockers": "Mijn shockers", "home_my_shockers_desc": "Bedien je shockers", @@ -602,24 +576,15 @@ "home_get_started_desc": "Je hebt nog geen hubs. Maak een hub om je eerste apparaat te verbinden en voeg er daarna shockers aan toe.", "home_set_up_hub": "Hub instellen", "home_first_shocker": "Voeg je eerste shocker toe", - "home_first_shocker_desc": [ - { - "declarations": ["input count", "local countPlural = count: plural"], - "selectors": ["countPlural"], - "match": { - "countPlural=one": "Je hebt {count} hub ingesteld. Voeg een shocker toe om die te bedienen.", - "countPlural=other": "Je hebt {count} hubs ingesteld. Voeg een shocker toe om die te bedienen." - } - } - ], + "home_first_shocker_desc_one": "Je hebt {{count}} hub ingesteld. Voeg een shocker toe om die te bedienen.", + "home_first_shocker_desc_other": "Je hebt {{count}} hubs ingesteld. Voeg een shocker toe om die te bedienen.", "home_go_to_shockers": "Naar shockers", "profile_title": "Profiel", "profile_coming_soon": "Profiel komt binnenkort", "profile_coming_soon_desc": "Je openbare profiel is nog niet beschikbaar. Accountgegevens vind je onder Instellingen.", - "common_retry": "Opnieuw", "common_never_used": "Nooit gebruikt", - "common_expires": "Verloopt {time}", + "common_expires": "Verloopt {{time}}", "common_search_placeholder": "Zoeken...", "common_unknown": "Onbekend", "settings_breadcrumb_account": "Account", @@ -649,7 +614,7 @@ "account_deactivate": "Account deactiveren", "account_email_title": "E-mail wijzigen", "account_email_desc": "Voer je nieuwe e-mailadres in en bevestig met je huidige wachtwoord.", - "account_email_toast_sent": "Verificatie-e-mail verzonden naar {email}. Klik op de link in die e-mail om de wijziging door te voeren.", + "account_email_toast_sent": "Verificatie-e-mail verzonden naar {{email}}. Klik op de link in die e-mail om de wijziging door te voeren.", "account_new_email": "Nieuw e-mailadres", "account_current_password": "Huidig wachtwoord", "account_password_title": "Wachtwoord wijzigen", @@ -664,8 +629,8 @@ "tokens_toast_refreshed": "Tokens vernieuwd", "tokens_empty_title": "Geen API tokens", "tokens_empty_desc": "Maak een token om je te authenticeren bij de OpenShock API.", - "tokens_created_on": "Gemaakt op {date}", - "tokens_last_used": "Laatst gebruikt {time}", + "tokens_created_on": "Gemaakt op {{date}}", + "tokens_last_used": "Laatst gebruikt {{time}}", "tokens_never_expires": "Verloopt nooit", "tokens_load_failed": "Kan API tokens niet laden.", "token_toast_edited": "Token bewerkt", @@ -687,7 +652,7 @@ "token_toast_paused": "Token gepauzeerd", "token_toast_resumed": "Token hervat", "token_delete_title": "API token verwijderen", - "token_delete_desc": "Weet je zeker dat je {#strong}{name}{/strong} wilt verwijderen?", + "token_delete_desc": "Weet je zeker dat je {{name}} wilt verwijderen?", "token_delete_permanent": "Dit kan niet ongedaan worden gemaakt. Het token wordt permanent verwijderd.", "token_toast_deleted": "Token verwijderd", "token_resume": "Token hervatten", @@ -700,11 +665,11 @@ "token_new_breadcrumb": "Nieuw", "token_redirect_not_allowed": "De opgegeven redirect_uri is niet toegestaan. Alleen loopback-adressen of eigen applicatieschema's zijn toegestaan.", "token_params_missing": "Verplichte GET-parameters ontbreken. Zorg dat name, redirect_uri en permissions zijn opgegeven.", - "token_invalid_permissions": "Ongeldige rechten opgegeven: {list}", + "token_invalid_permissions": "Ongeldige rechten opgegeven: {{list}}", "token_toast_created": "Token gemaakt", "token_request_title": "API token-aanvraag", "token_access_granted": "Toegang verleend", - "token_shared_redirecting": "Het token is gemaakt en gedeeld met de applicatie. Je wordt teruggestuurd naar {#b}{uri}{/b}.", + "token_shared_redirecting": "Het token is gemaakt en gedeeld met de applicatie. Je wordt teruggestuurd naar {{uri}}.", "token_not_redirected": "Word je niet automatisch doorgestuurd, gebruik dan de knop hieronder.", "token_finish": "Voltooien", "token_generated_title": "API token gemaakt", @@ -712,7 +677,7 @@ "token_new_title": "Nieuw API token", "token_external_desc": "Een externe applicatie vraagt toegang tot je account. Controleer en pas de rechten hieronder aan voordat je toegang geeft.", "token_new_desc": "Stel een nieuw API token voor je account in en maak het aan.", - "token_external_requesting": "{#b}{name}{/b} vraagt een API token aan. Je token wordt gedeeld met de applicatie op {#b}{uri}{/b}.", + "token_external_requesting": "{{name}} vraagt een API token aan. Je token wordt gedeeld met de applicatie op {{uri}}.", "token_allow": "Toestaan", "token_generate": "Maken", "token_deny": "Weigeren", @@ -722,13 +687,13 @@ "sessions_load_failed": "Kan sessies niet laden.", "sessions_empty_title": "Geen actieve sessies", "sessions_empty_desc": "Sessies verschijnen hier zodra je inlogt via een browser of app.", - "sessions_last_seen": "Laatst gezien {time}", - "sessions_signed_in": "Ingelogd {time}", + "sessions_last_seen": "Laatst gezien {{time}}", + "sessions_signed_in": "Ingelogd {{time}}", "session_toast_revoked": "Sessie ingetrokken", "session_revoke_title": "Sessie intrekken", "session_revoke": "Intrekken", "session_revoke_desc": "Weet je zeker dat je deze sessie wilt intrekken?", - "session_revoke_from": "Sessie ingelogd vanaf {#strong}{ip}{/strong} met {#strong}{agent}{/strong}", + "session_revoke_from": "Sessie ingelogd vanaf {{ip}} met {{agent}}", "connections_title": "OAuth-koppelingen", "connections_subtitle": "Koppel accounts van derden of ontkoppel ze om sneller in te loggen en je profiel gesynchroniseerd te houden.", "connections_toast_linked": "Account gekoppeld.", @@ -741,11 +706,11 @@ "connections_empty_desc": "Kies hierboven “Nieuwe provider koppelen” om beschikbare providers te verbinden.", "connections_unlink": "Ontkoppelen", "connections_load_failed": "Kan OAuth-koppelingen niet laden.", - "connections_unlink_title": "{name} ontkoppelen?", + "connections_unlink_title": "{{name}} ontkoppelen?", "connections_unlink_title_generic": "Dit account ontkoppelen?", "connections_unlink_desc": "Je kunt dan niet meer inloggen met deze provider, tenzij je hem opnieuw koppelt.", - "provider_starting": "{name} starten...", - "provider_link": "{name} koppelen", + "provider_starting": "{{name}} starten...", + "provider_link": "{{name}} koppelen", "audit_subtitle": "Beveiligingsrelevante activiteit op je account. Controleer alles wat je niet herkent.", "audit_col_time": "Tijd", "audit_col_action": "Actie", @@ -771,22 +736,13 @@ "audit_action_automation_token_rotated": "Automatiseringstoken vernieuwd", "audit_action_automation_token_deleted": "Automatiseringstoken verwijderd", "audit_action_automation_token_used": "Automatiseringstoken gebruikt", - "audit_meta_session": "Sessie {id}", - "audit_meta_changed": "{old} naar {new}", - "audit_meta_email_requested": "Wijziging naar {email} aangevraagd", - "audit_meta_accounts_removed": [ - { - "declarations": ["input count", "local countPlural = count: plural"], - "selectors": ["countPlural"], - "match": { - "countPlural=one": "{name} ({count} account verwijderd)", - "countPlural=other": "{name} ({count} accounts verwijderd)" - } - } - ], + "audit_meta_session": "Sessie {{id}}", + "audit_meta_changed": "{{old}} naar {{new}}", + "audit_meta_email_requested": "Wijziging naar {{email}} aangevraagd", + "audit_meta_accounts_removed_one": "{{name}} ({{count}} account verwijderd)", + "audit_meta_accounts_removed_other": "{{name}} ({{count}} accounts verwijderd)", "audit_meta_scheduled_deletion": "Gepland voor verwijdering", "audit_meta_kept": "Bewaard voor heractivering", - "common_view": "Bekijken", "common_save": "Opslaan", "common_saving": "Opslaan...", @@ -811,20 +767,12 @@ "public_share_create_title": "Openbare deling maken", "public_share_toast_deleted": "Openbare deling verwijderd", "public_share_delete_title": "Openbare deling verwijderen", - "public_share_delete_desc": "Weet je zeker dat je openbare deling {#strong}{name}{/strong} wilt verwijderen?", - "public_share_edit_title": "Openbare deling: {name}", + "public_share_delete_desc": "Weet je zeker dat je openbare deling {{name}} wilt verwijderen?", + "public_share_edit_title": "Openbare deling: {{name}}", "public_share_edit_subtitle": "Bewerken: wijzigingen gelden zodra je opslaat.", "public_share_add_shocker": "Shocker toevoegen", - "public_share_toast_added": [ - { - "declarations": ["input count", "local countPlural = count: plural"], - "selectors": ["countPlural"], - "match": { - "countPlural=one": "{count} shocker aan deling toegevoegd", - "countPlural=other": "{count} shockers aan deling toegevoegd" - } - } - ], + "public_share_toast_added_one": "{{count}} shocker aan deling toegevoegd", + "public_share_toast_added_other": "{{count}} shockers aan deling toegevoegd", "public_share_empty_shockers_title": "Geen shockers in deze deling", "public_share_empty_shockers_desc": "Voeg een shocker toe en iedereen met de link kan hem bedienen.", "public_share_load_failed": "Fout bij ophalen van delinggegevens", @@ -854,15 +802,14 @@ "perm_live_on": "Live ingeschakeld", "perm_live_off": "Live uitgeschakeld", "perm_live_control": "Live-bediening", - "user_selector_avatar_of": "Avatar van {name}", + "user_selector_avatar_of": "Avatar van {{name}}", "user_selector_placeholder": "Gebruikersnaam invoeren", "user_selector_aria": "Te zoeken gebruikersnaam", "user_selector_search": "Gebruiker zoeken", "user_selector_found": "Gebruiker gevonden", - "common_remove": "Verwijderen", "user_shares_subtitle": "Directe, permanente delingen met andere gebruikers.", - "user_shares_toast_invited": "Shocker-uitnodiging naar {name} verstuurd", + "user_shares_toast_invited": "Shocker-uitnodiging naar {{name}} verstuurd", "user_shares_redeem": "Code inwisselen", "user_shares_new": "Nieuwe deling", "user_shares_tab_shares": "Delingen", @@ -885,12 +832,12 @@ "share_code_redeem": "Inwisselen", "incoming_shares_empty_title": "Niets met je gedeeld", "incoming_shares_empty_desc": "Nog niemand heeft een shocker met je gedeeld.", - "incoming_share_toast_removed": "Deling van {name} verwijderd", + "incoming_share_toast_removed": "Deling van {{name}} verwijderd", "incoming_share_remove_title": "Deling verwijderen", - "incoming_share_remove_desc": "Weet je zeker dat je de deling van {#strong}{name}{/strong} wilt verwijderen?", - "incoming_share_toast_removed_shocker": "{shocker} van {name} verwijderd", + "incoming_share_remove_desc": "Weet je zeker dat je de deling van {{name}} wilt verwijderen?", + "incoming_share_toast_removed_shocker": "{{shocker}} van {{name}} verwijderd", "incoming_share_remove_shocker_title": "Deze gedeelde shocker verwijderen?", - "incoming_share_remove_shocker_desc": "Weet je zeker dat je de gedeelde shocker {#strong}{shocker}{/strong} van {#strong}{name}{/strong} wilt verwijderen?", + "incoming_share_remove_shocker_desc": "Weet je zeker dat je de gedeelde shocker {{shocker}} van {{name}} wilt verwijderen?", "incoming_share_manage_from": "Delingen beheren van", "share_remove": "Deling verwijderen", "invites_empty_title": "Nog geen uitnodigingen", @@ -901,23 +848,23 @@ "invites_incoming": "Inkomend", "invites_incoming_empty_title": "Geen inkomende uitnodigingen", "invites_incoming_empty_desc": "Je hebt geen inkomende uitnodigingen.", - "invite_toast_accepted": "Uitnodiging van {name} geaccepteerd", - "invite_toast_declined": "Uitnodiging van {name} geweigerd", + "invite_toast_accepted": "Uitnodiging van {{name}} geaccepteerd", + "invite_toast_declined": "Uitnodiging van {{name}} geweigerd", "invite_deny_title": "Uitnodiging weigeren", "invite_deny_label": "Uitnodiging weigeren", "invite_deny": "Weigeren", - "invite_deny_desc": "Weet je zeker dat je de uitnodiging van {#strong}{name}{/strong} wilt weigeren?", + "invite_deny_desc": "Weet je zeker dat je de uitnodiging van {{name}} wilt weigeren?", "invite_accept": "Accepteren", - "invite_toast_cancelled_for": "Uitnodiging voor {name} ingetrokken ({id})", - "invite_toast_cancelled": "Uitnodiging {id} ingetrokken", + "invite_toast_cancelled_for": "Uitnodiging voor {{name}} ingetrokken ({{id}})", + "invite_toast_cancelled": "Uitnodiging {{id}} ingetrokken", "invite_cancel_title": "Uitnodiging intrekken", "invite_cancel": "Intrekken", - "invite_cancel_for_desc": "Weet je zeker dat je de uitnodiging voor {#strong}{name}{/strong} wilt intrekken?", - "invite_cancel_code_desc": "Weet je zeker dat je de uitnodiging met code {#strong}{code}{/strong} wilt intrekken?", + "invite_cancel_for_desc": "Weet je zeker dat je de uitnodiging voor {{name}} wilt intrekken?", + "invite_cancel_code_desc": "Weet je zeker dat je de uitnodiging met code {{code}} wilt intrekken?", "invite_cancel_outstanding": "Openstaande uitnodiging intrekken", "outgoing_shares_empty_title": "Geen gedeelde shockers", "outgoing_shares_empty_desc": "Je hebt nog geen shockers met andere gebruikers gedeeld.", - "outgoing_share_toast_removed": "Gedeelde shocker {name} verwijderd", + "outgoing_share_toast_removed": "Gedeelde shocker {{name}} verwijderd", "outgoing_share_remove_title": "Stoppen met delen van deze shocker?", "outgoing_share_editing_for": "Delingen bewerken voor", "outgoing_share_limits": "Limieten en rechten", @@ -925,11 +872,9 @@ "outgoing_share_per_desc": "Beperkingen per shocker instellen", "outgoing_share_all": "Alle", "outgoing_share_per": "Per shocker", - - "outgoing_share_remove_desc": "Weet je zeker dat je {#strong}{shocker}{/strong} niet meer wilt delen met {#strong}{name}{/strong}?", - + "outgoing_share_remove_desc": "Weet je zeker dat je {{shocker}} niet meer wilt delen met {{name}}?", "report_breadcrumb": "API-tokens melden", - "report_toast_clipboard_failed": "Klembord lezen mislukt: {error}", + "report_toast_clipboard_failed": "Klembord lezen mislukt: {{error}}", "report_title": "Gelekte API-tokens melden", "report_paste": "Plakken van klembord", "report_warning": "Dit formulier is alleen bedoeld voor het melden van per ongeluk gelekte API-tokens.", @@ -947,19 +892,11 @@ "expiration_label": "Vervaldatum", "expiration_never": "Nooit", "expiration_custom": "Aangepast", - "expiration_days": [ - { - "declarations": ["input count", "local countPlural = count: plural"], - "selectors": ["countPlural"], - "match": { - "countPlural=one": "{count} dag", - "countPlural=other": "{count} dagen" - } - } - ], + "expiration_days_one": "{{count}} dag", + "expiration_days_other": "{{count}} dagen", "expiration_required": "Vervaldatum is verplicht", "expiration_never_desc": "Verloopt nooit", - "expiration_expires_at": "Verloopt {time} ({date})", + "expiration_expires_at": "Verloopt {{time}} ({{date}})", "date_picker_placeholder": "Kies een datum", "telemetry_toast_title": "Help je OpenShock verbeteren?", "telemetry_toast_desc": "Stuur diagnosegegevens zodat we crashes en trage API-aanroepen kunnen oplossen. Rapporten bevatten de foutmelding, stacktrace en je IP-adres. Je kunt dit altijd wijzigen in de accountinstellingen.", @@ -969,28 +906,27 @@ "table_show_details": "Details tonen", "table_hide_details": "Details verbergen", "table_no_results": "Geen resultaten.", - "table_sort_asc": "Sorteren op {name}, oplopend", - "table_sort_desc": "Sorteren op {name}, aflopend", - "table_sort_none": "Sorteren op {name}, ongesorteerd", + "table_sort_asc": "Sorteren op {{name}}, oplopend", + "table_sort_desc": "Sorteren op {{name}}, aflopend", + "table_sort_none": "Sorteren op {{name}}, ongesorteerd", "cell_na": "n.v.t.", "cell_not_applicable": "Niet van toepassing", "cell_invalid": "Ongeldig", "cell_unavailable": "Niet beschikbaar", "cell_none": "Geen", - "oauth_login_with": "Inloggen met {provider}", - "oauth_signup_with": "Registreren met {provider}", + "oauth_login_with": "Inloggen met {{provider}}", + "oauth_signup_with": "Registreren met {{provider}}", "signalr_connect_failed": "Verbinden met server mislukt!", "signalr_disconnect_failed": "Fout bij het verbreken van de verbinding met de server!", "signalr_invalid_update": "Ongeldige update van server ontvangen!", "signalr_invalid_log": "Ongeldige loggegevens van server ontvangen!", "signalr_invalid_ota": "Ongeldige firmware-updategegevens van server ontvangen!", - "ota_toast_failed": "Firmware-update van hub mislukt: {message}", + "ota_toast_failed": "Firmware-update van hub mislukt: {{message}}", "ota_toast_succeeded": "Firmware-update van hub voltooid!", "ota_toast_rolled_back": "Hub-firmware teruggezet naar vorige versie", "lcg_connect_failed": "Verbinden met live control gateway mislukt", - "terminal_toast_bootloader_failed": "Bootloader starten mislukt: {error}", - "terminal_toast_app_mode_failed": "Applicatiemodus starten mislukt: {error}", - + "terminal_toast_bootloader_failed": "Bootloader starten mislukt: {{error}}", + "terminal_toast_app_mode_failed": "Applicatiemodus starten mislukt: {{error}}", "problem_account_account_not_activated_title": "Account niet geactiveerd", "problem_account_account_not_activated_desc": "Kijk in je inbox voor de activatiemail.", "problem_account_activation_not_found_title": "Activatielink is ongeldig", @@ -1108,22 +1044,12 @@ "problem_webhook_not_found_title": "Webhook niet gevonden", "problem_webhook_unsupported_title": "Alleen Discord-webhooks worden ondersteund", "problem_webhook_unsupported_desc": "Gebruik een discord.com-URL, geen canary of ptb.", - "error_too_many_requests": "Te veel verzoeken", - "error_retry_after": [ - { - "declarations": ["input seconds", "local secondsPlural = seconds: plural"], - "selectors": ["secondsPlural"], - "match": { - "secondsPlural=one": "Probeer het over {seconds} seconde opnieuw.", - "secondsPlural=other": "Probeer het over {seconds} seconden opnieuw." - } - } - ], + "error_retry_after_one": "Probeer het over {{count}} seconde opnieuw.", + "error_retry_after_other": "Probeer het over {{count}} seconden opnieuw.", "error_unexpected_response": "Onverwacht antwoord van server", "error_internal": "Er is een interne fout opgetreden", "error_network": "Er is een netwerkfout opgetreden", - - "dev_banner": "Dit is de {#b}ONTWIKKEL{/b}omgeving van OpenShock. {#u}Er worden geen gegevens opgeslagen{/u} en ze wordt regelmatig overschreven met productiegegevens.", + "dev_banner": "Dit is de ONTWIKKELomgeving van OpenShock. Er worden geen gegevens opgeslagen en ze wordt regelmatig overschreven met productiegegevens.", "firmware_channel_bugs_warning": "Dit kanaal kan bugs bevatten." } From 15febfbdfb4b7ed5a8bb51b1ff23c64c047d6de9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Luc=20=E2=99=A5?= Date: Thu, 12 Nov 2026 17:43:26 +0100 Subject: [PATCH 18/27] New translations en.json (Norwegian) [ci skip] --- messages/no.json | 1055 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 1055 insertions(+) create mode 100644 messages/no.json diff --git a/messages/no.json b/messages/no.json new file mode 100644 index 00000000..ef4df56c --- /dev/null +++ b/messages/no.json @@ -0,0 +1,1055 @@ +{ + "landing_tagline": "The go-to platform for safe, reliable, real low-latency remote shocking.", + "landing_section_label": "Home", + "landing_hubs_online": "Hubs online right now: ", + "landing_learn_more": "Learn More", + "landing_wiki": "Wiki", + "landing_meta_description": "Welcome to OpenShock, a free and open-source ecosystem to control various shock collars over the internet.", + "instance_meta_description": "Welcome to {{siteName}}, an independent instance of OpenShock, a free and open-source ecosystem to control various shock collars over the internet.", + "header_sidebar_toggle": "Toggle Sidebar", + "header_avatar_alt": "{{name}}'s avatar", + "header_menu_profile": "Profile", + "header_menu_settings": "Settings", + "header_menu_logout": "Logout", + "header_login": "Login", + "header_signup": "Sign Up", + "header_github_title": "OpenShock on GitHub", + "header_discord_title": "Community Discord", + "footer_made_with": "Made with by the OpenShock Team", + "footer_connection_status_label": "Server connection status", + "footer_signalr_state": "SignalR State", + "footer_frontend_version": "Frontend Version", + "footer_frontend_commit_title": "Commit {{commit}}", + "footer_backend_version": "Backend Version", + "footer_backend_commit_title": "Commit {{commit}}", + "footer_language_label": "Language", + "sidebar_home_link_label": "OpenShock home", + "sidebar_group_general": "General", + "sidebar_home": "Home", + "sidebar_shockers": "Shockers", + "sidebar_shared_shockers": "Shared Shockers", + "sidebar_hubs": "Hubs", + "sidebar_user_shares": "User Shares", + "sidebar_public_shares": "Public Shares", + "sidebar_serial_terminal": "Serial Terminal", + "sidebar_group_admin": "Admin", + "sidebar_admin_monitoring": "Monitoring", + "sidebar_admin_online_hubs": "Online Hubs", + "sidebar_admin_online_gateways": "Online Gateways", + "sidebar_admin_management": "Management", + "sidebar_admin_users": "Users", + "sidebar_admin_blacklists": "Blacklists", + "sidebar_admin_webhooks": "Webhooks", + "sidebar_admin_mail": "Mail", + "sidebar_admin_automation_tokens": "Automation Tokens", + "sidebar_admin_configuration": "Configuration", + "sidebar_group_settings": "Settings", + "sidebar_settings_api_tokens": "API Tokens", + "sidebar_settings_sessions": "Sessions", + "sidebar_settings_audit_log": "Audit Log", + "sidebar_settings_connections": "Connections", + "sidebar_settings_account": "Account Settings", + "error_meta_title": "Service Unavailable", + "error_meta_description": "OpenShock is currently unavailable", + "error_meta_logo_alt": "OpenShock Logo", + "error_fallback_message": "Something went wrong.", + "error_not_found_message": "Page not found", + "error_not_found_description": "The page you're looking for doesn't exist.", + "error_unexpected_description": "An unexpected error occurred.", + "error_go_back": "Go back", + "auth_layout_logo_alt": "OpenShock Logo", + "auth_layout_invalid_redirect_removed": "An invalid redirect URL was removed for your safety.", + "auth_activate_breadcrumb": "Activate Account", + "auth_activate_title": "Activate Account", + "auth_activate_activating": "Activating your account...", + "auth_activate_success": "Your account has been activated", + "auth_activate_failed": "This activation link is invalid or has expired", + "auth_activate_missing_token": "Missing activation token", + "auth_activate_continue": "Continue to login", + "auth_activate_toast_success": "Account activated", + "auth_forgot_breadcrumb": "Forgot Password", + "auth_forgot_title": "Forgot Password", + "auth_forgot_description": "Enter your email to reset your password", + "auth_forgot_email_label": "Email", + "auth_forgot_email_placeholder": "Email", + "auth_forgot_submit": "Reset Password", + "auth_forgot_signin_prompt": "Remember your password? Sign in", + "auth_forgot_mail_disabled": "Password resets are unavailable on this instance because it has no mail provider configured. Please contact your administrator for help recovering your account.", + "auth_forgot_toast_sent": "Reset password request has been sent to the given email", + "auth_login_breadcrumb": "Login", + "auth_login_title": "Welcome back", + "auth_login_loading_methods": "Loading available login methods", + "auth_login_choose_method": "Login with one of these methods", + "auth_login_with_account": "Login with your OpenShock Account", + "auth_login_activation_after_signup": "Your account has been created. We've sent an activation link to your email address. Check your inbox and spam folder.", + "auth_login_activation_pending": "Your account isn't activated yet. We've sent an activation link to your email address. Check your inbox and spam folder. If nothing arrives, try logging in again later to get a new link.", + "auth_login_oauth_only": "This account has no password. Sign in with the provider you signed up with.", + "auth_login_oauth_only_with_buttons": "This account has no password. Sign in with the provider you signed up with using the buttons above.", + "auth_login_or_continue_with": "Or continue with", + "auth_login_username_label": "Username or Email", + "auth_login_password_label": "Password", + "auth_login_submit": "Login", + "auth_login_signup_prompt": "Don't have an account? Sign up", + "auth_login_legal": "By clicking Login, you agree to our Terms of Service and Privacy Policy.", + "auth_oauth_create_breadcrumb": "Sign Up With {{provider}}", + "auth_oauth_create_title": "Sign Up With {{provider}}", + "auth_oauth_create_description": "Complete your account details", + "auth_oauth_create_username_label": "Username", + "auth_oauth_create_username_placeholder": "Username", + "auth_oauth_create_email_label": "Email", + "auth_oauth_create_email_placeholder": "Email", + "auth_oauth_create_submit": "Sign Up", + "auth_oauth_create_legal": "By clicking Sign Up, you agree to our Terms of Service and Privacy Policy.", + "auth_oauth_error_breadcrumb": "Authentication Error", + "auth_oauth_error_title": "Authentication Error", + "auth_oauth_error_back": "Back to login", + "auth_reset_breadcrumb": "Reset Password", + "auth_reset_title": "Reset Password", + "auth_reset_checking": "Verifying reset link...", + "auth_reset_choose_password": "Choose a new password for your account", + "auth_reset_invalid": "This reset link is invalid or has expired", + "auth_reset_password_label": "New Password", + "auth_reset_password_placeholder": "New Password", + "auth_reset_confirm_label": "Confirm New Password", + "auth_reset_confirm_placeholder": "Confirm New Password", + "auth_reset_submit": "Reset Password", + "auth_reset_request_new": "Request a new reset link", + "auth_reset_toast_success": "Password has been reset", + "auth_signup_breadcrumb": "Sign Up", + "auth_signup_toast_created_mail": "Account created successfully. Please check your email to verify your account.", + "auth_signup_toast_created_no_mail": "Account created successfully. You can log in now.", + "auth_signup_dialog_title": "Welcome! Thank you for signing up! ❤️", + "auth_signup_dialog_created_mail": "Your account has been created. 🎉 Please check your email to verify your account.", + "auth_signup_dialog_verify_then_login": "After verifying your email, you can log in to your account.", + "auth_signup_dialog_created_no_mail": "Your account has been created and is ready to use. 🎉", + "auth_signup_dialog_login_now": "You can log in to your account now.", + "auth_signup_title": "Create your account", + "auth_signup_loading_methods": "Loading available sign-up methods", + "auth_signup_using_email": "Signing up using email", + "auth_signup_choose_method": "Choose your preferred sign-up method", + "auth_signup_back": "Back", + "auth_signup_username_label": "Username", + "auth_signup_username_placeholder": "John OpenShock", + "auth_signup_email_label": "Email", + "auth_signup_email_placeholder": "john@example.com", + "auth_signup_password_label": "Password", + "auth_signup_password_placeholder": "Password", + "auth_signup_confirm_label": "Confirm Password", + "auth_signup_confirm_placeholder": "Confirm Password", + "auth_signup_submit": "Create Account", + "auth_signup_signin_prompt": "Already have an account? Sign in", + "auth_signup_or": "Or", + "auth_signup_with_email": "Signup with Email", + "auth_signup_legal": "By clicking Create Account, you agree to our Terms of Service and Privacy Policy.", + "auth_verify_breadcrumb": "Verify Email", + "auth_verify_title": "Verify Email", + "auth_verify_verifying": "Verifying your email address...", + "auth_verify_success": "Your email has been verified", + "auth_verify_failed": "This verification link is invalid or has expired", + "auth_verify_missing_token": "Missing verification token", + "auth_verify_continue": "Continue to login", + "auth_verify_toast_success": "Email verified", + "common_cancel": "Cancel", + "common_delete": "Delete", + "common_edit": "Edit", + "common_share": "Share", + "common_copy_id": "Copy ID", + "common_id_copied": "ID copied to clipboard", + "common_open_menu": "Open menu", + "common_refresh": "Refresh", + "common_settings": "Settings", + "common_clear": "Clear", + "common_online": "Online", + "common_offline": "Offline", + "common_paused": "Paused", + "common_resume": "Resume", + "common_resuming": "Resuming...", + "common_coming_soon": "(Coming soon)", + "common_save_changes": "Save Changes", + "common_danger_zone": "Danger Zone", + "common_name": "Name", + "control_intensity": "Intensity", + "control_duration": "Duration", + "control_max_intensity": "Max Intensity", + "control_max_duration": "Max Duration", + "control_vibration": "Vibration", + "control_value": "Value", + "control_live_intensity": "Live intensity", + "control_type_stop": "Stop", + "control_type_shock": "Shock", + "control_type_vibrate": "Vibrate", + "control_type_sound": "Sound", + "live_tooltip_active": "Live via {{gateway}} ({{country}}), {{latency}}ms", + "live_tooltip_connecting": "Connecting...", + "live_tooltip_connect": "Connect to Live Control", + "live_tooltip_hub_start": "Ctrl+click to start the whole hub", + "live_tooltip_hub_stop": "Ctrl+click to stop the whole hub", + "pause_resume_shocker": "Resume shocker", + "pause_pause_shocker": "Pause shocker", + "pause_resume_all": "Resume all shockers", + "pause_pause_all": "Pause all shockers", + "shocker_label": "Shocker", + "shocker_hub": "Hub", + "shocker_select_hub": "Select hub", + "shocker_rf_id": "RF ID", + "shocker_rf_id_invalid": "RF ID must be a whole number between {{min}} and {{max}}.", + "shocker_model": "Model", + "shocker_select_model": "Select model", + "shocker_name_placeholder": "Shocker name", + "shocker_menu_view_logs": "View Logs", + "shocker_delete_title": "Delete Shocker", + "shocker_delete_desc": "Are you sure you want to delete \"{{name}}\"? This action cannot be undone.", + "shocker_toast_deleted": "Shocker \"{{name}}\" deleted", + "shocker_toast_paused": "Shocker paused", + "shocker_toast_resumed": "Shocker resumed", + "shocker_add_desc": "Register a new shocker to one of your hubs.", + "shocker_add_name_placeholder": "My Shocker", + "shockers_title": "Shockers", + "shockers_subtitle": "Every shocker paired to your hubs.", + "shockers_loading": "Loading shockers...", + "shockers_toast_refreshed": "Shockers refreshed", + "shockers_toast_need_hub": "You need to create a hub before adding shockers.", + "shockers_toast_added": "Shocker added", + "shockers_unknown_module": "Unknown module type", + "shockers_add": "Add Shocker", + "shockers_view_mode": "View mode", + "shockers_mode_classic": "Classic", + "shockers_mode_rich": "Rich", + "shockers_mode_simple": "Simple", + "shockers_mode_map": "Map", + "shockers_group_by_hub": "Group by Hub", + "shockers_global_limits": "Global Limits", + "shockers_logs_label": "Logs", + "shockers_empty_title": "No shockers yet", + "shockers_empty_no_hubs": "Create a hub first, then add shockers to it.", + "shockers_empty_has_hubs": "Add a shocker to one of your hubs to get started.", + "shockers_create_hub": "Create a Hub", + "shockers_count_one": "{{count}} shocker", + "shockers_count_other": "{{count}} shockers", + "shared_shockers_title": "Shared Shockers", + "shared_shockers_subtitle": "Shockers other users have shared with you.", + "shared_shockers_empty_title": "No shockers have been shared with you yet.", + "shared_shockers_empty_desc": "When someone shares their shockers with you, they'll appear here.", + "shocker_logs_title": "Shocker Logs", + "shocker_logs_subtitle": "Every control command sent to your shockers.", + "shocker_logs_live_title": "New logs appear in real time", + "shocker_logs_paused_title": "Live updates pause when sorting or viewing a page other than the first", + "shocker_logs_live": "Live", + "shocker_logs_col_time": "Time", + "shocker_logs_col_type": "Type", + "shocker_logs_col_by": "By", + "shocker_logs_filter_label": "Filter by shocker", + "shocker_logs_filter_placeholder": "Search shockers...", + "shocker_logs_filter_all": "All shockers", + "shocker_logs_filter_none": "No matching shockers", + "shocker_edit_title": "Edit Shocker", + "shocker_edit_subtitle": "Change this shocker's details or remove it.", + "shocker_edit_back": "Back to Shockers", + "shocker_edit_load_failed": "Failed to load shocker.", + "shocker_edit_loading": "Loading shocker...", + "shocker_edit_details_title": "Shocker Details", + "shocker_edit_details_desc": "Update the name, RF ID, and model for this shocker.", + "shocker_edit_pause_state": "Pause State", + "shocker_edit_is_paused": "Shocker is paused", + "shocker_edit_is_active": "Shocker is active", + "shocker_edit_toast_updated": "Shocker updated", + "shocker_edit_delete_desc": "Permanently delete this shocker. This action cannot be undone.", + "common_close": "Close", + "common_continue": "Continue", + "common_loading": "Loading...", + "common_previous": "Previous", + "common_next": "Next", + "common_steps": "Steps", + "common_step_label": "Step {{number}}: {{title}}", + "common_copy": "Copy", + "common_copied": "Copied", + "common_never": "Never", + "common_error": "Error: {{message}}", + "terminal_title": "Serial Terminal", + "terminal_connecting": "Connecting...", + "terminal_help_button": "I'm having trouble, help?", + "terminal_back_to_modes": "Back to mode picker", + "terminal_mode_configure": "Configure Device", + "terminal_mode_configure_desc": "Configure WiFi, authentication, and more. Includes an interactive serial console.", + "terminal_mode_flash": "Flash Firmware", + "terminal_mode_flash_desc": "Install or update firmware on a connected device.", + "terminal_mode_raw": "Serial Monitor", + "terminal_mode_raw_desc": "Just the console. Read device logs and send commands.", + "terminal_step_channel": "Select Channel", + "terminal_step_board": "Select Board", + "terminal_go_to_step": "Go to step {{number}}: {{title}}", + "terminal_erase": "Erase before flashing", + "terminal_erase_desc": "Clears all data on the device including existing configs", + "terminal_unsupported": "Your browser does not support this feature.", + "terminal_update_browser": "Please update your browser to the latest version.", + "terminal_use_browsers": "Please use one of the following browsers:", + "terminal_connect_failed_bootloader": "Could not enter bootloader mode", + "terminal_connect_failed": "Device connection failed", + "terminal_connect_failed_desc": "We couldn't establish a serial connection with the device.", + "terminal_quick_tries": "Quick things to try:", + "terminal_try_replug": "Unplug and replug the device.", + "terminal_try_cable": "Try a different USB cable or port.", + "terminal_try_driver": "Make sure the serial driver is installed.", + "terminal_open_troubleshooter": "Open troubleshooter", + "terminal_log_reset_no_device": "Host-side error during reset: no device!", + "terminal_log_reset_error": "Host-side error during reset: {{error}}", + "terminal_log_send_no_device": "Couldn't send: no device!", + "terminal_log_send_error": "Couldn't send: {{error}}", + "terminal_log_firmware_disconnected": "Firmware disconnected: {{error}}", + "terminal_log_erase_failed": "Failed to erase flash: {{error}}", + "terminal_log_hard_reset_failed": "Failed to hard reset: {{error}}", + "terminal_log_flash_complete": "Flash complete", + "terminal_log_flash_failed": "Failed to flash: {{error}}", + "terminal_log_command_failed": "Failed to write application command: {{error}}", + "terminal_help_title": "Troubleshooter", + "terminal_help_desc": "Work through these steps in order. Each one rules out a common cause.", + "terminal_help_step_cable": "USB cable", + "terminal_help_step_port": "USB port", + "terminal_help_step_driver": "Install driver", + "terminal_help_step_manual": "Manual driver update", + "terminal_help_step_discord": "Ask on Discord", + "terminal_help_cable_body": "Many USB-C and micro-USB cables are charge-only and don't carry data. Swap to a known-good data cable (one you've used to transfer files or connect other devices) and reconnect the hub.", + "terminal_help_port_body": "Plug the device directly into a USB port on your computer. Avoid USB hubs, docking stations, and front-panel ports if possible; these are common sources of power and signal issues. If you're on a desktop, try a port on the back of the machine.", + "terminal_help_driver_download": "Download the CP210x driver:", + "terminal_help_driver_extract": "Extract the contents of the zip file to a folder on your computer.", + "terminal_help_driver_run": "Open the folder and run {{installer}}. Follow the prompts to install.", + "terminal_help_driver_reconnect": "Reconnect the device.", + "terminal_help_manual_intro": "If the driver installer ran but the device still doesn't show up:", + "terminal_help_manual_open": "Open Device Manager (press Win + X and select Device Manager).", + "terminal_help_manual_ports": "Under Ports (COM & LPT), look for an entry like:", + "terminal_help_manual_missing": "If it's missing, the device isn't being detected by Windows at all; revisit the cable and port steps.", + "terminal_help_manual_update": "Right-click the device and pick Update Driver.", + "terminal_help_manual_browse": "Choose Browse my computer for drivers and select the folder you extracted the driver zip into. Make sure Include subfolders is checked.", + "terminal_help_manual_success": "On success, the entry should now read {{deviceName}}.", + "terminal_help_discord_intro": "Still stuck after all of the above? Hop into our Discord server and ask in the {{channel}} channel. Please include:", + "terminal_help_discord_os": "your operating system and browser", + "terminal_help_discord_device": "the device you're using (board model, where you got it)", + "terminal_help_discord_tried": "what you've already tried from the previous steps", + "terminal_help_discord_errors": "any error messages or relevant terminal output", + "terminal_help_discord_join": "Join our Discord server", + "terminal_risk_title": "⚠️ UNSTABLE FIRMWARE", + "terminal_risk_intro": "You are about to flash experimental firmware that is known to be unstable.", + "terminal_risk_brick": "This may permanently brick your device, require manual recovery, or render it unusable.", + "terminal_risk_no_support": "We will NOT provide support for issues caused by this firmware.", + "terminal_risk_acknowledge": "I understand this is entirely my responsibility", + "terminal_risk_abort": "Abort", + "terminal_risk_accept": "I ACCEPT FULL RESPONSIBILITY", + "firmware_channel_recommended": "This is the recommended channel.", + "firmware_channel_danger": "DO NOT USE THIS UNLESS YOU KNOW WHAT YOU ARE DOING", + "firmware_channel_stable": "Stable", + "firmware_channel_beta": "Beta", + "firmware_channel_develop": "Develop", + "terminal_board_select": "Select a board...", + "terminal_board_search": "Search boards...", + "terminal_board_none": "No board found.", + "terminal_flash_button": "Flash", + "terminal_flash_progress": "Flash Progress: {{status}}", + "terminal_flash_idle": "Idle", + "terminal_flash_no_device": "No device selected.", + "terminal_flash_resetting": "Resetting...", + "terminal_flash_downloading": "Downloading firmware...", + "terminal_flash_download_failed": "Failed to download firmware.", + "terminal_flash_flashing": "Flashing firmware...", + "terminal_flash_rebooting": "Rebooting device... (Reconnect to power manually if stuck)", + "terminal_flash_done": "Rebooted device! Flashing complete.", + "terminal_port_select": "Select Device", + "terminal_port_disconnect": "Disconnect Device", + "terminal_port_connected": "Device connected: {{id}}", + "terminal_console": "Console", + "terminal_connected_device": "Connected device", + "terminal_resize": "Resize terminal panel", + "terminal_reboot": "Reboot", + "terminal_disconnect": "Disconnect", + "terminal_fullscreen_exit_esc": "Exit fullscreen (Esc)", + "terminal_fullscreen_exit": "Exit fullscreen", + "terminal_fullscreen_fill": "Fill the window", + "terminal_command_label": "Serial command", + "terminal_command_placeholder": "Type a command...", + "terminal_command_send": "Send command", + "terminal_colors": "Colors", + "terminal_colors_menu": "Colors...", + "terminal_colors_label": "Console colors", + "terminal_colors_close": "Close colors", + "terminal_color_input": "{{name}} color", + "terminal_colors_reset": "Reset to defaults", + "terminal_color_bg": "Background", + "terminal_color_fg": "Text", + "terminal_color_ts": "Timestamp", + "terminal_color_error": "Error", + "terminal_color_warning": "Warning", + "terminal_color_info": "Info", + "terminal_color_debug": "Debug", + "terminal_color_verbose": "Verbose", + "terminal_options": "Options", + "terminal_options_label": "Console options", + "terminal_hide_system": "Hide system messages", + "terminal_stick_bottom": "Stick to bottom", + "terminal_raw_output": "Raw output", + "terminal_timestamps": "Timestamps", + "terminal_timestamp_uptime": "Uptime", + "terminal_timestamp_local": "Local", + "terminal_timestamp_ms": "Ms", + "terminal_timestamp_off": "Off", + "terminal_copy_settings": "Copy settings", + "terminal_import_settings": "Import settings", + "terminal_copy_selection": "Copy selection", + "terminal_copy_all": "Copy all output", + "terminal_toast_selection_copied": "Selection copied", + "terminal_toast_output_copied": "Console output copied", + "terminal_toast_settings_copied": "Console settings copied", + "terminal_toast_clipboard_unreadable": "Could not read the clipboard", + "terminal_toast_settings_imported": "Console settings imported", + "terminal_toast_settings_invalid": "Clipboard does not contain console settings", + "common_try_again": "Try again", + "terminal_cfg_intro": "Values are sent to the device via UART. Read the device's response in the console below. Commands without an argument act as getters; use the button next to each field to read the current value.", + "terminal_cfg_rf_title": "RF Transmitter", + "terminal_cfg_rf_desc": "Controls the shocker RF output.", + "terminal_cfg_tx_pin": "TX GPIO pin", + "terminal_cfg_example": "e.g. {{value}}", + "terminal_cfg_read_value": "Read current value", + "terminal_cfg_set": "Set", + "terminal_cfg_read": "Read", + "terminal_cfg_reading": "Reading…", + "terminal_cfg_apply": "Apply", + "terminal_cfg_keepalive": "Keepalive enabled", + "terminal_cfg_keepalive_desc": "Periodically pings paired shockers to keep them awake.", + "terminal_cfg_estop_title": "Emergency Stop", + "terminal_cfg_estop_desc": "Hardware button that halts all output.", + "terminal_cfg_estop_enabled": "EStop enabled", + "terminal_cfg_estop_pin": "EStop GPIO pin", + "terminal_cfg_estop_note": "Note: {{latching}} and {{active}} have no dedicated commands; set them via the JSON config below.", + "terminal_cfg_wifi_title": "WiFi", + "terminal_cfg_wifi_desc": "Station credentials and device hostname.", + "terminal_cfg_hostname": "Hostname", + "terminal_cfg_networks": "Networks (JSON array)", + "terminal_cfg_invalid_json_array": "Must be a valid JSON array", + "terminal_cfg_ap_note": "AP settings ({{ssid}}, {{password}}, {{disabled}}, {{staDisabled}}, {{offlineMode}}) have no dedicated commands; use the JSON config.", + "terminal_cfg_backend_title": "Backend", + "terminal_cfg_backend_desc": "OpenShock server and authentication.", + "terminal_cfg_domain": "Domain", + "terminal_cfg_domain_restart": "Setting the domain will restart the device.", + "terminal_cfg_auth_token": "Auth token", + "terminal_cfg_auth_token_placeholder": "Paste device token", + "terminal_cfg_hide": "Hide", + "terminal_cfg_show": "Show", + "terminal_cfg_serial_title": "Serial Input", + "terminal_cfg_echo": "Echo enabled", + "terminal_cfg_echo_desc": "Print typed characters back to the console.", + "terminal_cfg_advanced_title": "Advanced: full config", + "terminal_cfg_advanced_desc": "For fields without dedicated commands (captive portal, OTA, LAN, etc.), replace the entire config.", + "terminal_cfg_json_config": "JSON config", + "terminal_cfg_invalid_json": "Must be valid JSON", + "terminal_cfg_read_json": "Read current config as JSON", + "terminal_cfg_json_restart": "Applying a JSON config will restart the device.", + "terminal_cfg_raw_config": "Raw FlatBuffer config (base64)", + "terminal_cfg_invalid_base64": "Must be a valid base64 string", + "terminal_cfg_read_raw": "Read current config as base64", + "terminal_cfg_factory_reset": "Factory reset", + "terminal_cfg_factory_reset_desc": "Wipes the entire device configuration.", + "terminal_cfg_factory_reset_title": "Factory reset device?", + "terminal_cfg_factory_reset_action": "Wipe config", + "terminal_cfg_factory_reset_confirm": "This will erase all configuration on the device; WiFi networks, backend credentials, pins, and all other settings. The device will be reset to defaults.", + "terminal_cfg_read_failed_json_title": "Couldn't read the JSON config", + "terminal_cfg_read_failed_raw_title": "Couldn't read the raw config", + "terminal_cfg_read_failed_desc": "The device didn't respond after {{attempts}} attempts.", + "terminal_cfg_common_causes": "Common causes:", + "terminal_cfg_cause_busy": "The device is busy handling another command.", + "terminal_cfg_cause_disconnected": "The device disconnected or rebooted.", + "terminal_cfg_cause_unsupported": "The firmware version doesn't support this command.", + "common_status": "Status", + "common_version": "Version", + "common_created": "Created", + "common_create": "Create", + "common_done": "Done", + "common_enable": "Enable", + "common_disable": "Disable", + "common_are_you_sure": "Are you sure?", + "common_generating": "Generating...", + "hubs_title": "Hubs", + "hubs_subtitle": "Every hub registered to your account.", + "hubs_add": "Add Hub", + "hubs_load_failed": "Failed to load hubs.", + "hubs_empty_title": "No hubs yet", + "hubs_empty_desc": "A hub is the device that relays commands to your shockers. Add one to get started.", + "hubs_create_title": "Create hub", + "hubs_name_label": "Hub Name", + "hubs_name_placeholder": "My Hub", + "hub_toast_not_connected": "Not connected to the server", + "hub_toast_try_later": "Try again in a moment.", + "hub_reboot_title": "Reboot {{name}}?", + "hub_reboot_desc": "The hub will disconnect and restart. Any shockers paired to it stop responding until it comes back online.", + "hub_reboot": "Reboot", + "hub_hotspot_enable_title": "Enable Wi-Fi hotspot on {{name}}?", + "hub_hotspot_disable_title": "Disable Wi-Fi hotspot on {{name}}?", + "hub_hotspot_enable_desc": "The hub broadcasts its own setup network. It stays reachable on your Wi-Fi, but the hotspot is open to anyone in range until you turn it off.", + "hub_hotspot_disable_desc": "The setup hotspot shuts down. If the hub is not already on your Wi-Fi you will need physical access to set it up again.", + "hub_delete_desc": "You are about to delete hub {{name}}.", + "hub_delete_shockers": "This will also delete the following shockers:", + "hub_edit_title": "Edit hub", + "hub_edit_apply": "Apply", + "hub_pair_title_generate": "Generate pair code?", + "hub_pair_title_generated": "Pair code generated", + "hub_pair_title_paired": "Hub paired", + "hub_pair_consumed": "{{name}} consumed this pair code and is now paired.", + "hub_pair_used": "The code has been used and is no longer valid.", + "hub_pair_generated_for": "Pair code generated for {{name}}.", + "hub_copy_now": "The code below will not be accessible later, please copy it now and update clients with it.", + "hub_pair_generate_for": "You are about to generate a pair code for {{name}}.", + "hub_pair_valid_for": "It will be valid for 15 minutes after its creation.", + "hub_pair_one_active": "There is only one active pair code per hub, newly generated ones will override the older active ones.", + "hub_pair_complete": "Pairing complete", + "hub_pair_code_label": "Pair code:", + "hub_pair_copied_close": "Code has been copied, close", + "hub_pair_get": "Get Pair Code", + "hub_token_generated": "Token generated", + "hub_token_generated_for": "New token generated for {{name}}.", + "hub_token_regenerate_for": "You are about to regenerate the token for {{name}}.", + "hub_token_invalidate": "This action will invalidate the current token and disconnect clients using it.", + "hub_token_confirm": "Are you sure you want to do this?", + "hub_token_label": "New token:", + "hub_token_copied_close": "Token has been copied, close", + "hub_token_regenerate": "Regenerate Token", + "hub_menu_update": "Update", + "hub_menu_label": "Hub", + "hub_menu_hotspot_enable": "Enable Wi-Fi hotspot", + "hub_menu_hotspot_disable": "Disable Wi-Fi hotspot", + "hub_menu_pair": "Pair", + "hub_menu_estop": "Emergency Stop", + "hub_update_breadcrumb": "Update", + "hub_update_unknown_hub": "Unknown Hub", + "hub_update_unknown_task": "Unknown Task", + "hub_update_task_metadata": "Fetching Metadata", + "hub_update_task_preparing": "Preparing for Update", + "hub_update_task_flash_fs": "Flashing Filesystem", + "hub_update_task_verify_fs": "Verifying Filesystem", + "hub_update_task_flash_app": "Flashing Application", + "hub_update_task_bootable": "Marking Application Bootable", + "hub_update_task_rebooting": "Rebooting", + "hub_update_status_started": "Started", + "hub_update_status_running": "Running", + "hub_update_status_finished": "Finished", + "hub_update_status_error": "Error", + "hub_update_status_timeout": "Timeout", + "hub_update_confirm_title": "Confirm firmware update", + "hub_update_confirm_desc": "Update {{name}} to version {{version}}?", + "hub_update_unstable_warning": "This version may not be from the stable channel and could contain bugs.", + "hub_update_title": "Update {{name}}", + "hub_update_subtitle": "Manage firmware updates for this hub.", + "hub_update_status_title": "Hub Status", + "hub_update_firmware": "Firmware: {{version}}", + "hub_update_confirm": "Update", + "hub_update_success": "Update completed successfully", + "hub_update_rolled_back": "Device rolled back to previous version", + "hub_update_back": "Back to Hubs", + "hub_update_flash_again": "Flash Again", + "hub_update_card_title": "Firmware Update", + "hub_update_card_desc": "Select a firmware channel and version to install.", + "hub_update_to": "Update to {{version}}", + "hub_update_must_be_online": "Hub must be online to start an update.", + "hub_update_updating_to": "Updating to {{version}}...", + "hub_update_total": "Total", + "hub_update_task": "Task", + "hub_update_history": "Update History", + "hub_update_no_history": "No update history found for this hub.", + "hub_update_col_id": "ID", + "hub_update_col_started": "Started", + "hub_update_col_message": "Message", + "hub_update_loading": "Loading hub information...", + "hub_update_not_found": "Hub not found.", + "home_breadcrumb": "Home", + "home_welcome": "Welcome back", + "home_welcome_name": "Welcome back, {{name}}", + "home_subtitle": "Here's an overview of your OpenShock setup.", + "home_hubs_online": "{{count}} online", + "home_hub_status": "Hub Status", + "home_no_hubs": "No hubs", + "home_all_online": "All online", + "home_all_offline": "All offline", + "home_some_online": "{{online}}/{{total}} online", + "home_quick_links": "Quick Links", + "home_my_shockers": "My Shockers", + "home_my_shockers_desc": "Control your shockers", + "home_hubs_desc": "Manage your hubs", + "home_shared_desc": "Shockers shared with you", + "home_public_desc": "Manage share links", + "home_get_started": "Get Started", + "home_get_started_desc": "You don't have any hubs yet. Create a hub to connect your first device, then add shockers to it.", + "home_set_up_hub": "Set Up a Hub", + "home_first_shocker": "Add Your First Shocker", + "home_first_shocker_desc_one": "You have {{count}} hub set up. Add a shocker to start controlling it.", + "home_first_shocker_desc_other": "You have {{count}} hubs set up. Add a shocker to start controlling it.", + "home_go_to_shockers": "Go to Shockers", + "profile_title": "Profile", + "profile_coming_soon": "Profile is coming soon", + "profile_coming_soon_desc": "Your public profile is not available yet. Account details live under Settings.", + "common_retry": "Retry", + "common_never_used": "Never used", + "common_expires": "Expires {{time}}", + "common_search_placeholder": "Search...", + "common_unknown": "Unknown", + "settings_breadcrumb_account": "Account", + "account_subtitle": "Your sign-in details and account actions.", + "account_change_username": "Change Username", + "account_change_email": "Change Email", + "account_change_password": "Change Password", + "account_username_label": "Username", + "account_email_label": "Email", + "account_password_label": "Password", + "account_new_password_label": "New Password", + "account_confirm_password_label": "Confirm New Password", + "account_oauth_only": "Not available for OAuth-only accounts", + "account_oauth_no_password": "This account signs in via OAuth and has no password.", + "account_diagnostics": "Diagnostics", + "account_diagnostics_desc": "Help us fix crashes and slow API calls. Reports include the error message, stack trace and your IP. Off by default.", + "account_diagnostics_level": "Diagnostics level", + "account_telemetry_off": "Off", + "account_telemetry_off_desc": "Send nothing.", + "account_telemetry_errors": "Errors", + "account_telemetry_errors_desc": "Send browser error reports only.", + "account_telemetry_full": "Full", + "account_telemetry_full_desc": "Error reports plus traces of API calls (no page navigations).", + "account_toast_deactivated": "Account deactivated successfully", + "account_deactivate_title": "Deactivate account", + "account_deactivate_desc": "Are you sure you want to deactivate your account?", + "account_deactivate": "Deactivate Account", + "account_email_title": "Change email", + "account_email_desc": "Enter your new email address and confirm with your current password.", + "account_email_toast_sent": "Verification email sent to {{email}}. Click the link in that email to apply the change.", + "account_new_email": "New Email", + "account_current_password": "Current Password", + "account_password_title": "Change password", + "account_password_desc": "Enter your current password and choose a new one.", + "account_password_toast": "Password has been changed", + "account_username_title": "Change username", + "account_username_desc": "Enter a new username.", + "account_new_username": "New Username", + "account_username_toast": "Username changed successfully", + "tokens_subtitle": "API Tokens are used to authenticate with the OpenShock API.", + "tokens_generate": "Generate Token", + "tokens_toast_refreshed": "Tokens refreshed successfully", + "tokens_empty_title": "No API tokens", + "tokens_empty_desc": "Generate a token to authenticate with the OpenShock API.", + "tokens_created_on": "Created {{date}}", + "tokens_last_used": "Last used {{time}}", + "tokens_never_expires": "Never expires", + "tokens_load_failed": "Failed to load API tokens.", + "token_toast_edited": "Token edited successfully", + "token_name_required": "Name is required", + "token_name_too_long": "Name is too long", + "token_edit_title": "Edit API token", + "token_name_label": "Token Name", + "token_name_placeholder": "Token name...", + "token_permissions": "Permissions", + "token_perm_category_shockers": "Shockers", + "token_perm_category_devices": "Hubs", + "token_perm_category_usershares": "User Shares", + "token_perm_category_publicshares": "Public Shares", + "token_perm_use": "Use", + "token_perm_edit": "Edit", + "token_perm_pause": "Pause", + "token_perm_auth": "Authenticate", + "token_shocker_control": "Shocker Control", + "token_toast_paused": "Token paused", + "token_toast_resumed": "Token resumed", + "token_delete_title": "Delete API token", + "token_delete_desc": "Are you sure you want to delete {{name}}?", + "token_delete_permanent": "This action cannot be undone. This will permanently delete the token.", + "token_toast_deleted": "Token deleted successfully", + "token_resume": "Resume token", + "token_pause": "Pause token", + "token_mode_clamp_desc": "Clamp: requests outside the allowed range are capped to the nearest limit (the min or the max).", + "token_mode_lerp_desc": "Lerp: the full input range is linearly rescaled so it fits within your allowed min–max range.", + "token_paused_desc": "A paused token may not send shocker control messages.", + "token_intensity_range": "Intensity range", + "token_duration_range": "Duration range", + "token_new_breadcrumb": "New", + "token_redirect_not_allowed": "The provided redirect_uri is not allowed. Only loopback addresses or custom application schemes are permitted.", + "token_params_missing": "Required get parameters are missing. Make sure name, redirect_uri, and permissions are provided.", + "token_invalid_permissions": "Invalid permissions provided: {{list}}", + "token_toast_created": "Token created successfully", + "token_request_title": "API Token Request", + "token_access_granted": "Access granted", + "token_shared_redirecting": "The token has been created and shared with the application. Redirecting you back to {{uri}}.", + "token_not_redirected": "If you are not redirected automatically, use the button below.", + "token_finish": "Finish", + "token_generated_title": "API Token Generated", + "token_copy_now": "Please copy your API Token now, you will not be able to view it again later!", + "token_new_title": "New API Token", + "token_external_desc": "An external application is requesting access to your account. Review and adjust the permissions below before allowing access.", + "token_new_desc": "Configure and generate a new API token for your account.", + "token_external_requesting": "{{name}} is requesting an API Token. Your token will be shared with the application at {{uri}}.", + "token_allow": "Allow", + "token_generate": "Generate", + "token_deny": "Deny", + "sessions_subtitle": "Every active session on your account. Revoke any you do not recognize.", + "sessions_unknown_device": "Unknown device", + "sessions_toast_refreshed": "Sessions refreshed successfully", + "sessions_load_failed": "Failed to load sessions.", + "sessions_empty_title": "No active sessions", + "sessions_empty_desc": "Sessions appear here once you sign in from a browser or app.", + "sessions_last_seen": "Last seen {{time}}", + "sessions_signed_in": "Signed in {{time}}", + "session_toast_revoked": "Session revoked successfully", + "session_revoke_title": "Revoke session", + "session_revoke": "Revoke", + "session_revoke_desc": "Are you sure you want to revoke this session?", + "session_revoke_from": "Session logged in from {{ip}} using {{agent}}", + "connections_title": "OAuth Connections", + "connections_subtitle": "Link or unlink third-party accounts to sign in faster and keep your profile in sync.", + "connections_toast_linked": "Account linked.", + "connections_toast_cancelled": "Link flow cancelled.", + "connections_toast_failed": "Linking failed.", + "connections_toast_removed": "Connection removed", + "connections_refreshing": "Refreshing…", + "connections_link_new": "Link new provider", + "connections_empty_title": "No connections yet", + "connections_empty_desc": "Choose “Link new provider” above to connect available providers.", + "connections_unlink": "Unlink", + "connections_load_failed": "Failed to load OAuth connections.", + "connections_unlink_title": "Unlink {{name}}?", + "connections_unlink_title_generic": "Unlink this account?", + "connections_unlink_desc": "You'll no longer be able to sign in with this provider unless you link it again.", + "provider_starting": "Starting {{name}}...", + "provider_link": "Link {{name}}", + "audit_subtitle": "Security-relevant activity on your account. Review anything you do not recognize.", + "audit_col_time": "Time", + "audit_col_action": "Action", + "audit_col_details": "Details", + "audit_col_reason": "Reason", + "audit_col_ip": "IP address", + "audit_col_device": "Device", + "audit_action_login": "Signed in", + "audit_action_logout": "Signed out", + "audit_action_password_changed": "Password changed", + "audit_action_email_change_requested": "Email change requested", + "audit_action_email_changed": "Email changed", + "audit_action_username_changed": "Username changed", + "audit_action_api_token_created": "API token created", + "audit_action_api_token_deleted": "API token deleted", + "audit_action_oauth_connected": "Connection added", + "audit_action_oauth_disconnected": "Connection removed", + "audit_action_account_deactivated": "Account deactivated", + "audit_action_account_reactivated": "Account reactivated", + "audit_action_account_deleted": "Account deleted", + "audit_action_automation_token_created": "Automation token created", + "audit_action_automation_token_updated": "Automation token updated", + "audit_action_automation_token_rotated": "Automation token rotated", + "audit_action_automation_token_deleted": "Automation token deleted", + "audit_action_automation_token_used": "Automation token used", + "audit_meta_session": "Session {{id}}", + "audit_meta_changed": "{{old}} to {{new}}", + "audit_meta_email_requested": "Requested change to {{email}}", + "audit_meta_accounts_removed_one": "{{name}} ({{count}} account removed)", + "audit_meta_accounts_removed_other": "{{name}} ({{count}} accounts removed)", + "audit_meta_scheduled_deletion": "Scheduled for deletion", + "audit_meta_kept": "Kept for reactivation", + "common_view": "View", + "common_save": "Save", + "common_saving": "Saving...", + "common_back": "Back", + "common_shared_by": "Shared by", + "common_user_avatar": "User Avatar", + "common_toast_saved": "Changes saved successfully", + "pause_reason_shocker": "Paused at shocker level", + "pause_reason_shocker_user_share": "Paused at shocker and user share level", + "pause_reason_shocker_public_share": "Paused at shocker and public share level", + "pause_reason_user_share": "Paused at user share level", + "pause_reason_public_share": "Paused at public share level", + "public_shares_subtitle": "A link anyone can use, no account required.", + "public_shares_new": "New Share", + "public_share_never_expires": "Never expires", + "public_shares_empty_title": "No public shares yet", + "public_shares_empty_desc": "Create a link that anyone can use to control your shockers.", + "public_share_expired": "Expired", + "public_share_no_expiry": "No expiry", + "public_share_label": "Public Share", + "public_share_toast_created": "Created new public share", + "public_share_create_title": "Create public share", + "public_share_toast_deleted": "Deleted public share", + "public_share_delete_title": "Delete public share", + "public_share_delete_desc": "Are you sure you want to delete public share {{name}}?", + "public_share_edit_title": "Public Share: {{name}}", + "public_share_edit_subtitle": "Editing: changes apply when you save.", + "public_share_add_shocker": "Add Shocker", + "public_share_toast_added_one": "Added {{count}} shocker to share", + "public_share_toast_added_other": "Added {{count}} shockers to share", + "public_share_empty_shockers_title": "No shockers in this share", + "public_share_empty_shockers_desc": "Add a shocker and anyone with the link will be able to control it.", + "public_share_load_failed": "Error fetching public share details", + "public_share_paused_here": "Paused for this share", + "public_share_resume_shocker": "Resume shocker", + "public_share_pause_shocker": "Pause shocker", + "public_share_remove": "Remove from share", + "public_share_toast_removed": "Shocker removed from share", + "public_share_add_title": "Add shockers", + "public_share_add_desc": "Add shockers to this public share. You can set their limits once they are added.", + "public_share_add_placeholder": "Select shockers to share...", + "public_share_add_no_match": "No matching shockers", + "public_share_add_submit": "Add Shockers", + "public_share_view_loading": "Loading share details...", + "public_share_view_title": "Public Share Link", + "public_share_view_desc": "Enter as a guest or login with your OpenShock account", + "public_share_view_guest_name": "Guest Name", + "public_share_view_enter": "Enter", + "public_share_view_enter_guest": "Enter as Guest", + "public_share_login": "Login", + "perm_shock_on": "Shock enabled", + "perm_shock_off": "Shock disabled", + "perm_vibrate_on": "Vibrate enabled", + "perm_vibrate_off": "Vibrate disabled", + "perm_sound_on": "Sound enabled", + "perm_sound_off": "Sound disabled", + "perm_live_on": "Live enabled", + "perm_live_off": "Live disabled", + "perm_live_control": "Live Control", + "user_selector_avatar_of": "{{name}}'s avatar", + "user_selector_placeholder": "Enter user name", + "user_selector_aria": "Username to search", + "user_selector_search": "Search user", + "user_selector_found": "User found", + "common_remove": "Remove", + "user_shares_subtitle": "Direct permanent shares with other users.", + "user_shares_toast_invited": "Sent a shocker invite to {{name}}", + "user_shares_redeem": "Redeem Code", + "user_shares_new": "New Share", + "user_shares_tab_shares": "Shares", + "user_shares_tab_incoming": "Shared with Me", + "user_shares_tab_invites": "Invites", + "share_code_create_title": "New share code", + "share_code_create_desc": "Create a Share Code or Invite", + "share_code_shocker_placeholder": "Select shockers to share...", + "share_code_no_match": "No matching shockers", + "share_code_send_invite": "Send Share Invite", + "share_code_create": "Create Share Code", + "share_code_created_title": "Share code generated", + "share_code_created_desc": "Please copy share code or code link!", + "share_code_redeem_title": "Redeem share code", + "share_code_redeem_desc": "Enter the share code to redeem", + "share_code_redeem_placeholder": "Enter share code", + "share_code_redeemed": "Redeemed successfully!", + "share_code_shared_shockers": "Shared shockers", + "share_code_redeeming": "Redeeming...", + "share_code_redeem": "Redeem", + "incoming_shares_empty_title": "Nothing shared with you", + "incoming_shares_empty_desc": "No one has shared a shocker with you yet.", + "incoming_share_toast_removed": "Removed share for {{name}}", + "incoming_share_remove_title": "Remove Share", + "incoming_share_remove_desc": "Are you sure you want to remove the share for {{name}}?", + "incoming_share_toast_removed_shocker": "Removed {{shocker}} shared by {{name}}", + "incoming_share_remove_shocker_title": "Remove this shared shocker?", + "incoming_share_remove_shocker_desc": "Are you sure you want to remove the shocker share {{shocker}} by {{name}}?", + "incoming_share_manage_from": "Manage shares from", + "share_remove": "Remove share", + "invites_empty_title": "No invites yet", + "invites_empty_desc": "You have no incoming or outgoing share invites.", + "invites_outgoing": "Outgoing", + "invites_outgoing_empty_title": "No outgoing invites", + "invites_outgoing_empty_desc": "You have no outgoing share invites.", + "invites_incoming": "Incoming", + "invites_incoming_empty_title": "No incoming invites", + "invites_incoming_empty_desc": "You have no incoming share invites.", + "invite_toast_accepted": "Accepted share invite from {{name}}", + "invite_toast_declined": "Declined share invite from {{name}}", + "invite_deny_title": "Deny Invite", + "invite_deny_label": "Deny Invite", + "invite_deny": "Deny", + "invite_deny_desc": "Are you sure you want to deny the invite from {{name}}?", + "invite_accept": "Accept Invite", + "invite_toast_cancelled_for": "Cancelled invite for {{name}} ({{id}})", + "invite_toast_cancelled": "Cancelled invite {{id}}", + "invite_cancel_title": "Cancel Invite", + "invite_cancel": "Cancel", + "invite_cancel_for_desc": "Are you sure you want to cancel the invite for {{name}}?", + "invite_cancel_code_desc": "Are you sure you want to cancel the invite with code {{code}}?", + "invite_cancel_outstanding": "Cancel Outstanding Invite", + "outgoing_shares_empty_title": "No shared shockers", + "outgoing_shares_empty_desc": "You haven't shared any shockers with other users yet.", + "outgoing_share_toast_removed": "Removed shocker share {{name}}", + "outgoing_share_remove_title": "Stop sharing this shocker?", + "outgoing_share_editing_for": "Editing shares for", + "outgoing_share_limits": "Limits & Permissions", + "outgoing_share_same": "Same restrictions on every shocker", + "outgoing_share_per_desc": "Tune restrictions per shocker", + "outgoing_share_all": "All", + "outgoing_share_per": "Per shocker", + "outgoing_share_remove_desc": "Are you sure you want to stop sharing {{shocker}} with {{name}}?", + "report_breadcrumb": "Report API Tokens", + "report_toast_clipboard_failed": "Failed to read clipboard: {{error}}", + "report_title": "Report Leaked API Tokens", + "report_paste": "Paste from clipboard", + "report_warning": "This form is only for reporting accidentally leaked API tokens.", + "report_abuse_warning": "Intentional abuse will result in bans or severe endpoint restrictions.", + "report_detected": "Detected Tokens", + "report_invalid": "One or more tokens appear to be invalid. Please check for formatting issues.", + "report_acknowledge": "I confirm I understand what this feature is for and accept responsibility.", + "report_submit": "Submit Report", + "turnstile_disabled": "Turnstile disabled", + "common_internal_error": "Internal error", + "resend_toast_sent": "Activation email sent. Check your inbox and spam folder.", + "resend_toast_throttled": "Too many activation emails have been requested. Please try again later.", + "resend_toast_unavailable": "No activation email can be resent from this browser. If your account isn't activated yet, logging in sends a new link.", + "resend_button": "Didn't get the email? Resend", + "expiration_label": "Expiration", + "expiration_never": "Never", + "expiration_custom": "Custom", + "expiration_days_one": "{{count}} Day", + "expiration_days_other": "{{count}} Days", + "expiration_required": "Expire date is required", + "expiration_never_desc": "This will never expire", + "expiration_expires_at": "Expires {{time}} ({{date}})", + "date_picker_placeholder": "Pick a date", + "telemetry_toast_title": "Help improve OpenShock?", + "telemetry_toast_desc": "Send diagnostics to help us fix crashes and slow API calls. Reports include the error message, stack trace and your IP. You can change this any time in Account settings.", + "telemetry_toast_no": "No thanks", + "telemetry_toast_errors": "Errors only", + "telemetry_toast_full": "Full", + "table_show_details": "Show details", + "table_hide_details": "Hide details", + "table_no_results": "No results.", + "table_sort_asc": "Sort by {{name}}, ascending", + "table_sort_desc": "Sort by {{name}}, descending", + "table_sort_none": "Sort by {{name}}, unsorted", + "cell_na": "N/A", + "cell_not_applicable": "Not applicable", + "cell_invalid": "Invalid", + "cell_unavailable": "Unavailable", + "cell_none": "None", + "oauth_login_with": "Login with {{provider}}", + "oauth_signup_with": "Signup with {{provider}}", + "signalr_connect_failed": "Failed to connect to server!", + "signalr_disconnect_failed": "Encountered error while disconnecting from server!", + "signalr_invalid_update": "Received invalid update from server!", + "signalr_invalid_log": "Received invalid log data from server!", + "signalr_invalid_ota": "Received invalid firmware update data from server!", + "ota_toast_failed": "Hub firmware update failed: {{message}}", + "ota_toast_succeeded": "Hub firmware update completed successfully!", + "ota_toast_rolled_back": "Hub firmware rolled back to previous version", + "lcg_connect_failed": "Failed to connect to live control gateway", + "terminal_toast_bootloader_failed": "Failed to enter bootloader: {{error}}", + "terminal_toast_app_mode_failed": "Failed to enter application mode: {{error}}", + "problem_account_account_not_activated_title": "Account not activated", + "problem_account_account_not_activated_desc": "Check your inbox for the activation email.", + "problem_account_activation_not_found_title": "Activation link is invalid", + "problem_account_activation_not_found_desc": "The link may have expired or already been used.", + "problem_account_activation_resend_too_many_title": "Too many activation emails requested", + "problem_account_activation_resend_too_many_desc": "Please wait a while before trying again.", + "problem_account_activation_resend_unavailable_title": "Cannot resend activation email", + "problem_account_activation_resend_unavailable_desc": "Log in again to request a new activation link.", + "problem_account_deactivate_already_deactivated_title": "Account is already deactivated", + "problem_account_deactivate_denied_privileged_title": "Privileged accounts cannot be deactivated", + "problem_account_deactivate_unauthorized_title": "You are not allowed to do this", + "problem_account_deactivated_title": "This account has been deactivated", + "problem_account_email_already_in_use_title": "That email address is already in use", + "problem_account_email_invalid_title": "That email address is not valid", + "problem_account_email_taken_title": "That email address is already in use", + "problem_account_email_too_many_requests_title": "Too many email change requests", + "problem_account_email_too_many_requests_desc": "Please wait a while before trying again.", + "problem_account_email_unchanged_title": "That is already your email address", + "problem_account_email_verify_not_found_title": "Verification link is invalid", + "problem_account_email_verify_not_found_desc": "The link may have expired or already been used.", + "problem_account_o_auth_only_title": "This account has no password", + "problem_account_o_auth_only_desc": "Sign in with the provider you signed up with.", + "problem_account_password_not_set_title": "No password set", + "problem_account_password_not_set_desc": "This account signs in through an external provider.", + "problem_account_password_old_password_invalid_title": "Current password is incorrect", + "problem_account_username_invalid_title": "That username is not allowed", + "problem_account_username_recently_changed_title": "Username changed too recently", + "problem_account_username_recently_changed_desc": "You can change your username once every 7 days.", + "problem_account_username_taken_title": "That username is already taken", + "problem_admin_user_deactivated_title": "This user is deactivated", + "problem_admin_user_not_activated_title": "This user has not been activated yet", + "problem_api_token_can_only_delete_self_title": "An API token can only delete itself", + "problem_api_token_not_found_title": "API token not found", + "problem_api_token_paused_title": "This API token is paused", + "problem_assign_lcg_bad_schema_version_title": "Unsupported hub protocol version", + "problem_assign_lcg_bad_schema_version_desc": "Update the hub firmware to connect.", + "problem_assign_lcg_no_lcg_available_title": "No gateway available", + "problem_assign_lcg_no_lcg_available_desc": "No live control gateway is available right now. Please try again later.", + "problem_authentication_account_deactivated_title": "This account has been deactivated", + "problem_authentication_account_not_activated_title": "This account has not been activated", + "problem_authentication_cookie_missing_or_invalid_title": "You are not logged in", + "problem_authentication_cookie_missing_or_invalid_desc": "Your session may have expired. Please log in again.", + "problem_authentication_header_missing_or_invalid_title": "Invalid API token", + "problem_authentication_session_invalid_title": "Session expired", + "problem_authentication_session_invalid_desc": "Please log in again.", + "problem_authentication_token_invalid_title": "Invalid API token", + "problem_authentication_unknown_error_title": "Authentication failed", + "problem_authorization_policy_not_met_title": "You do not have permission to do this", + "problem_authorization_token_only_title": "This action requires an API token", + "problem_authorization_token_permission_missing_title": "This API token is missing a required permission", + "problem_authorization_unknown_error_title": "Authorization failed", + "problem_authorization_user_session_only_title": "This action requires a logged-in session", + "problem_automation_token_not_allowed_for_account_title": "Automation tokens cannot be used with privileged accounts", + "problem_configuration_already_exists_title": "A configuration entry with that name already exists", + "problem_configuration_invalid_name_format_title": "Invalid configuration name", + "problem_configuration_invalid_name_format_desc": "Only A to Z and underscores are allowed.", + "problem_configuration_invalid_value_format_title": "Value does not match the configuration type", + "problem_configuration_not_found_title": "Configuration entry not found", + "problem_control_stats_invalid_range_title": "The from date must not be after the to date", + "problem_control_stats_invalid_time_zone_title": "Unknown time zone", + "problem_control_stats_missing_capability_title": "Control statistics are not available on this server", + "problem_device_not_found_title": "Hub not found", + "problem_device_not_online_title": "Hub is offline", + "problem_device_too_many_hubs_title": "You have reached the maximum number of hubs", + "problem_device_too_many_shockers_title": "This hub has reached its maximum number of shockers", + "problem_endpoint_retired_title": "This feature is no longer available", + "problem_expression_error_title": "Invalid filter expression", + "problem_internal_server_error_title": "Something went wrong on our end", + "problem_login_invalid_credentials_title": "Invalid username or password", + "problem_login_invalid_domain_title": "Logging in from this address is not allowed", + "problem_o_auth_connection_already_exists_title": "Your account is already connected to this provider", + "problem_o_auth_connection_already_linked_title": "This external account is already linked to another user", + "problem_o_auth_flow_anonymous_only_title": "You are already signed in", + "problem_o_auth_flow_mismatch_title": "Sign-in attempt does not match", + "problem_o_auth_flow_mismatch_desc": "Please start over.", + "problem_o_auth_flow_missing_data_title": "The provider did not return your account details", + "problem_o_auth_flow_missing_data_desc": "Please try again.", + "problem_o_auth_flow_not_found_title": "Sign-in attempt expired", + "problem_o_auth_flow_not_found_desc": "Please start over.", + "problem_o_auth_flow_unsupported_title": "Unsupported sign-in flow", + "problem_o_auth_internal_error_title": "Something went wrong during sign-in", + "problem_o_auth_internal_error_desc": "Please try again in a moment.", + "problem_o_auth_link_authenticated_user_only_title": "You must be signed in to link an external account", + "problem_o_auth_provider_mismatch_title": "Sign-in attempt does not match the provider", + "problem_o_auth_provider_mismatch_desc": "Please start over.", + "problem_o_auth_provider_unsupported_title": "This sign-in provider is not supported", + "problem_pair_code_not_found_title": "Pair code not found", + "problem_password_reset_not_found_title": "Password reset link is invalid", + "problem_password_reset_not_found_desc": "The link may have expired or already been used.", + "problem_session_not_found_title": "Session not found", + "problem_share_get_no_shares_title": "You have no shares with this user", + "problem_share_request_create_cannot_share_with_self_title": "You cannot share with yourself", + "problem_share_request_create_shocker_not_found_title": "One or more shockers were not found", + "problem_share_request_create_shocker_not_found_desc": "They may have been removed or do not belong to you.", + "problem_share_request_not_found_title": "Share invite not found", + "problem_share_user_not_found_title": "Share not found", + "problem_share_code_already_linked_title": "Shocker is already linked to your account", + "problem_share_code_cant_link_own_share_code_title": "You cannot redeem your own share code", + "problem_share_code_not_found_title": "Share code not found", + "problem_share_link_expiry_date_in_past_title": "Expiry date cannot be in the past", + "problem_share_link_not_found_title": "Public share not found", + "problem_share_link_shocker_already_in_share_link_title": "Shocker is already in this public share", + "problem_share_link_shocker_not_in_share_link_title": "Shocker is not in this public share", + "problem_shocker_control_no_permission_title": "You do not have permission to control this shocker", + "problem_shocker_control_not_found_title": "Shocker not found", + "problem_shocker_control_paused_title": "Shocker is paused", + "problem_shocker_not_found_title": "Shocker not found", + "problem_signup_registration_disabled_title": "Registration is currently disabled", + "problem_signup_username_or_email_exists_title": "That username or email is already in use", + "problem_turnstile_invalid_title": "Verification failed", + "problem_turnstile_invalid_desc": "Please complete the challenge again and retry.", + "problem_user_not_found_title": "User not found", + "problem_user_privileged_delete_denied_title": "Privileged users cannot be deleted", + "problem_validation_error_title": "Some fields are invalid", + "problem_webhook_not_found_title": "Webhook not found", + "problem_webhook_unsupported_title": "Only Discord webhooks are supported", + "problem_webhook_unsupported_desc": "Use a discord.com URL, not canary or ptb.", + "error_too_many_requests": "Too many requests", + "error_retry_after_one": "Try again in {{count}} second.", + "error_retry_after_other": "Try again in {{count}} seconds.", + "error_unexpected_response": "Unexpected server response", + "error_internal": "Internal error occurred", + "error_network": "Network error occurred", + "dev_banner": "This is the OpenShock DEVELOPMENT environment. No data is saved, and it is regularly overwritten by production data.", + "firmware_channel_bugs_warning": "This channel might contain bugs." +} From fdd645daba7a59bab81c3bea3a4b2d2fdf7e2846 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Luc=20=E2=99=A5?= Date: Thu, 12 Nov 2026 17:43:27 +0100 Subject: [PATCH 19/27] New translations en.json (Polish) [ci skip] --- messages/pl.json | 1055 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 1055 insertions(+) create mode 100644 messages/pl.json diff --git a/messages/pl.json b/messages/pl.json new file mode 100644 index 00000000..ef4df56c --- /dev/null +++ b/messages/pl.json @@ -0,0 +1,1055 @@ +{ + "landing_tagline": "The go-to platform for safe, reliable, real low-latency remote shocking.", + "landing_section_label": "Home", + "landing_hubs_online": "Hubs online right now: ", + "landing_learn_more": "Learn More", + "landing_wiki": "Wiki", + "landing_meta_description": "Welcome to OpenShock, a free and open-source ecosystem to control various shock collars over the internet.", + "instance_meta_description": "Welcome to {{siteName}}, an independent instance of OpenShock, a free and open-source ecosystem to control various shock collars over the internet.", + "header_sidebar_toggle": "Toggle Sidebar", + "header_avatar_alt": "{{name}}'s avatar", + "header_menu_profile": "Profile", + "header_menu_settings": "Settings", + "header_menu_logout": "Logout", + "header_login": "Login", + "header_signup": "Sign Up", + "header_github_title": "OpenShock on GitHub", + "header_discord_title": "Community Discord", + "footer_made_with": "Made with by the OpenShock Team", + "footer_connection_status_label": "Server connection status", + "footer_signalr_state": "SignalR State", + "footer_frontend_version": "Frontend Version", + "footer_frontend_commit_title": "Commit {{commit}}", + "footer_backend_version": "Backend Version", + "footer_backend_commit_title": "Commit {{commit}}", + "footer_language_label": "Language", + "sidebar_home_link_label": "OpenShock home", + "sidebar_group_general": "General", + "sidebar_home": "Home", + "sidebar_shockers": "Shockers", + "sidebar_shared_shockers": "Shared Shockers", + "sidebar_hubs": "Hubs", + "sidebar_user_shares": "User Shares", + "sidebar_public_shares": "Public Shares", + "sidebar_serial_terminal": "Serial Terminal", + "sidebar_group_admin": "Admin", + "sidebar_admin_monitoring": "Monitoring", + "sidebar_admin_online_hubs": "Online Hubs", + "sidebar_admin_online_gateways": "Online Gateways", + "sidebar_admin_management": "Management", + "sidebar_admin_users": "Users", + "sidebar_admin_blacklists": "Blacklists", + "sidebar_admin_webhooks": "Webhooks", + "sidebar_admin_mail": "Mail", + "sidebar_admin_automation_tokens": "Automation Tokens", + "sidebar_admin_configuration": "Configuration", + "sidebar_group_settings": "Settings", + "sidebar_settings_api_tokens": "API Tokens", + "sidebar_settings_sessions": "Sessions", + "sidebar_settings_audit_log": "Audit Log", + "sidebar_settings_connections": "Connections", + "sidebar_settings_account": "Account Settings", + "error_meta_title": "Service Unavailable", + "error_meta_description": "OpenShock is currently unavailable", + "error_meta_logo_alt": "OpenShock Logo", + "error_fallback_message": "Something went wrong.", + "error_not_found_message": "Page not found", + "error_not_found_description": "The page you're looking for doesn't exist.", + "error_unexpected_description": "An unexpected error occurred.", + "error_go_back": "Go back", + "auth_layout_logo_alt": "OpenShock Logo", + "auth_layout_invalid_redirect_removed": "An invalid redirect URL was removed for your safety.", + "auth_activate_breadcrumb": "Activate Account", + "auth_activate_title": "Activate Account", + "auth_activate_activating": "Activating your account...", + "auth_activate_success": "Your account has been activated", + "auth_activate_failed": "This activation link is invalid or has expired", + "auth_activate_missing_token": "Missing activation token", + "auth_activate_continue": "Continue to login", + "auth_activate_toast_success": "Account activated", + "auth_forgot_breadcrumb": "Forgot Password", + "auth_forgot_title": "Forgot Password", + "auth_forgot_description": "Enter your email to reset your password", + "auth_forgot_email_label": "Email", + "auth_forgot_email_placeholder": "Email", + "auth_forgot_submit": "Reset Password", + "auth_forgot_signin_prompt": "Remember your password? Sign in", + "auth_forgot_mail_disabled": "Password resets are unavailable on this instance because it has no mail provider configured. Please contact your administrator for help recovering your account.", + "auth_forgot_toast_sent": "Reset password request has been sent to the given email", + "auth_login_breadcrumb": "Login", + "auth_login_title": "Welcome back", + "auth_login_loading_methods": "Loading available login methods", + "auth_login_choose_method": "Login with one of these methods", + "auth_login_with_account": "Login with your OpenShock Account", + "auth_login_activation_after_signup": "Your account has been created. We've sent an activation link to your email address. Check your inbox and spam folder.", + "auth_login_activation_pending": "Your account isn't activated yet. We've sent an activation link to your email address. Check your inbox and spam folder. If nothing arrives, try logging in again later to get a new link.", + "auth_login_oauth_only": "This account has no password. Sign in with the provider you signed up with.", + "auth_login_oauth_only_with_buttons": "This account has no password. Sign in with the provider you signed up with using the buttons above.", + "auth_login_or_continue_with": "Or continue with", + "auth_login_username_label": "Username or Email", + "auth_login_password_label": "Password", + "auth_login_submit": "Login", + "auth_login_signup_prompt": "Don't have an account? Sign up", + "auth_login_legal": "By clicking Login, you agree to our Terms of Service and Privacy Policy.", + "auth_oauth_create_breadcrumb": "Sign Up With {{provider}}", + "auth_oauth_create_title": "Sign Up With {{provider}}", + "auth_oauth_create_description": "Complete your account details", + "auth_oauth_create_username_label": "Username", + "auth_oauth_create_username_placeholder": "Username", + "auth_oauth_create_email_label": "Email", + "auth_oauth_create_email_placeholder": "Email", + "auth_oauth_create_submit": "Sign Up", + "auth_oauth_create_legal": "By clicking Sign Up, you agree to our Terms of Service and Privacy Policy.", + "auth_oauth_error_breadcrumb": "Authentication Error", + "auth_oauth_error_title": "Authentication Error", + "auth_oauth_error_back": "Back to login", + "auth_reset_breadcrumb": "Reset Password", + "auth_reset_title": "Reset Password", + "auth_reset_checking": "Verifying reset link...", + "auth_reset_choose_password": "Choose a new password for your account", + "auth_reset_invalid": "This reset link is invalid or has expired", + "auth_reset_password_label": "New Password", + "auth_reset_password_placeholder": "New Password", + "auth_reset_confirm_label": "Confirm New Password", + "auth_reset_confirm_placeholder": "Confirm New Password", + "auth_reset_submit": "Reset Password", + "auth_reset_request_new": "Request a new reset link", + "auth_reset_toast_success": "Password has been reset", + "auth_signup_breadcrumb": "Sign Up", + "auth_signup_toast_created_mail": "Account created successfully. Please check your email to verify your account.", + "auth_signup_toast_created_no_mail": "Account created successfully. You can log in now.", + "auth_signup_dialog_title": "Welcome! Thank you for signing up! ❤️", + "auth_signup_dialog_created_mail": "Your account has been created. 🎉 Please check your email to verify your account.", + "auth_signup_dialog_verify_then_login": "After verifying your email, you can log in to your account.", + "auth_signup_dialog_created_no_mail": "Your account has been created and is ready to use. 🎉", + "auth_signup_dialog_login_now": "You can log in to your account now.", + "auth_signup_title": "Create your account", + "auth_signup_loading_methods": "Loading available sign-up methods", + "auth_signup_using_email": "Signing up using email", + "auth_signup_choose_method": "Choose your preferred sign-up method", + "auth_signup_back": "Back", + "auth_signup_username_label": "Username", + "auth_signup_username_placeholder": "John OpenShock", + "auth_signup_email_label": "Email", + "auth_signup_email_placeholder": "john@example.com", + "auth_signup_password_label": "Password", + "auth_signup_password_placeholder": "Password", + "auth_signup_confirm_label": "Confirm Password", + "auth_signup_confirm_placeholder": "Confirm Password", + "auth_signup_submit": "Create Account", + "auth_signup_signin_prompt": "Already have an account? Sign in", + "auth_signup_or": "Or", + "auth_signup_with_email": "Signup with Email", + "auth_signup_legal": "By clicking Create Account, you agree to our Terms of Service and Privacy Policy.", + "auth_verify_breadcrumb": "Verify Email", + "auth_verify_title": "Verify Email", + "auth_verify_verifying": "Verifying your email address...", + "auth_verify_success": "Your email has been verified", + "auth_verify_failed": "This verification link is invalid or has expired", + "auth_verify_missing_token": "Missing verification token", + "auth_verify_continue": "Continue to login", + "auth_verify_toast_success": "Email verified", + "common_cancel": "Cancel", + "common_delete": "Delete", + "common_edit": "Edit", + "common_share": "Share", + "common_copy_id": "Copy ID", + "common_id_copied": "ID copied to clipboard", + "common_open_menu": "Open menu", + "common_refresh": "Refresh", + "common_settings": "Settings", + "common_clear": "Clear", + "common_online": "Online", + "common_offline": "Offline", + "common_paused": "Paused", + "common_resume": "Resume", + "common_resuming": "Resuming...", + "common_coming_soon": "(Coming soon)", + "common_save_changes": "Save Changes", + "common_danger_zone": "Danger Zone", + "common_name": "Name", + "control_intensity": "Intensity", + "control_duration": "Duration", + "control_max_intensity": "Max Intensity", + "control_max_duration": "Max Duration", + "control_vibration": "Vibration", + "control_value": "Value", + "control_live_intensity": "Live intensity", + "control_type_stop": "Stop", + "control_type_shock": "Shock", + "control_type_vibrate": "Vibrate", + "control_type_sound": "Sound", + "live_tooltip_active": "Live via {{gateway}} ({{country}}), {{latency}}ms", + "live_tooltip_connecting": "Connecting...", + "live_tooltip_connect": "Connect to Live Control", + "live_tooltip_hub_start": "Ctrl+click to start the whole hub", + "live_tooltip_hub_stop": "Ctrl+click to stop the whole hub", + "pause_resume_shocker": "Resume shocker", + "pause_pause_shocker": "Pause shocker", + "pause_resume_all": "Resume all shockers", + "pause_pause_all": "Pause all shockers", + "shocker_label": "Shocker", + "shocker_hub": "Hub", + "shocker_select_hub": "Select hub", + "shocker_rf_id": "RF ID", + "shocker_rf_id_invalid": "RF ID must be a whole number between {{min}} and {{max}}.", + "shocker_model": "Model", + "shocker_select_model": "Select model", + "shocker_name_placeholder": "Shocker name", + "shocker_menu_view_logs": "View Logs", + "shocker_delete_title": "Delete Shocker", + "shocker_delete_desc": "Are you sure you want to delete \"{{name}}\"? This action cannot be undone.", + "shocker_toast_deleted": "Shocker \"{{name}}\" deleted", + "shocker_toast_paused": "Shocker paused", + "shocker_toast_resumed": "Shocker resumed", + "shocker_add_desc": "Register a new shocker to one of your hubs.", + "shocker_add_name_placeholder": "My Shocker", + "shockers_title": "Shockers", + "shockers_subtitle": "Every shocker paired to your hubs.", + "shockers_loading": "Loading shockers...", + "shockers_toast_refreshed": "Shockers refreshed", + "shockers_toast_need_hub": "You need to create a hub before adding shockers.", + "shockers_toast_added": "Shocker added", + "shockers_unknown_module": "Unknown module type", + "shockers_add": "Add Shocker", + "shockers_view_mode": "View mode", + "shockers_mode_classic": "Classic", + "shockers_mode_rich": "Rich", + "shockers_mode_simple": "Simple", + "shockers_mode_map": "Map", + "shockers_group_by_hub": "Group by Hub", + "shockers_global_limits": "Global Limits", + "shockers_logs_label": "Logs", + "shockers_empty_title": "No shockers yet", + "shockers_empty_no_hubs": "Create a hub first, then add shockers to it.", + "shockers_empty_has_hubs": "Add a shocker to one of your hubs to get started.", + "shockers_create_hub": "Create a Hub", + "shockers_count_one": "{{count}} shocker", + "shockers_count_other": "{{count}} shockers", + "shared_shockers_title": "Shared Shockers", + "shared_shockers_subtitle": "Shockers other users have shared with you.", + "shared_shockers_empty_title": "No shockers have been shared with you yet.", + "shared_shockers_empty_desc": "When someone shares their shockers with you, they'll appear here.", + "shocker_logs_title": "Shocker Logs", + "shocker_logs_subtitle": "Every control command sent to your shockers.", + "shocker_logs_live_title": "New logs appear in real time", + "shocker_logs_paused_title": "Live updates pause when sorting or viewing a page other than the first", + "shocker_logs_live": "Live", + "shocker_logs_col_time": "Time", + "shocker_logs_col_type": "Type", + "shocker_logs_col_by": "By", + "shocker_logs_filter_label": "Filter by shocker", + "shocker_logs_filter_placeholder": "Search shockers...", + "shocker_logs_filter_all": "All shockers", + "shocker_logs_filter_none": "No matching shockers", + "shocker_edit_title": "Edit Shocker", + "shocker_edit_subtitle": "Change this shocker's details or remove it.", + "shocker_edit_back": "Back to Shockers", + "shocker_edit_load_failed": "Failed to load shocker.", + "shocker_edit_loading": "Loading shocker...", + "shocker_edit_details_title": "Shocker Details", + "shocker_edit_details_desc": "Update the name, RF ID, and model for this shocker.", + "shocker_edit_pause_state": "Pause State", + "shocker_edit_is_paused": "Shocker is paused", + "shocker_edit_is_active": "Shocker is active", + "shocker_edit_toast_updated": "Shocker updated", + "shocker_edit_delete_desc": "Permanently delete this shocker. This action cannot be undone.", + "common_close": "Close", + "common_continue": "Continue", + "common_loading": "Loading...", + "common_previous": "Previous", + "common_next": "Next", + "common_steps": "Steps", + "common_step_label": "Step {{number}}: {{title}}", + "common_copy": "Copy", + "common_copied": "Copied", + "common_never": "Never", + "common_error": "Error: {{message}}", + "terminal_title": "Serial Terminal", + "terminal_connecting": "Connecting...", + "terminal_help_button": "I'm having trouble, help?", + "terminal_back_to_modes": "Back to mode picker", + "terminal_mode_configure": "Configure Device", + "terminal_mode_configure_desc": "Configure WiFi, authentication, and more. Includes an interactive serial console.", + "terminal_mode_flash": "Flash Firmware", + "terminal_mode_flash_desc": "Install or update firmware on a connected device.", + "terminal_mode_raw": "Serial Monitor", + "terminal_mode_raw_desc": "Just the console. Read device logs and send commands.", + "terminal_step_channel": "Select Channel", + "terminal_step_board": "Select Board", + "terminal_go_to_step": "Go to step {{number}}: {{title}}", + "terminal_erase": "Erase before flashing", + "terminal_erase_desc": "Clears all data on the device including existing configs", + "terminal_unsupported": "Your browser does not support this feature.", + "terminal_update_browser": "Please update your browser to the latest version.", + "terminal_use_browsers": "Please use one of the following browsers:", + "terminal_connect_failed_bootloader": "Could not enter bootloader mode", + "terminal_connect_failed": "Device connection failed", + "terminal_connect_failed_desc": "We couldn't establish a serial connection with the device.", + "terminal_quick_tries": "Quick things to try:", + "terminal_try_replug": "Unplug and replug the device.", + "terminal_try_cable": "Try a different USB cable or port.", + "terminal_try_driver": "Make sure the serial driver is installed.", + "terminal_open_troubleshooter": "Open troubleshooter", + "terminal_log_reset_no_device": "Host-side error during reset: no device!", + "terminal_log_reset_error": "Host-side error during reset: {{error}}", + "terminal_log_send_no_device": "Couldn't send: no device!", + "terminal_log_send_error": "Couldn't send: {{error}}", + "terminal_log_firmware_disconnected": "Firmware disconnected: {{error}}", + "terminal_log_erase_failed": "Failed to erase flash: {{error}}", + "terminal_log_hard_reset_failed": "Failed to hard reset: {{error}}", + "terminal_log_flash_complete": "Flash complete", + "terminal_log_flash_failed": "Failed to flash: {{error}}", + "terminal_log_command_failed": "Failed to write application command: {{error}}", + "terminal_help_title": "Troubleshooter", + "terminal_help_desc": "Work through these steps in order. Each one rules out a common cause.", + "terminal_help_step_cable": "USB cable", + "terminal_help_step_port": "USB port", + "terminal_help_step_driver": "Install driver", + "terminal_help_step_manual": "Manual driver update", + "terminal_help_step_discord": "Ask on Discord", + "terminal_help_cable_body": "Many USB-C and micro-USB cables are charge-only and don't carry data. Swap to a known-good data cable (one you've used to transfer files or connect other devices) and reconnect the hub.", + "terminal_help_port_body": "Plug the device directly into a USB port on your computer. Avoid USB hubs, docking stations, and front-panel ports if possible; these are common sources of power and signal issues. If you're on a desktop, try a port on the back of the machine.", + "terminal_help_driver_download": "Download the CP210x driver:", + "terminal_help_driver_extract": "Extract the contents of the zip file to a folder on your computer.", + "terminal_help_driver_run": "Open the folder and run {{installer}}. Follow the prompts to install.", + "terminal_help_driver_reconnect": "Reconnect the device.", + "terminal_help_manual_intro": "If the driver installer ran but the device still doesn't show up:", + "terminal_help_manual_open": "Open Device Manager (press Win + X and select Device Manager).", + "terminal_help_manual_ports": "Under Ports (COM & LPT), look for an entry like:", + "terminal_help_manual_missing": "If it's missing, the device isn't being detected by Windows at all; revisit the cable and port steps.", + "terminal_help_manual_update": "Right-click the device and pick Update Driver.", + "terminal_help_manual_browse": "Choose Browse my computer for drivers and select the folder you extracted the driver zip into. Make sure Include subfolders is checked.", + "terminal_help_manual_success": "On success, the entry should now read {{deviceName}}.", + "terminal_help_discord_intro": "Still stuck after all of the above? Hop into our Discord server and ask in the {{channel}} channel. Please include:", + "terminal_help_discord_os": "your operating system and browser", + "terminal_help_discord_device": "the device you're using (board model, where you got it)", + "terminal_help_discord_tried": "what you've already tried from the previous steps", + "terminal_help_discord_errors": "any error messages or relevant terminal output", + "terminal_help_discord_join": "Join our Discord server", + "terminal_risk_title": "⚠️ UNSTABLE FIRMWARE", + "terminal_risk_intro": "You are about to flash experimental firmware that is known to be unstable.", + "terminal_risk_brick": "This may permanently brick your device, require manual recovery, or render it unusable.", + "terminal_risk_no_support": "We will NOT provide support for issues caused by this firmware.", + "terminal_risk_acknowledge": "I understand this is entirely my responsibility", + "terminal_risk_abort": "Abort", + "terminal_risk_accept": "I ACCEPT FULL RESPONSIBILITY", + "firmware_channel_recommended": "This is the recommended channel.", + "firmware_channel_danger": "DO NOT USE THIS UNLESS YOU KNOW WHAT YOU ARE DOING", + "firmware_channel_stable": "Stable", + "firmware_channel_beta": "Beta", + "firmware_channel_develop": "Develop", + "terminal_board_select": "Select a board...", + "terminal_board_search": "Search boards...", + "terminal_board_none": "No board found.", + "terminal_flash_button": "Flash", + "terminal_flash_progress": "Flash Progress: {{status}}", + "terminal_flash_idle": "Idle", + "terminal_flash_no_device": "No device selected.", + "terminal_flash_resetting": "Resetting...", + "terminal_flash_downloading": "Downloading firmware...", + "terminal_flash_download_failed": "Failed to download firmware.", + "terminal_flash_flashing": "Flashing firmware...", + "terminal_flash_rebooting": "Rebooting device... (Reconnect to power manually if stuck)", + "terminal_flash_done": "Rebooted device! Flashing complete.", + "terminal_port_select": "Select Device", + "terminal_port_disconnect": "Disconnect Device", + "terminal_port_connected": "Device connected: {{id}}", + "terminal_console": "Console", + "terminal_connected_device": "Connected device", + "terminal_resize": "Resize terminal panel", + "terminal_reboot": "Reboot", + "terminal_disconnect": "Disconnect", + "terminal_fullscreen_exit_esc": "Exit fullscreen (Esc)", + "terminal_fullscreen_exit": "Exit fullscreen", + "terminal_fullscreen_fill": "Fill the window", + "terminal_command_label": "Serial command", + "terminal_command_placeholder": "Type a command...", + "terminal_command_send": "Send command", + "terminal_colors": "Colors", + "terminal_colors_menu": "Colors...", + "terminal_colors_label": "Console colors", + "terminal_colors_close": "Close colors", + "terminal_color_input": "{{name}} color", + "terminal_colors_reset": "Reset to defaults", + "terminal_color_bg": "Background", + "terminal_color_fg": "Text", + "terminal_color_ts": "Timestamp", + "terminal_color_error": "Error", + "terminal_color_warning": "Warning", + "terminal_color_info": "Info", + "terminal_color_debug": "Debug", + "terminal_color_verbose": "Verbose", + "terminal_options": "Options", + "terminal_options_label": "Console options", + "terminal_hide_system": "Hide system messages", + "terminal_stick_bottom": "Stick to bottom", + "terminal_raw_output": "Raw output", + "terminal_timestamps": "Timestamps", + "terminal_timestamp_uptime": "Uptime", + "terminal_timestamp_local": "Local", + "terminal_timestamp_ms": "Ms", + "terminal_timestamp_off": "Off", + "terminal_copy_settings": "Copy settings", + "terminal_import_settings": "Import settings", + "terminal_copy_selection": "Copy selection", + "terminal_copy_all": "Copy all output", + "terminal_toast_selection_copied": "Selection copied", + "terminal_toast_output_copied": "Console output copied", + "terminal_toast_settings_copied": "Console settings copied", + "terminal_toast_clipboard_unreadable": "Could not read the clipboard", + "terminal_toast_settings_imported": "Console settings imported", + "terminal_toast_settings_invalid": "Clipboard does not contain console settings", + "common_try_again": "Try again", + "terminal_cfg_intro": "Values are sent to the device via UART. Read the device's response in the console below. Commands without an argument act as getters; use the button next to each field to read the current value.", + "terminal_cfg_rf_title": "RF Transmitter", + "terminal_cfg_rf_desc": "Controls the shocker RF output.", + "terminal_cfg_tx_pin": "TX GPIO pin", + "terminal_cfg_example": "e.g. {{value}}", + "terminal_cfg_read_value": "Read current value", + "terminal_cfg_set": "Set", + "terminal_cfg_read": "Read", + "terminal_cfg_reading": "Reading…", + "terminal_cfg_apply": "Apply", + "terminal_cfg_keepalive": "Keepalive enabled", + "terminal_cfg_keepalive_desc": "Periodically pings paired shockers to keep them awake.", + "terminal_cfg_estop_title": "Emergency Stop", + "terminal_cfg_estop_desc": "Hardware button that halts all output.", + "terminal_cfg_estop_enabled": "EStop enabled", + "terminal_cfg_estop_pin": "EStop GPIO pin", + "terminal_cfg_estop_note": "Note: {{latching}} and {{active}} have no dedicated commands; set them via the JSON config below.", + "terminal_cfg_wifi_title": "WiFi", + "terminal_cfg_wifi_desc": "Station credentials and device hostname.", + "terminal_cfg_hostname": "Hostname", + "terminal_cfg_networks": "Networks (JSON array)", + "terminal_cfg_invalid_json_array": "Must be a valid JSON array", + "terminal_cfg_ap_note": "AP settings ({{ssid}}, {{password}}, {{disabled}}, {{staDisabled}}, {{offlineMode}}) have no dedicated commands; use the JSON config.", + "terminal_cfg_backend_title": "Backend", + "terminal_cfg_backend_desc": "OpenShock server and authentication.", + "terminal_cfg_domain": "Domain", + "terminal_cfg_domain_restart": "Setting the domain will restart the device.", + "terminal_cfg_auth_token": "Auth token", + "terminal_cfg_auth_token_placeholder": "Paste device token", + "terminal_cfg_hide": "Hide", + "terminal_cfg_show": "Show", + "terminal_cfg_serial_title": "Serial Input", + "terminal_cfg_echo": "Echo enabled", + "terminal_cfg_echo_desc": "Print typed characters back to the console.", + "terminal_cfg_advanced_title": "Advanced: full config", + "terminal_cfg_advanced_desc": "For fields without dedicated commands (captive portal, OTA, LAN, etc.), replace the entire config.", + "terminal_cfg_json_config": "JSON config", + "terminal_cfg_invalid_json": "Must be valid JSON", + "terminal_cfg_read_json": "Read current config as JSON", + "terminal_cfg_json_restart": "Applying a JSON config will restart the device.", + "terminal_cfg_raw_config": "Raw FlatBuffer config (base64)", + "terminal_cfg_invalid_base64": "Must be a valid base64 string", + "terminal_cfg_read_raw": "Read current config as base64", + "terminal_cfg_factory_reset": "Factory reset", + "terminal_cfg_factory_reset_desc": "Wipes the entire device configuration.", + "terminal_cfg_factory_reset_title": "Factory reset device?", + "terminal_cfg_factory_reset_action": "Wipe config", + "terminal_cfg_factory_reset_confirm": "This will erase all configuration on the device; WiFi networks, backend credentials, pins, and all other settings. The device will be reset to defaults.", + "terminal_cfg_read_failed_json_title": "Couldn't read the JSON config", + "terminal_cfg_read_failed_raw_title": "Couldn't read the raw config", + "terminal_cfg_read_failed_desc": "The device didn't respond after {{attempts}} attempts.", + "terminal_cfg_common_causes": "Common causes:", + "terminal_cfg_cause_busy": "The device is busy handling another command.", + "terminal_cfg_cause_disconnected": "The device disconnected or rebooted.", + "terminal_cfg_cause_unsupported": "The firmware version doesn't support this command.", + "common_status": "Status", + "common_version": "Version", + "common_created": "Created", + "common_create": "Create", + "common_done": "Done", + "common_enable": "Enable", + "common_disable": "Disable", + "common_are_you_sure": "Are you sure?", + "common_generating": "Generating...", + "hubs_title": "Hubs", + "hubs_subtitle": "Every hub registered to your account.", + "hubs_add": "Add Hub", + "hubs_load_failed": "Failed to load hubs.", + "hubs_empty_title": "No hubs yet", + "hubs_empty_desc": "A hub is the device that relays commands to your shockers. Add one to get started.", + "hubs_create_title": "Create hub", + "hubs_name_label": "Hub Name", + "hubs_name_placeholder": "My Hub", + "hub_toast_not_connected": "Not connected to the server", + "hub_toast_try_later": "Try again in a moment.", + "hub_reboot_title": "Reboot {{name}}?", + "hub_reboot_desc": "The hub will disconnect and restart. Any shockers paired to it stop responding until it comes back online.", + "hub_reboot": "Reboot", + "hub_hotspot_enable_title": "Enable Wi-Fi hotspot on {{name}}?", + "hub_hotspot_disable_title": "Disable Wi-Fi hotspot on {{name}}?", + "hub_hotspot_enable_desc": "The hub broadcasts its own setup network. It stays reachable on your Wi-Fi, but the hotspot is open to anyone in range until you turn it off.", + "hub_hotspot_disable_desc": "The setup hotspot shuts down. If the hub is not already on your Wi-Fi you will need physical access to set it up again.", + "hub_delete_desc": "You are about to delete hub {{name}}.", + "hub_delete_shockers": "This will also delete the following shockers:", + "hub_edit_title": "Edit hub", + "hub_edit_apply": "Apply", + "hub_pair_title_generate": "Generate pair code?", + "hub_pair_title_generated": "Pair code generated", + "hub_pair_title_paired": "Hub paired", + "hub_pair_consumed": "{{name}} consumed this pair code and is now paired.", + "hub_pair_used": "The code has been used and is no longer valid.", + "hub_pair_generated_for": "Pair code generated for {{name}}.", + "hub_copy_now": "The code below will not be accessible later, please copy it now and update clients with it.", + "hub_pair_generate_for": "You are about to generate a pair code for {{name}}.", + "hub_pair_valid_for": "It will be valid for 15 minutes after its creation.", + "hub_pair_one_active": "There is only one active pair code per hub, newly generated ones will override the older active ones.", + "hub_pair_complete": "Pairing complete", + "hub_pair_code_label": "Pair code:", + "hub_pair_copied_close": "Code has been copied, close", + "hub_pair_get": "Get Pair Code", + "hub_token_generated": "Token generated", + "hub_token_generated_for": "New token generated for {{name}}.", + "hub_token_regenerate_for": "You are about to regenerate the token for {{name}}.", + "hub_token_invalidate": "This action will invalidate the current token and disconnect clients using it.", + "hub_token_confirm": "Are you sure you want to do this?", + "hub_token_label": "New token:", + "hub_token_copied_close": "Token has been copied, close", + "hub_token_regenerate": "Regenerate Token", + "hub_menu_update": "Update", + "hub_menu_label": "Hub", + "hub_menu_hotspot_enable": "Enable Wi-Fi hotspot", + "hub_menu_hotspot_disable": "Disable Wi-Fi hotspot", + "hub_menu_pair": "Pair", + "hub_menu_estop": "Emergency Stop", + "hub_update_breadcrumb": "Update", + "hub_update_unknown_hub": "Unknown Hub", + "hub_update_unknown_task": "Unknown Task", + "hub_update_task_metadata": "Fetching Metadata", + "hub_update_task_preparing": "Preparing for Update", + "hub_update_task_flash_fs": "Flashing Filesystem", + "hub_update_task_verify_fs": "Verifying Filesystem", + "hub_update_task_flash_app": "Flashing Application", + "hub_update_task_bootable": "Marking Application Bootable", + "hub_update_task_rebooting": "Rebooting", + "hub_update_status_started": "Started", + "hub_update_status_running": "Running", + "hub_update_status_finished": "Finished", + "hub_update_status_error": "Error", + "hub_update_status_timeout": "Timeout", + "hub_update_confirm_title": "Confirm firmware update", + "hub_update_confirm_desc": "Update {{name}} to version {{version}}?", + "hub_update_unstable_warning": "This version may not be from the stable channel and could contain bugs.", + "hub_update_title": "Update {{name}}", + "hub_update_subtitle": "Manage firmware updates for this hub.", + "hub_update_status_title": "Hub Status", + "hub_update_firmware": "Firmware: {{version}}", + "hub_update_confirm": "Update", + "hub_update_success": "Update completed successfully", + "hub_update_rolled_back": "Device rolled back to previous version", + "hub_update_back": "Back to Hubs", + "hub_update_flash_again": "Flash Again", + "hub_update_card_title": "Firmware Update", + "hub_update_card_desc": "Select a firmware channel and version to install.", + "hub_update_to": "Update to {{version}}", + "hub_update_must_be_online": "Hub must be online to start an update.", + "hub_update_updating_to": "Updating to {{version}}...", + "hub_update_total": "Total", + "hub_update_task": "Task", + "hub_update_history": "Update History", + "hub_update_no_history": "No update history found for this hub.", + "hub_update_col_id": "ID", + "hub_update_col_started": "Started", + "hub_update_col_message": "Message", + "hub_update_loading": "Loading hub information...", + "hub_update_not_found": "Hub not found.", + "home_breadcrumb": "Home", + "home_welcome": "Welcome back", + "home_welcome_name": "Welcome back, {{name}}", + "home_subtitle": "Here's an overview of your OpenShock setup.", + "home_hubs_online": "{{count}} online", + "home_hub_status": "Hub Status", + "home_no_hubs": "No hubs", + "home_all_online": "All online", + "home_all_offline": "All offline", + "home_some_online": "{{online}}/{{total}} online", + "home_quick_links": "Quick Links", + "home_my_shockers": "My Shockers", + "home_my_shockers_desc": "Control your shockers", + "home_hubs_desc": "Manage your hubs", + "home_shared_desc": "Shockers shared with you", + "home_public_desc": "Manage share links", + "home_get_started": "Get Started", + "home_get_started_desc": "You don't have any hubs yet. Create a hub to connect your first device, then add shockers to it.", + "home_set_up_hub": "Set Up a Hub", + "home_first_shocker": "Add Your First Shocker", + "home_first_shocker_desc_one": "You have {{count}} hub set up. Add a shocker to start controlling it.", + "home_first_shocker_desc_other": "You have {{count}} hubs set up. Add a shocker to start controlling it.", + "home_go_to_shockers": "Go to Shockers", + "profile_title": "Profile", + "profile_coming_soon": "Profile is coming soon", + "profile_coming_soon_desc": "Your public profile is not available yet. Account details live under Settings.", + "common_retry": "Retry", + "common_never_used": "Never used", + "common_expires": "Expires {{time}}", + "common_search_placeholder": "Search...", + "common_unknown": "Unknown", + "settings_breadcrumb_account": "Account", + "account_subtitle": "Your sign-in details and account actions.", + "account_change_username": "Change Username", + "account_change_email": "Change Email", + "account_change_password": "Change Password", + "account_username_label": "Username", + "account_email_label": "Email", + "account_password_label": "Password", + "account_new_password_label": "New Password", + "account_confirm_password_label": "Confirm New Password", + "account_oauth_only": "Not available for OAuth-only accounts", + "account_oauth_no_password": "This account signs in via OAuth and has no password.", + "account_diagnostics": "Diagnostics", + "account_diagnostics_desc": "Help us fix crashes and slow API calls. Reports include the error message, stack trace and your IP. Off by default.", + "account_diagnostics_level": "Diagnostics level", + "account_telemetry_off": "Off", + "account_telemetry_off_desc": "Send nothing.", + "account_telemetry_errors": "Errors", + "account_telemetry_errors_desc": "Send browser error reports only.", + "account_telemetry_full": "Full", + "account_telemetry_full_desc": "Error reports plus traces of API calls (no page navigations).", + "account_toast_deactivated": "Account deactivated successfully", + "account_deactivate_title": "Deactivate account", + "account_deactivate_desc": "Are you sure you want to deactivate your account?", + "account_deactivate": "Deactivate Account", + "account_email_title": "Change email", + "account_email_desc": "Enter your new email address and confirm with your current password.", + "account_email_toast_sent": "Verification email sent to {{email}}. Click the link in that email to apply the change.", + "account_new_email": "New Email", + "account_current_password": "Current Password", + "account_password_title": "Change password", + "account_password_desc": "Enter your current password and choose a new one.", + "account_password_toast": "Password has been changed", + "account_username_title": "Change username", + "account_username_desc": "Enter a new username.", + "account_new_username": "New Username", + "account_username_toast": "Username changed successfully", + "tokens_subtitle": "API Tokens are used to authenticate with the OpenShock API.", + "tokens_generate": "Generate Token", + "tokens_toast_refreshed": "Tokens refreshed successfully", + "tokens_empty_title": "No API tokens", + "tokens_empty_desc": "Generate a token to authenticate with the OpenShock API.", + "tokens_created_on": "Created {{date}}", + "tokens_last_used": "Last used {{time}}", + "tokens_never_expires": "Never expires", + "tokens_load_failed": "Failed to load API tokens.", + "token_toast_edited": "Token edited successfully", + "token_name_required": "Name is required", + "token_name_too_long": "Name is too long", + "token_edit_title": "Edit API token", + "token_name_label": "Token Name", + "token_name_placeholder": "Token name...", + "token_permissions": "Permissions", + "token_perm_category_shockers": "Shockers", + "token_perm_category_devices": "Hubs", + "token_perm_category_usershares": "User Shares", + "token_perm_category_publicshares": "Public Shares", + "token_perm_use": "Use", + "token_perm_edit": "Edit", + "token_perm_pause": "Pause", + "token_perm_auth": "Authenticate", + "token_shocker_control": "Shocker Control", + "token_toast_paused": "Token paused", + "token_toast_resumed": "Token resumed", + "token_delete_title": "Delete API token", + "token_delete_desc": "Are you sure you want to delete {{name}}?", + "token_delete_permanent": "This action cannot be undone. This will permanently delete the token.", + "token_toast_deleted": "Token deleted successfully", + "token_resume": "Resume token", + "token_pause": "Pause token", + "token_mode_clamp_desc": "Clamp: requests outside the allowed range are capped to the nearest limit (the min or the max).", + "token_mode_lerp_desc": "Lerp: the full input range is linearly rescaled so it fits within your allowed min–max range.", + "token_paused_desc": "A paused token may not send shocker control messages.", + "token_intensity_range": "Intensity range", + "token_duration_range": "Duration range", + "token_new_breadcrumb": "New", + "token_redirect_not_allowed": "The provided redirect_uri is not allowed. Only loopback addresses or custom application schemes are permitted.", + "token_params_missing": "Required get parameters are missing. Make sure name, redirect_uri, and permissions are provided.", + "token_invalid_permissions": "Invalid permissions provided: {{list}}", + "token_toast_created": "Token created successfully", + "token_request_title": "API Token Request", + "token_access_granted": "Access granted", + "token_shared_redirecting": "The token has been created and shared with the application. Redirecting you back to {{uri}}.", + "token_not_redirected": "If you are not redirected automatically, use the button below.", + "token_finish": "Finish", + "token_generated_title": "API Token Generated", + "token_copy_now": "Please copy your API Token now, you will not be able to view it again later!", + "token_new_title": "New API Token", + "token_external_desc": "An external application is requesting access to your account. Review and adjust the permissions below before allowing access.", + "token_new_desc": "Configure and generate a new API token for your account.", + "token_external_requesting": "{{name}} is requesting an API Token. Your token will be shared with the application at {{uri}}.", + "token_allow": "Allow", + "token_generate": "Generate", + "token_deny": "Deny", + "sessions_subtitle": "Every active session on your account. Revoke any you do not recognize.", + "sessions_unknown_device": "Unknown device", + "sessions_toast_refreshed": "Sessions refreshed successfully", + "sessions_load_failed": "Failed to load sessions.", + "sessions_empty_title": "No active sessions", + "sessions_empty_desc": "Sessions appear here once you sign in from a browser or app.", + "sessions_last_seen": "Last seen {{time}}", + "sessions_signed_in": "Signed in {{time}}", + "session_toast_revoked": "Session revoked successfully", + "session_revoke_title": "Revoke session", + "session_revoke": "Revoke", + "session_revoke_desc": "Are you sure you want to revoke this session?", + "session_revoke_from": "Session logged in from {{ip}} using {{agent}}", + "connections_title": "OAuth Connections", + "connections_subtitle": "Link or unlink third-party accounts to sign in faster and keep your profile in sync.", + "connections_toast_linked": "Account linked.", + "connections_toast_cancelled": "Link flow cancelled.", + "connections_toast_failed": "Linking failed.", + "connections_toast_removed": "Connection removed", + "connections_refreshing": "Refreshing…", + "connections_link_new": "Link new provider", + "connections_empty_title": "No connections yet", + "connections_empty_desc": "Choose “Link new provider” above to connect available providers.", + "connections_unlink": "Unlink", + "connections_load_failed": "Failed to load OAuth connections.", + "connections_unlink_title": "Unlink {{name}}?", + "connections_unlink_title_generic": "Unlink this account?", + "connections_unlink_desc": "You'll no longer be able to sign in with this provider unless you link it again.", + "provider_starting": "Starting {{name}}...", + "provider_link": "Link {{name}}", + "audit_subtitle": "Security-relevant activity on your account. Review anything you do not recognize.", + "audit_col_time": "Time", + "audit_col_action": "Action", + "audit_col_details": "Details", + "audit_col_reason": "Reason", + "audit_col_ip": "IP address", + "audit_col_device": "Device", + "audit_action_login": "Signed in", + "audit_action_logout": "Signed out", + "audit_action_password_changed": "Password changed", + "audit_action_email_change_requested": "Email change requested", + "audit_action_email_changed": "Email changed", + "audit_action_username_changed": "Username changed", + "audit_action_api_token_created": "API token created", + "audit_action_api_token_deleted": "API token deleted", + "audit_action_oauth_connected": "Connection added", + "audit_action_oauth_disconnected": "Connection removed", + "audit_action_account_deactivated": "Account deactivated", + "audit_action_account_reactivated": "Account reactivated", + "audit_action_account_deleted": "Account deleted", + "audit_action_automation_token_created": "Automation token created", + "audit_action_automation_token_updated": "Automation token updated", + "audit_action_automation_token_rotated": "Automation token rotated", + "audit_action_automation_token_deleted": "Automation token deleted", + "audit_action_automation_token_used": "Automation token used", + "audit_meta_session": "Session {{id}}", + "audit_meta_changed": "{{old}} to {{new}}", + "audit_meta_email_requested": "Requested change to {{email}}", + "audit_meta_accounts_removed_one": "{{name}} ({{count}} account removed)", + "audit_meta_accounts_removed_other": "{{name}} ({{count}} accounts removed)", + "audit_meta_scheduled_deletion": "Scheduled for deletion", + "audit_meta_kept": "Kept for reactivation", + "common_view": "View", + "common_save": "Save", + "common_saving": "Saving...", + "common_back": "Back", + "common_shared_by": "Shared by", + "common_user_avatar": "User Avatar", + "common_toast_saved": "Changes saved successfully", + "pause_reason_shocker": "Paused at shocker level", + "pause_reason_shocker_user_share": "Paused at shocker and user share level", + "pause_reason_shocker_public_share": "Paused at shocker and public share level", + "pause_reason_user_share": "Paused at user share level", + "pause_reason_public_share": "Paused at public share level", + "public_shares_subtitle": "A link anyone can use, no account required.", + "public_shares_new": "New Share", + "public_share_never_expires": "Never expires", + "public_shares_empty_title": "No public shares yet", + "public_shares_empty_desc": "Create a link that anyone can use to control your shockers.", + "public_share_expired": "Expired", + "public_share_no_expiry": "No expiry", + "public_share_label": "Public Share", + "public_share_toast_created": "Created new public share", + "public_share_create_title": "Create public share", + "public_share_toast_deleted": "Deleted public share", + "public_share_delete_title": "Delete public share", + "public_share_delete_desc": "Are you sure you want to delete public share {{name}}?", + "public_share_edit_title": "Public Share: {{name}}", + "public_share_edit_subtitle": "Editing: changes apply when you save.", + "public_share_add_shocker": "Add Shocker", + "public_share_toast_added_one": "Added {{count}} shocker to share", + "public_share_toast_added_other": "Added {{count}} shockers to share", + "public_share_empty_shockers_title": "No shockers in this share", + "public_share_empty_shockers_desc": "Add a shocker and anyone with the link will be able to control it.", + "public_share_load_failed": "Error fetching public share details", + "public_share_paused_here": "Paused for this share", + "public_share_resume_shocker": "Resume shocker", + "public_share_pause_shocker": "Pause shocker", + "public_share_remove": "Remove from share", + "public_share_toast_removed": "Shocker removed from share", + "public_share_add_title": "Add shockers", + "public_share_add_desc": "Add shockers to this public share. You can set their limits once they are added.", + "public_share_add_placeholder": "Select shockers to share...", + "public_share_add_no_match": "No matching shockers", + "public_share_add_submit": "Add Shockers", + "public_share_view_loading": "Loading share details...", + "public_share_view_title": "Public Share Link", + "public_share_view_desc": "Enter as a guest or login with your OpenShock account", + "public_share_view_guest_name": "Guest Name", + "public_share_view_enter": "Enter", + "public_share_view_enter_guest": "Enter as Guest", + "public_share_login": "Login", + "perm_shock_on": "Shock enabled", + "perm_shock_off": "Shock disabled", + "perm_vibrate_on": "Vibrate enabled", + "perm_vibrate_off": "Vibrate disabled", + "perm_sound_on": "Sound enabled", + "perm_sound_off": "Sound disabled", + "perm_live_on": "Live enabled", + "perm_live_off": "Live disabled", + "perm_live_control": "Live Control", + "user_selector_avatar_of": "{{name}}'s avatar", + "user_selector_placeholder": "Enter user name", + "user_selector_aria": "Username to search", + "user_selector_search": "Search user", + "user_selector_found": "User found", + "common_remove": "Remove", + "user_shares_subtitle": "Direct permanent shares with other users.", + "user_shares_toast_invited": "Sent a shocker invite to {{name}}", + "user_shares_redeem": "Redeem Code", + "user_shares_new": "New Share", + "user_shares_tab_shares": "Shares", + "user_shares_tab_incoming": "Shared with Me", + "user_shares_tab_invites": "Invites", + "share_code_create_title": "New share code", + "share_code_create_desc": "Create a Share Code or Invite", + "share_code_shocker_placeholder": "Select shockers to share...", + "share_code_no_match": "No matching shockers", + "share_code_send_invite": "Send Share Invite", + "share_code_create": "Create Share Code", + "share_code_created_title": "Share code generated", + "share_code_created_desc": "Please copy share code or code link!", + "share_code_redeem_title": "Redeem share code", + "share_code_redeem_desc": "Enter the share code to redeem", + "share_code_redeem_placeholder": "Enter share code", + "share_code_redeemed": "Redeemed successfully!", + "share_code_shared_shockers": "Shared shockers", + "share_code_redeeming": "Redeeming...", + "share_code_redeem": "Redeem", + "incoming_shares_empty_title": "Nothing shared with you", + "incoming_shares_empty_desc": "No one has shared a shocker with you yet.", + "incoming_share_toast_removed": "Removed share for {{name}}", + "incoming_share_remove_title": "Remove Share", + "incoming_share_remove_desc": "Are you sure you want to remove the share for {{name}}?", + "incoming_share_toast_removed_shocker": "Removed {{shocker}} shared by {{name}}", + "incoming_share_remove_shocker_title": "Remove this shared shocker?", + "incoming_share_remove_shocker_desc": "Are you sure you want to remove the shocker share {{shocker}} by {{name}}?", + "incoming_share_manage_from": "Manage shares from", + "share_remove": "Remove share", + "invites_empty_title": "No invites yet", + "invites_empty_desc": "You have no incoming or outgoing share invites.", + "invites_outgoing": "Outgoing", + "invites_outgoing_empty_title": "No outgoing invites", + "invites_outgoing_empty_desc": "You have no outgoing share invites.", + "invites_incoming": "Incoming", + "invites_incoming_empty_title": "No incoming invites", + "invites_incoming_empty_desc": "You have no incoming share invites.", + "invite_toast_accepted": "Accepted share invite from {{name}}", + "invite_toast_declined": "Declined share invite from {{name}}", + "invite_deny_title": "Deny Invite", + "invite_deny_label": "Deny Invite", + "invite_deny": "Deny", + "invite_deny_desc": "Are you sure you want to deny the invite from {{name}}?", + "invite_accept": "Accept Invite", + "invite_toast_cancelled_for": "Cancelled invite for {{name}} ({{id}})", + "invite_toast_cancelled": "Cancelled invite {{id}}", + "invite_cancel_title": "Cancel Invite", + "invite_cancel": "Cancel", + "invite_cancel_for_desc": "Are you sure you want to cancel the invite for {{name}}?", + "invite_cancel_code_desc": "Are you sure you want to cancel the invite with code {{code}}?", + "invite_cancel_outstanding": "Cancel Outstanding Invite", + "outgoing_shares_empty_title": "No shared shockers", + "outgoing_shares_empty_desc": "You haven't shared any shockers with other users yet.", + "outgoing_share_toast_removed": "Removed shocker share {{name}}", + "outgoing_share_remove_title": "Stop sharing this shocker?", + "outgoing_share_editing_for": "Editing shares for", + "outgoing_share_limits": "Limits & Permissions", + "outgoing_share_same": "Same restrictions on every shocker", + "outgoing_share_per_desc": "Tune restrictions per shocker", + "outgoing_share_all": "All", + "outgoing_share_per": "Per shocker", + "outgoing_share_remove_desc": "Are you sure you want to stop sharing {{shocker}} with {{name}}?", + "report_breadcrumb": "Report API Tokens", + "report_toast_clipboard_failed": "Failed to read clipboard: {{error}}", + "report_title": "Report Leaked API Tokens", + "report_paste": "Paste from clipboard", + "report_warning": "This form is only for reporting accidentally leaked API tokens.", + "report_abuse_warning": "Intentional abuse will result in bans or severe endpoint restrictions.", + "report_detected": "Detected Tokens", + "report_invalid": "One or more tokens appear to be invalid. Please check for formatting issues.", + "report_acknowledge": "I confirm I understand what this feature is for and accept responsibility.", + "report_submit": "Submit Report", + "turnstile_disabled": "Turnstile disabled", + "common_internal_error": "Internal error", + "resend_toast_sent": "Activation email sent. Check your inbox and spam folder.", + "resend_toast_throttled": "Too many activation emails have been requested. Please try again later.", + "resend_toast_unavailable": "No activation email can be resent from this browser. If your account isn't activated yet, logging in sends a new link.", + "resend_button": "Didn't get the email? Resend", + "expiration_label": "Expiration", + "expiration_never": "Never", + "expiration_custom": "Custom", + "expiration_days_one": "{{count}} Day", + "expiration_days_other": "{{count}} Days", + "expiration_required": "Expire date is required", + "expiration_never_desc": "This will never expire", + "expiration_expires_at": "Expires {{time}} ({{date}})", + "date_picker_placeholder": "Pick a date", + "telemetry_toast_title": "Help improve OpenShock?", + "telemetry_toast_desc": "Send diagnostics to help us fix crashes and slow API calls. Reports include the error message, stack trace and your IP. You can change this any time in Account settings.", + "telemetry_toast_no": "No thanks", + "telemetry_toast_errors": "Errors only", + "telemetry_toast_full": "Full", + "table_show_details": "Show details", + "table_hide_details": "Hide details", + "table_no_results": "No results.", + "table_sort_asc": "Sort by {{name}}, ascending", + "table_sort_desc": "Sort by {{name}}, descending", + "table_sort_none": "Sort by {{name}}, unsorted", + "cell_na": "N/A", + "cell_not_applicable": "Not applicable", + "cell_invalid": "Invalid", + "cell_unavailable": "Unavailable", + "cell_none": "None", + "oauth_login_with": "Login with {{provider}}", + "oauth_signup_with": "Signup with {{provider}}", + "signalr_connect_failed": "Failed to connect to server!", + "signalr_disconnect_failed": "Encountered error while disconnecting from server!", + "signalr_invalid_update": "Received invalid update from server!", + "signalr_invalid_log": "Received invalid log data from server!", + "signalr_invalid_ota": "Received invalid firmware update data from server!", + "ota_toast_failed": "Hub firmware update failed: {{message}}", + "ota_toast_succeeded": "Hub firmware update completed successfully!", + "ota_toast_rolled_back": "Hub firmware rolled back to previous version", + "lcg_connect_failed": "Failed to connect to live control gateway", + "terminal_toast_bootloader_failed": "Failed to enter bootloader: {{error}}", + "terminal_toast_app_mode_failed": "Failed to enter application mode: {{error}}", + "problem_account_account_not_activated_title": "Account not activated", + "problem_account_account_not_activated_desc": "Check your inbox for the activation email.", + "problem_account_activation_not_found_title": "Activation link is invalid", + "problem_account_activation_not_found_desc": "The link may have expired or already been used.", + "problem_account_activation_resend_too_many_title": "Too many activation emails requested", + "problem_account_activation_resend_too_many_desc": "Please wait a while before trying again.", + "problem_account_activation_resend_unavailable_title": "Cannot resend activation email", + "problem_account_activation_resend_unavailable_desc": "Log in again to request a new activation link.", + "problem_account_deactivate_already_deactivated_title": "Account is already deactivated", + "problem_account_deactivate_denied_privileged_title": "Privileged accounts cannot be deactivated", + "problem_account_deactivate_unauthorized_title": "You are not allowed to do this", + "problem_account_deactivated_title": "This account has been deactivated", + "problem_account_email_already_in_use_title": "That email address is already in use", + "problem_account_email_invalid_title": "That email address is not valid", + "problem_account_email_taken_title": "That email address is already in use", + "problem_account_email_too_many_requests_title": "Too many email change requests", + "problem_account_email_too_many_requests_desc": "Please wait a while before trying again.", + "problem_account_email_unchanged_title": "That is already your email address", + "problem_account_email_verify_not_found_title": "Verification link is invalid", + "problem_account_email_verify_not_found_desc": "The link may have expired or already been used.", + "problem_account_o_auth_only_title": "This account has no password", + "problem_account_o_auth_only_desc": "Sign in with the provider you signed up with.", + "problem_account_password_not_set_title": "No password set", + "problem_account_password_not_set_desc": "This account signs in through an external provider.", + "problem_account_password_old_password_invalid_title": "Current password is incorrect", + "problem_account_username_invalid_title": "That username is not allowed", + "problem_account_username_recently_changed_title": "Username changed too recently", + "problem_account_username_recently_changed_desc": "You can change your username once every 7 days.", + "problem_account_username_taken_title": "That username is already taken", + "problem_admin_user_deactivated_title": "This user is deactivated", + "problem_admin_user_not_activated_title": "This user has not been activated yet", + "problem_api_token_can_only_delete_self_title": "An API token can only delete itself", + "problem_api_token_not_found_title": "API token not found", + "problem_api_token_paused_title": "This API token is paused", + "problem_assign_lcg_bad_schema_version_title": "Unsupported hub protocol version", + "problem_assign_lcg_bad_schema_version_desc": "Update the hub firmware to connect.", + "problem_assign_lcg_no_lcg_available_title": "No gateway available", + "problem_assign_lcg_no_lcg_available_desc": "No live control gateway is available right now. Please try again later.", + "problem_authentication_account_deactivated_title": "This account has been deactivated", + "problem_authentication_account_not_activated_title": "This account has not been activated", + "problem_authentication_cookie_missing_or_invalid_title": "You are not logged in", + "problem_authentication_cookie_missing_or_invalid_desc": "Your session may have expired. Please log in again.", + "problem_authentication_header_missing_or_invalid_title": "Invalid API token", + "problem_authentication_session_invalid_title": "Session expired", + "problem_authentication_session_invalid_desc": "Please log in again.", + "problem_authentication_token_invalid_title": "Invalid API token", + "problem_authentication_unknown_error_title": "Authentication failed", + "problem_authorization_policy_not_met_title": "You do not have permission to do this", + "problem_authorization_token_only_title": "This action requires an API token", + "problem_authorization_token_permission_missing_title": "This API token is missing a required permission", + "problem_authorization_unknown_error_title": "Authorization failed", + "problem_authorization_user_session_only_title": "This action requires a logged-in session", + "problem_automation_token_not_allowed_for_account_title": "Automation tokens cannot be used with privileged accounts", + "problem_configuration_already_exists_title": "A configuration entry with that name already exists", + "problem_configuration_invalid_name_format_title": "Invalid configuration name", + "problem_configuration_invalid_name_format_desc": "Only A to Z and underscores are allowed.", + "problem_configuration_invalid_value_format_title": "Value does not match the configuration type", + "problem_configuration_not_found_title": "Configuration entry not found", + "problem_control_stats_invalid_range_title": "The from date must not be after the to date", + "problem_control_stats_invalid_time_zone_title": "Unknown time zone", + "problem_control_stats_missing_capability_title": "Control statistics are not available on this server", + "problem_device_not_found_title": "Hub not found", + "problem_device_not_online_title": "Hub is offline", + "problem_device_too_many_hubs_title": "You have reached the maximum number of hubs", + "problem_device_too_many_shockers_title": "This hub has reached its maximum number of shockers", + "problem_endpoint_retired_title": "This feature is no longer available", + "problem_expression_error_title": "Invalid filter expression", + "problem_internal_server_error_title": "Something went wrong on our end", + "problem_login_invalid_credentials_title": "Invalid username or password", + "problem_login_invalid_domain_title": "Logging in from this address is not allowed", + "problem_o_auth_connection_already_exists_title": "Your account is already connected to this provider", + "problem_o_auth_connection_already_linked_title": "This external account is already linked to another user", + "problem_o_auth_flow_anonymous_only_title": "You are already signed in", + "problem_o_auth_flow_mismatch_title": "Sign-in attempt does not match", + "problem_o_auth_flow_mismatch_desc": "Please start over.", + "problem_o_auth_flow_missing_data_title": "The provider did not return your account details", + "problem_o_auth_flow_missing_data_desc": "Please try again.", + "problem_o_auth_flow_not_found_title": "Sign-in attempt expired", + "problem_o_auth_flow_not_found_desc": "Please start over.", + "problem_o_auth_flow_unsupported_title": "Unsupported sign-in flow", + "problem_o_auth_internal_error_title": "Something went wrong during sign-in", + "problem_o_auth_internal_error_desc": "Please try again in a moment.", + "problem_o_auth_link_authenticated_user_only_title": "You must be signed in to link an external account", + "problem_o_auth_provider_mismatch_title": "Sign-in attempt does not match the provider", + "problem_o_auth_provider_mismatch_desc": "Please start over.", + "problem_o_auth_provider_unsupported_title": "This sign-in provider is not supported", + "problem_pair_code_not_found_title": "Pair code not found", + "problem_password_reset_not_found_title": "Password reset link is invalid", + "problem_password_reset_not_found_desc": "The link may have expired or already been used.", + "problem_session_not_found_title": "Session not found", + "problem_share_get_no_shares_title": "You have no shares with this user", + "problem_share_request_create_cannot_share_with_self_title": "You cannot share with yourself", + "problem_share_request_create_shocker_not_found_title": "One or more shockers were not found", + "problem_share_request_create_shocker_not_found_desc": "They may have been removed or do not belong to you.", + "problem_share_request_not_found_title": "Share invite not found", + "problem_share_user_not_found_title": "Share not found", + "problem_share_code_already_linked_title": "Shocker is already linked to your account", + "problem_share_code_cant_link_own_share_code_title": "You cannot redeem your own share code", + "problem_share_code_not_found_title": "Share code not found", + "problem_share_link_expiry_date_in_past_title": "Expiry date cannot be in the past", + "problem_share_link_not_found_title": "Public share not found", + "problem_share_link_shocker_already_in_share_link_title": "Shocker is already in this public share", + "problem_share_link_shocker_not_in_share_link_title": "Shocker is not in this public share", + "problem_shocker_control_no_permission_title": "You do not have permission to control this shocker", + "problem_shocker_control_not_found_title": "Shocker not found", + "problem_shocker_control_paused_title": "Shocker is paused", + "problem_shocker_not_found_title": "Shocker not found", + "problem_signup_registration_disabled_title": "Registration is currently disabled", + "problem_signup_username_or_email_exists_title": "That username or email is already in use", + "problem_turnstile_invalid_title": "Verification failed", + "problem_turnstile_invalid_desc": "Please complete the challenge again and retry.", + "problem_user_not_found_title": "User not found", + "problem_user_privileged_delete_denied_title": "Privileged users cannot be deleted", + "problem_validation_error_title": "Some fields are invalid", + "problem_webhook_not_found_title": "Webhook not found", + "problem_webhook_unsupported_title": "Only Discord webhooks are supported", + "problem_webhook_unsupported_desc": "Use a discord.com URL, not canary or ptb.", + "error_too_many_requests": "Too many requests", + "error_retry_after_one": "Try again in {{count}} second.", + "error_retry_after_other": "Try again in {{count}} seconds.", + "error_unexpected_response": "Unexpected server response", + "error_internal": "Internal error occurred", + "error_network": "Network error occurred", + "dev_banner": "This is the OpenShock DEVELOPMENT environment. No data is saved, and it is regularly overwritten by production data.", + "firmware_channel_bugs_warning": "This channel might contain bugs." +} From c33182b37faf28852829e32d3f25719730bf0936 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Luc=20=E2=99=A5?= Date: Thu, 12 Nov 2026 17:43:29 +0100 Subject: [PATCH 20/27] New translations en.json (Portuguese) [ci skip] --- messages/pt.json | 1055 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 1055 insertions(+) create mode 100644 messages/pt.json diff --git a/messages/pt.json b/messages/pt.json new file mode 100644 index 00000000..ef4df56c --- /dev/null +++ b/messages/pt.json @@ -0,0 +1,1055 @@ +{ + "landing_tagline": "The go-to platform for safe, reliable, real low-latency remote shocking.", + "landing_section_label": "Home", + "landing_hubs_online": "Hubs online right now: ", + "landing_learn_more": "Learn More", + "landing_wiki": "Wiki", + "landing_meta_description": "Welcome to OpenShock, a free and open-source ecosystem to control various shock collars over the internet.", + "instance_meta_description": "Welcome to {{siteName}}, an independent instance of OpenShock, a free and open-source ecosystem to control various shock collars over the internet.", + "header_sidebar_toggle": "Toggle Sidebar", + "header_avatar_alt": "{{name}}'s avatar", + "header_menu_profile": "Profile", + "header_menu_settings": "Settings", + "header_menu_logout": "Logout", + "header_login": "Login", + "header_signup": "Sign Up", + "header_github_title": "OpenShock on GitHub", + "header_discord_title": "Community Discord", + "footer_made_with": "Made with by the OpenShock Team", + "footer_connection_status_label": "Server connection status", + "footer_signalr_state": "SignalR State", + "footer_frontend_version": "Frontend Version", + "footer_frontend_commit_title": "Commit {{commit}}", + "footer_backend_version": "Backend Version", + "footer_backend_commit_title": "Commit {{commit}}", + "footer_language_label": "Language", + "sidebar_home_link_label": "OpenShock home", + "sidebar_group_general": "General", + "sidebar_home": "Home", + "sidebar_shockers": "Shockers", + "sidebar_shared_shockers": "Shared Shockers", + "sidebar_hubs": "Hubs", + "sidebar_user_shares": "User Shares", + "sidebar_public_shares": "Public Shares", + "sidebar_serial_terminal": "Serial Terminal", + "sidebar_group_admin": "Admin", + "sidebar_admin_monitoring": "Monitoring", + "sidebar_admin_online_hubs": "Online Hubs", + "sidebar_admin_online_gateways": "Online Gateways", + "sidebar_admin_management": "Management", + "sidebar_admin_users": "Users", + "sidebar_admin_blacklists": "Blacklists", + "sidebar_admin_webhooks": "Webhooks", + "sidebar_admin_mail": "Mail", + "sidebar_admin_automation_tokens": "Automation Tokens", + "sidebar_admin_configuration": "Configuration", + "sidebar_group_settings": "Settings", + "sidebar_settings_api_tokens": "API Tokens", + "sidebar_settings_sessions": "Sessions", + "sidebar_settings_audit_log": "Audit Log", + "sidebar_settings_connections": "Connections", + "sidebar_settings_account": "Account Settings", + "error_meta_title": "Service Unavailable", + "error_meta_description": "OpenShock is currently unavailable", + "error_meta_logo_alt": "OpenShock Logo", + "error_fallback_message": "Something went wrong.", + "error_not_found_message": "Page not found", + "error_not_found_description": "The page you're looking for doesn't exist.", + "error_unexpected_description": "An unexpected error occurred.", + "error_go_back": "Go back", + "auth_layout_logo_alt": "OpenShock Logo", + "auth_layout_invalid_redirect_removed": "An invalid redirect URL was removed for your safety.", + "auth_activate_breadcrumb": "Activate Account", + "auth_activate_title": "Activate Account", + "auth_activate_activating": "Activating your account...", + "auth_activate_success": "Your account has been activated", + "auth_activate_failed": "This activation link is invalid or has expired", + "auth_activate_missing_token": "Missing activation token", + "auth_activate_continue": "Continue to login", + "auth_activate_toast_success": "Account activated", + "auth_forgot_breadcrumb": "Forgot Password", + "auth_forgot_title": "Forgot Password", + "auth_forgot_description": "Enter your email to reset your password", + "auth_forgot_email_label": "Email", + "auth_forgot_email_placeholder": "Email", + "auth_forgot_submit": "Reset Password", + "auth_forgot_signin_prompt": "Remember your password? Sign in", + "auth_forgot_mail_disabled": "Password resets are unavailable on this instance because it has no mail provider configured. Please contact your administrator for help recovering your account.", + "auth_forgot_toast_sent": "Reset password request has been sent to the given email", + "auth_login_breadcrumb": "Login", + "auth_login_title": "Welcome back", + "auth_login_loading_methods": "Loading available login methods", + "auth_login_choose_method": "Login with one of these methods", + "auth_login_with_account": "Login with your OpenShock Account", + "auth_login_activation_after_signup": "Your account has been created. We've sent an activation link to your email address. Check your inbox and spam folder.", + "auth_login_activation_pending": "Your account isn't activated yet. We've sent an activation link to your email address. Check your inbox and spam folder. If nothing arrives, try logging in again later to get a new link.", + "auth_login_oauth_only": "This account has no password. Sign in with the provider you signed up with.", + "auth_login_oauth_only_with_buttons": "This account has no password. Sign in with the provider you signed up with using the buttons above.", + "auth_login_or_continue_with": "Or continue with", + "auth_login_username_label": "Username or Email", + "auth_login_password_label": "Password", + "auth_login_submit": "Login", + "auth_login_signup_prompt": "Don't have an account? Sign up", + "auth_login_legal": "By clicking Login, you agree to our Terms of Service and Privacy Policy.", + "auth_oauth_create_breadcrumb": "Sign Up With {{provider}}", + "auth_oauth_create_title": "Sign Up With {{provider}}", + "auth_oauth_create_description": "Complete your account details", + "auth_oauth_create_username_label": "Username", + "auth_oauth_create_username_placeholder": "Username", + "auth_oauth_create_email_label": "Email", + "auth_oauth_create_email_placeholder": "Email", + "auth_oauth_create_submit": "Sign Up", + "auth_oauth_create_legal": "By clicking Sign Up, you agree to our Terms of Service and Privacy Policy.", + "auth_oauth_error_breadcrumb": "Authentication Error", + "auth_oauth_error_title": "Authentication Error", + "auth_oauth_error_back": "Back to login", + "auth_reset_breadcrumb": "Reset Password", + "auth_reset_title": "Reset Password", + "auth_reset_checking": "Verifying reset link...", + "auth_reset_choose_password": "Choose a new password for your account", + "auth_reset_invalid": "This reset link is invalid or has expired", + "auth_reset_password_label": "New Password", + "auth_reset_password_placeholder": "New Password", + "auth_reset_confirm_label": "Confirm New Password", + "auth_reset_confirm_placeholder": "Confirm New Password", + "auth_reset_submit": "Reset Password", + "auth_reset_request_new": "Request a new reset link", + "auth_reset_toast_success": "Password has been reset", + "auth_signup_breadcrumb": "Sign Up", + "auth_signup_toast_created_mail": "Account created successfully. Please check your email to verify your account.", + "auth_signup_toast_created_no_mail": "Account created successfully. You can log in now.", + "auth_signup_dialog_title": "Welcome! Thank you for signing up! ❤️", + "auth_signup_dialog_created_mail": "Your account has been created. 🎉 Please check your email to verify your account.", + "auth_signup_dialog_verify_then_login": "After verifying your email, you can log in to your account.", + "auth_signup_dialog_created_no_mail": "Your account has been created and is ready to use. 🎉", + "auth_signup_dialog_login_now": "You can log in to your account now.", + "auth_signup_title": "Create your account", + "auth_signup_loading_methods": "Loading available sign-up methods", + "auth_signup_using_email": "Signing up using email", + "auth_signup_choose_method": "Choose your preferred sign-up method", + "auth_signup_back": "Back", + "auth_signup_username_label": "Username", + "auth_signup_username_placeholder": "John OpenShock", + "auth_signup_email_label": "Email", + "auth_signup_email_placeholder": "john@example.com", + "auth_signup_password_label": "Password", + "auth_signup_password_placeholder": "Password", + "auth_signup_confirm_label": "Confirm Password", + "auth_signup_confirm_placeholder": "Confirm Password", + "auth_signup_submit": "Create Account", + "auth_signup_signin_prompt": "Already have an account? Sign in", + "auth_signup_or": "Or", + "auth_signup_with_email": "Signup with Email", + "auth_signup_legal": "By clicking Create Account, you agree to our Terms of Service and Privacy Policy.", + "auth_verify_breadcrumb": "Verify Email", + "auth_verify_title": "Verify Email", + "auth_verify_verifying": "Verifying your email address...", + "auth_verify_success": "Your email has been verified", + "auth_verify_failed": "This verification link is invalid or has expired", + "auth_verify_missing_token": "Missing verification token", + "auth_verify_continue": "Continue to login", + "auth_verify_toast_success": "Email verified", + "common_cancel": "Cancel", + "common_delete": "Delete", + "common_edit": "Edit", + "common_share": "Share", + "common_copy_id": "Copy ID", + "common_id_copied": "ID copied to clipboard", + "common_open_menu": "Open menu", + "common_refresh": "Refresh", + "common_settings": "Settings", + "common_clear": "Clear", + "common_online": "Online", + "common_offline": "Offline", + "common_paused": "Paused", + "common_resume": "Resume", + "common_resuming": "Resuming...", + "common_coming_soon": "(Coming soon)", + "common_save_changes": "Save Changes", + "common_danger_zone": "Danger Zone", + "common_name": "Name", + "control_intensity": "Intensity", + "control_duration": "Duration", + "control_max_intensity": "Max Intensity", + "control_max_duration": "Max Duration", + "control_vibration": "Vibration", + "control_value": "Value", + "control_live_intensity": "Live intensity", + "control_type_stop": "Stop", + "control_type_shock": "Shock", + "control_type_vibrate": "Vibrate", + "control_type_sound": "Sound", + "live_tooltip_active": "Live via {{gateway}} ({{country}}), {{latency}}ms", + "live_tooltip_connecting": "Connecting...", + "live_tooltip_connect": "Connect to Live Control", + "live_tooltip_hub_start": "Ctrl+click to start the whole hub", + "live_tooltip_hub_stop": "Ctrl+click to stop the whole hub", + "pause_resume_shocker": "Resume shocker", + "pause_pause_shocker": "Pause shocker", + "pause_resume_all": "Resume all shockers", + "pause_pause_all": "Pause all shockers", + "shocker_label": "Shocker", + "shocker_hub": "Hub", + "shocker_select_hub": "Select hub", + "shocker_rf_id": "RF ID", + "shocker_rf_id_invalid": "RF ID must be a whole number between {{min}} and {{max}}.", + "shocker_model": "Model", + "shocker_select_model": "Select model", + "shocker_name_placeholder": "Shocker name", + "shocker_menu_view_logs": "View Logs", + "shocker_delete_title": "Delete Shocker", + "shocker_delete_desc": "Are you sure you want to delete \"{{name}}\"? This action cannot be undone.", + "shocker_toast_deleted": "Shocker \"{{name}}\" deleted", + "shocker_toast_paused": "Shocker paused", + "shocker_toast_resumed": "Shocker resumed", + "shocker_add_desc": "Register a new shocker to one of your hubs.", + "shocker_add_name_placeholder": "My Shocker", + "shockers_title": "Shockers", + "shockers_subtitle": "Every shocker paired to your hubs.", + "shockers_loading": "Loading shockers...", + "shockers_toast_refreshed": "Shockers refreshed", + "shockers_toast_need_hub": "You need to create a hub before adding shockers.", + "shockers_toast_added": "Shocker added", + "shockers_unknown_module": "Unknown module type", + "shockers_add": "Add Shocker", + "shockers_view_mode": "View mode", + "shockers_mode_classic": "Classic", + "shockers_mode_rich": "Rich", + "shockers_mode_simple": "Simple", + "shockers_mode_map": "Map", + "shockers_group_by_hub": "Group by Hub", + "shockers_global_limits": "Global Limits", + "shockers_logs_label": "Logs", + "shockers_empty_title": "No shockers yet", + "shockers_empty_no_hubs": "Create a hub first, then add shockers to it.", + "shockers_empty_has_hubs": "Add a shocker to one of your hubs to get started.", + "shockers_create_hub": "Create a Hub", + "shockers_count_one": "{{count}} shocker", + "shockers_count_other": "{{count}} shockers", + "shared_shockers_title": "Shared Shockers", + "shared_shockers_subtitle": "Shockers other users have shared with you.", + "shared_shockers_empty_title": "No shockers have been shared with you yet.", + "shared_shockers_empty_desc": "When someone shares their shockers with you, they'll appear here.", + "shocker_logs_title": "Shocker Logs", + "shocker_logs_subtitle": "Every control command sent to your shockers.", + "shocker_logs_live_title": "New logs appear in real time", + "shocker_logs_paused_title": "Live updates pause when sorting or viewing a page other than the first", + "shocker_logs_live": "Live", + "shocker_logs_col_time": "Time", + "shocker_logs_col_type": "Type", + "shocker_logs_col_by": "By", + "shocker_logs_filter_label": "Filter by shocker", + "shocker_logs_filter_placeholder": "Search shockers...", + "shocker_logs_filter_all": "All shockers", + "shocker_logs_filter_none": "No matching shockers", + "shocker_edit_title": "Edit Shocker", + "shocker_edit_subtitle": "Change this shocker's details or remove it.", + "shocker_edit_back": "Back to Shockers", + "shocker_edit_load_failed": "Failed to load shocker.", + "shocker_edit_loading": "Loading shocker...", + "shocker_edit_details_title": "Shocker Details", + "shocker_edit_details_desc": "Update the name, RF ID, and model for this shocker.", + "shocker_edit_pause_state": "Pause State", + "shocker_edit_is_paused": "Shocker is paused", + "shocker_edit_is_active": "Shocker is active", + "shocker_edit_toast_updated": "Shocker updated", + "shocker_edit_delete_desc": "Permanently delete this shocker. This action cannot be undone.", + "common_close": "Close", + "common_continue": "Continue", + "common_loading": "Loading...", + "common_previous": "Previous", + "common_next": "Next", + "common_steps": "Steps", + "common_step_label": "Step {{number}}: {{title}}", + "common_copy": "Copy", + "common_copied": "Copied", + "common_never": "Never", + "common_error": "Error: {{message}}", + "terminal_title": "Serial Terminal", + "terminal_connecting": "Connecting...", + "terminal_help_button": "I'm having trouble, help?", + "terminal_back_to_modes": "Back to mode picker", + "terminal_mode_configure": "Configure Device", + "terminal_mode_configure_desc": "Configure WiFi, authentication, and more. Includes an interactive serial console.", + "terminal_mode_flash": "Flash Firmware", + "terminal_mode_flash_desc": "Install or update firmware on a connected device.", + "terminal_mode_raw": "Serial Monitor", + "terminal_mode_raw_desc": "Just the console. Read device logs and send commands.", + "terminal_step_channel": "Select Channel", + "terminal_step_board": "Select Board", + "terminal_go_to_step": "Go to step {{number}}: {{title}}", + "terminal_erase": "Erase before flashing", + "terminal_erase_desc": "Clears all data on the device including existing configs", + "terminal_unsupported": "Your browser does not support this feature.", + "terminal_update_browser": "Please update your browser to the latest version.", + "terminal_use_browsers": "Please use one of the following browsers:", + "terminal_connect_failed_bootloader": "Could not enter bootloader mode", + "terminal_connect_failed": "Device connection failed", + "terminal_connect_failed_desc": "We couldn't establish a serial connection with the device.", + "terminal_quick_tries": "Quick things to try:", + "terminal_try_replug": "Unplug and replug the device.", + "terminal_try_cable": "Try a different USB cable or port.", + "terminal_try_driver": "Make sure the serial driver is installed.", + "terminal_open_troubleshooter": "Open troubleshooter", + "terminal_log_reset_no_device": "Host-side error during reset: no device!", + "terminal_log_reset_error": "Host-side error during reset: {{error}}", + "terminal_log_send_no_device": "Couldn't send: no device!", + "terminal_log_send_error": "Couldn't send: {{error}}", + "terminal_log_firmware_disconnected": "Firmware disconnected: {{error}}", + "terminal_log_erase_failed": "Failed to erase flash: {{error}}", + "terminal_log_hard_reset_failed": "Failed to hard reset: {{error}}", + "terminal_log_flash_complete": "Flash complete", + "terminal_log_flash_failed": "Failed to flash: {{error}}", + "terminal_log_command_failed": "Failed to write application command: {{error}}", + "terminal_help_title": "Troubleshooter", + "terminal_help_desc": "Work through these steps in order. Each one rules out a common cause.", + "terminal_help_step_cable": "USB cable", + "terminal_help_step_port": "USB port", + "terminal_help_step_driver": "Install driver", + "terminal_help_step_manual": "Manual driver update", + "terminal_help_step_discord": "Ask on Discord", + "terminal_help_cable_body": "Many USB-C and micro-USB cables are charge-only and don't carry data. Swap to a known-good data cable (one you've used to transfer files or connect other devices) and reconnect the hub.", + "terminal_help_port_body": "Plug the device directly into a USB port on your computer. Avoid USB hubs, docking stations, and front-panel ports if possible; these are common sources of power and signal issues. If you're on a desktop, try a port on the back of the machine.", + "terminal_help_driver_download": "Download the CP210x driver:", + "terminal_help_driver_extract": "Extract the contents of the zip file to a folder on your computer.", + "terminal_help_driver_run": "Open the folder and run {{installer}}. Follow the prompts to install.", + "terminal_help_driver_reconnect": "Reconnect the device.", + "terminal_help_manual_intro": "If the driver installer ran but the device still doesn't show up:", + "terminal_help_manual_open": "Open Device Manager (press Win + X and select Device Manager).", + "terminal_help_manual_ports": "Under Ports (COM & LPT), look for an entry like:", + "terminal_help_manual_missing": "If it's missing, the device isn't being detected by Windows at all; revisit the cable and port steps.", + "terminal_help_manual_update": "Right-click the device and pick Update Driver.", + "terminal_help_manual_browse": "Choose Browse my computer for drivers and select the folder you extracted the driver zip into. Make sure Include subfolders is checked.", + "terminal_help_manual_success": "On success, the entry should now read {{deviceName}}.", + "terminal_help_discord_intro": "Still stuck after all of the above? Hop into our Discord server and ask in the {{channel}} channel. Please include:", + "terminal_help_discord_os": "your operating system and browser", + "terminal_help_discord_device": "the device you're using (board model, where you got it)", + "terminal_help_discord_tried": "what you've already tried from the previous steps", + "terminal_help_discord_errors": "any error messages or relevant terminal output", + "terminal_help_discord_join": "Join our Discord server", + "terminal_risk_title": "⚠️ UNSTABLE FIRMWARE", + "terminal_risk_intro": "You are about to flash experimental firmware that is known to be unstable.", + "terminal_risk_brick": "This may permanently brick your device, require manual recovery, or render it unusable.", + "terminal_risk_no_support": "We will NOT provide support for issues caused by this firmware.", + "terminal_risk_acknowledge": "I understand this is entirely my responsibility", + "terminal_risk_abort": "Abort", + "terminal_risk_accept": "I ACCEPT FULL RESPONSIBILITY", + "firmware_channel_recommended": "This is the recommended channel.", + "firmware_channel_danger": "DO NOT USE THIS UNLESS YOU KNOW WHAT YOU ARE DOING", + "firmware_channel_stable": "Stable", + "firmware_channel_beta": "Beta", + "firmware_channel_develop": "Develop", + "terminal_board_select": "Select a board...", + "terminal_board_search": "Search boards...", + "terminal_board_none": "No board found.", + "terminal_flash_button": "Flash", + "terminal_flash_progress": "Flash Progress: {{status}}", + "terminal_flash_idle": "Idle", + "terminal_flash_no_device": "No device selected.", + "terminal_flash_resetting": "Resetting...", + "terminal_flash_downloading": "Downloading firmware...", + "terminal_flash_download_failed": "Failed to download firmware.", + "terminal_flash_flashing": "Flashing firmware...", + "terminal_flash_rebooting": "Rebooting device... (Reconnect to power manually if stuck)", + "terminal_flash_done": "Rebooted device! Flashing complete.", + "terminal_port_select": "Select Device", + "terminal_port_disconnect": "Disconnect Device", + "terminal_port_connected": "Device connected: {{id}}", + "terminal_console": "Console", + "terminal_connected_device": "Connected device", + "terminal_resize": "Resize terminal panel", + "terminal_reboot": "Reboot", + "terminal_disconnect": "Disconnect", + "terminal_fullscreen_exit_esc": "Exit fullscreen (Esc)", + "terminal_fullscreen_exit": "Exit fullscreen", + "terminal_fullscreen_fill": "Fill the window", + "terminal_command_label": "Serial command", + "terminal_command_placeholder": "Type a command...", + "terminal_command_send": "Send command", + "terminal_colors": "Colors", + "terminal_colors_menu": "Colors...", + "terminal_colors_label": "Console colors", + "terminal_colors_close": "Close colors", + "terminal_color_input": "{{name}} color", + "terminal_colors_reset": "Reset to defaults", + "terminal_color_bg": "Background", + "terminal_color_fg": "Text", + "terminal_color_ts": "Timestamp", + "terminal_color_error": "Error", + "terminal_color_warning": "Warning", + "terminal_color_info": "Info", + "terminal_color_debug": "Debug", + "terminal_color_verbose": "Verbose", + "terminal_options": "Options", + "terminal_options_label": "Console options", + "terminal_hide_system": "Hide system messages", + "terminal_stick_bottom": "Stick to bottom", + "terminal_raw_output": "Raw output", + "terminal_timestamps": "Timestamps", + "terminal_timestamp_uptime": "Uptime", + "terminal_timestamp_local": "Local", + "terminal_timestamp_ms": "Ms", + "terminal_timestamp_off": "Off", + "terminal_copy_settings": "Copy settings", + "terminal_import_settings": "Import settings", + "terminal_copy_selection": "Copy selection", + "terminal_copy_all": "Copy all output", + "terminal_toast_selection_copied": "Selection copied", + "terminal_toast_output_copied": "Console output copied", + "terminal_toast_settings_copied": "Console settings copied", + "terminal_toast_clipboard_unreadable": "Could not read the clipboard", + "terminal_toast_settings_imported": "Console settings imported", + "terminal_toast_settings_invalid": "Clipboard does not contain console settings", + "common_try_again": "Try again", + "terminal_cfg_intro": "Values are sent to the device via UART. Read the device's response in the console below. Commands without an argument act as getters; use the button next to each field to read the current value.", + "terminal_cfg_rf_title": "RF Transmitter", + "terminal_cfg_rf_desc": "Controls the shocker RF output.", + "terminal_cfg_tx_pin": "TX GPIO pin", + "terminal_cfg_example": "e.g. {{value}}", + "terminal_cfg_read_value": "Read current value", + "terminal_cfg_set": "Set", + "terminal_cfg_read": "Read", + "terminal_cfg_reading": "Reading…", + "terminal_cfg_apply": "Apply", + "terminal_cfg_keepalive": "Keepalive enabled", + "terminal_cfg_keepalive_desc": "Periodically pings paired shockers to keep them awake.", + "terminal_cfg_estop_title": "Emergency Stop", + "terminal_cfg_estop_desc": "Hardware button that halts all output.", + "terminal_cfg_estop_enabled": "EStop enabled", + "terminal_cfg_estop_pin": "EStop GPIO pin", + "terminal_cfg_estop_note": "Note: {{latching}} and {{active}} have no dedicated commands; set them via the JSON config below.", + "terminal_cfg_wifi_title": "WiFi", + "terminal_cfg_wifi_desc": "Station credentials and device hostname.", + "terminal_cfg_hostname": "Hostname", + "terminal_cfg_networks": "Networks (JSON array)", + "terminal_cfg_invalid_json_array": "Must be a valid JSON array", + "terminal_cfg_ap_note": "AP settings ({{ssid}}, {{password}}, {{disabled}}, {{staDisabled}}, {{offlineMode}}) have no dedicated commands; use the JSON config.", + "terminal_cfg_backend_title": "Backend", + "terminal_cfg_backend_desc": "OpenShock server and authentication.", + "terminal_cfg_domain": "Domain", + "terminal_cfg_domain_restart": "Setting the domain will restart the device.", + "terminal_cfg_auth_token": "Auth token", + "terminal_cfg_auth_token_placeholder": "Paste device token", + "terminal_cfg_hide": "Hide", + "terminal_cfg_show": "Show", + "terminal_cfg_serial_title": "Serial Input", + "terminal_cfg_echo": "Echo enabled", + "terminal_cfg_echo_desc": "Print typed characters back to the console.", + "terminal_cfg_advanced_title": "Advanced: full config", + "terminal_cfg_advanced_desc": "For fields without dedicated commands (captive portal, OTA, LAN, etc.), replace the entire config.", + "terminal_cfg_json_config": "JSON config", + "terminal_cfg_invalid_json": "Must be valid JSON", + "terminal_cfg_read_json": "Read current config as JSON", + "terminal_cfg_json_restart": "Applying a JSON config will restart the device.", + "terminal_cfg_raw_config": "Raw FlatBuffer config (base64)", + "terminal_cfg_invalid_base64": "Must be a valid base64 string", + "terminal_cfg_read_raw": "Read current config as base64", + "terminal_cfg_factory_reset": "Factory reset", + "terminal_cfg_factory_reset_desc": "Wipes the entire device configuration.", + "terminal_cfg_factory_reset_title": "Factory reset device?", + "terminal_cfg_factory_reset_action": "Wipe config", + "terminal_cfg_factory_reset_confirm": "This will erase all configuration on the device; WiFi networks, backend credentials, pins, and all other settings. The device will be reset to defaults.", + "terminal_cfg_read_failed_json_title": "Couldn't read the JSON config", + "terminal_cfg_read_failed_raw_title": "Couldn't read the raw config", + "terminal_cfg_read_failed_desc": "The device didn't respond after {{attempts}} attempts.", + "terminal_cfg_common_causes": "Common causes:", + "terminal_cfg_cause_busy": "The device is busy handling another command.", + "terminal_cfg_cause_disconnected": "The device disconnected or rebooted.", + "terminal_cfg_cause_unsupported": "The firmware version doesn't support this command.", + "common_status": "Status", + "common_version": "Version", + "common_created": "Created", + "common_create": "Create", + "common_done": "Done", + "common_enable": "Enable", + "common_disable": "Disable", + "common_are_you_sure": "Are you sure?", + "common_generating": "Generating...", + "hubs_title": "Hubs", + "hubs_subtitle": "Every hub registered to your account.", + "hubs_add": "Add Hub", + "hubs_load_failed": "Failed to load hubs.", + "hubs_empty_title": "No hubs yet", + "hubs_empty_desc": "A hub is the device that relays commands to your shockers. Add one to get started.", + "hubs_create_title": "Create hub", + "hubs_name_label": "Hub Name", + "hubs_name_placeholder": "My Hub", + "hub_toast_not_connected": "Not connected to the server", + "hub_toast_try_later": "Try again in a moment.", + "hub_reboot_title": "Reboot {{name}}?", + "hub_reboot_desc": "The hub will disconnect and restart. Any shockers paired to it stop responding until it comes back online.", + "hub_reboot": "Reboot", + "hub_hotspot_enable_title": "Enable Wi-Fi hotspot on {{name}}?", + "hub_hotspot_disable_title": "Disable Wi-Fi hotspot on {{name}}?", + "hub_hotspot_enable_desc": "The hub broadcasts its own setup network. It stays reachable on your Wi-Fi, but the hotspot is open to anyone in range until you turn it off.", + "hub_hotspot_disable_desc": "The setup hotspot shuts down. If the hub is not already on your Wi-Fi you will need physical access to set it up again.", + "hub_delete_desc": "You are about to delete hub {{name}}.", + "hub_delete_shockers": "This will also delete the following shockers:", + "hub_edit_title": "Edit hub", + "hub_edit_apply": "Apply", + "hub_pair_title_generate": "Generate pair code?", + "hub_pair_title_generated": "Pair code generated", + "hub_pair_title_paired": "Hub paired", + "hub_pair_consumed": "{{name}} consumed this pair code and is now paired.", + "hub_pair_used": "The code has been used and is no longer valid.", + "hub_pair_generated_for": "Pair code generated for {{name}}.", + "hub_copy_now": "The code below will not be accessible later, please copy it now and update clients with it.", + "hub_pair_generate_for": "You are about to generate a pair code for {{name}}.", + "hub_pair_valid_for": "It will be valid for 15 minutes after its creation.", + "hub_pair_one_active": "There is only one active pair code per hub, newly generated ones will override the older active ones.", + "hub_pair_complete": "Pairing complete", + "hub_pair_code_label": "Pair code:", + "hub_pair_copied_close": "Code has been copied, close", + "hub_pair_get": "Get Pair Code", + "hub_token_generated": "Token generated", + "hub_token_generated_for": "New token generated for {{name}}.", + "hub_token_regenerate_for": "You are about to regenerate the token for {{name}}.", + "hub_token_invalidate": "This action will invalidate the current token and disconnect clients using it.", + "hub_token_confirm": "Are you sure you want to do this?", + "hub_token_label": "New token:", + "hub_token_copied_close": "Token has been copied, close", + "hub_token_regenerate": "Regenerate Token", + "hub_menu_update": "Update", + "hub_menu_label": "Hub", + "hub_menu_hotspot_enable": "Enable Wi-Fi hotspot", + "hub_menu_hotspot_disable": "Disable Wi-Fi hotspot", + "hub_menu_pair": "Pair", + "hub_menu_estop": "Emergency Stop", + "hub_update_breadcrumb": "Update", + "hub_update_unknown_hub": "Unknown Hub", + "hub_update_unknown_task": "Unknown Task", + "hub_update_task_metadata": "Fetching Metadata", + "hub_update_task_preparing": "Preparing for Update", + "hub_update_task_flash_fs": "Flashing Filesystem", + "hub_update_task_verify_fs": "Verifying Filesystem", + "hub_update_task_flash_app": "Flashing Application", + "hub_update_task_bootable": "Marking Application Bootable", + "hub_update_task_rebooting": "Rebooting", + "hub_update_status_started": "Started", + "hub_update_status_running": "Running", + "hub_update_status_finished": "Finished", + "hub_update_status_error": "Error", + "hub_update_status_timeout": "Timeout", + "hub_update_confirm_title": "Confirm firmware update", + "hub_update_confirm_desc": "Update {{name}} to version {{version}}?", + "hub_update_unstable_warning": "This version may not be from the stable channel and could contain bugs.", + "hub_update_title": "Update {{name}}", + "hub_update_subtitle": "Manage firmware updates for this hub.", + "hub_update_status_title": "Hub Status", + "hub_update_firmware": "Firmware: {{version}}", + "hub_update_confirm": "Update", + "hub_update_success": "Update completed successfully", + "hub_update_rolled_back": "Device rolled back to previous version", + "hub_update_back": "Back to Hubs", + "hub_update_flash_again": "Flash Again", + "hub_update_card_title": "Firmware Update", + "hub_update_card_desc": "Select a firmware channel and version to install.", + "hub_update_to": "Update to {{version}}", + "hub_update_must_be_online": "Hub must be online to start an update.", + "hub_update_updating_to": "Updating to {{version}}...", + "hub_update_total": "Total", + "hub_update_task": "Task", + "hub_update_history": "Update History", + "hub_update_no_history": "No update history found for this hub.", + "hub_update_col_id": "ID", + "hub_update_col_started": "Started", + "hub_update_col_message": "Message", + "hub_update_loading": "Loading hub information...", + "hub_update_not_found": "Hub not found.", + "home_breadcrumb": "Home", + "home_welcome": "Welcome back", + "home_welcome_name": "Welcome back, {{name}}", + "home_subtitle": "Here's an overview of your OpenShock setup.", + "home_hubs_online": "{{count}} online", + "home_hub_status": "Hub Status", + "home_no_hubs": "No hubs", + "home_all_online": "All online", + "home_all_offline": "All offline", + "home_some_online": "{{online}}/{{total}} online", + "home_quick_links": "Quick Links", + "home_my_shockers": "My Shockers", + "home_my_shockers_desc": "Control your shockers", + "home_hubs_desc": "Manage your hubs", + "home_shared_desc": "Shockers shared with you", + "home_public_desc": "Manage share links", + "home_get_started": "Get Started", + "home_get_started_desc": "You don't have any hubs yet. Create a hub to connect your first device, then add shockers to it.", + "home_set_up_hub": "Set Up a Hub", + "home_first_shocker": "Add Your First Shocker", + "home_first_shocker_desc_one": "You have {{count}} hub set up. Add a shocker to start controlling it.", + "home_first_shocker_desc_other": "You have {{count}} hubs set up. Add a shocker to start controlling it.", + "home_go_to_shockers": "Go to Shockers", + "profile_title": "Profile", + "profile_coming_soon": "Profile is coming soon", + "profile_coming_soon_desc": "Your public profile is not available yet. Account details live under Settings.", + "common_retry": "Retry", + "common_never_used": "Never used", + "common_expires": "Expires {{time}}", + "common_search_placeholder": "Search...", + "common_unknown": "Unknown", + "settings_breadcrumb_account": "Account", + "account_subtitle": "Your sign-in details and account actions.", + "account_change_username": "Change Username", + "account_change_email": "Change Email", + "account_change_password": "Change Password", + "account_username_label": "Username", + "account_email_label": "Email", + "account_password_label": "Password", + "account_new_password_label": "New Password", + "account_confirm_password_label": "Confirm New Password", + "account_oauth_only": "Not available for OAuth-only accounts", + "account_oauth_no_password": "This account signs in via OAuth and has no password.", + "account_diagnostics": "Diagnostics", + "account_diagnostics_desc": "Help us fix crashes and slow API calls. Reports include the error message, stack trace and your IP. Off by default.", + "account_diagnostics_level": "Diagnostics level", + "account_telemetry_off": "Off", + "account_telemetry_off_desc": "Send nothing.", + "account_telemetry_errors": "Errors", + "account_telemetry_errors_desc": "Send browser error reports only.", + "account_telemetry_full": "Full", + "account_telemetry_full_desc": "Error reports plus traces of API calls (no page navigations).", + "account_toast_deactivated": "Account deactivated successfully", + "account_deactivate_title": "Deactivate account", + "account_deactivate_desc": "Are you sure you want to deactivate your account?", + "account_deactivate": "Deactivate Account", + "account_email_title": "Change email", + "account_email_desc": "Enter your new email address and confirm with your current password.", + "account_email_toast_sent": "Verification email sent to {{email}}. Click the link in that email to apply the change.", + "account_new_email": "New Email", + "account_current_password": "Current Password", + "account_password_title": "Change password", + "account_password_desc": "Enter your current password and choose a new one.", + "account_password_toast": "Password has been changed", + "account_username_title": "Change username", + "account_username_desc": "Enter a new username.", + "account_new_username": "New Username", + "account_username_toast": "Username changed successfully", + "tokens_subtitle": "API Tokens are used to authenticate with the OpenShock API.", + "tokens_generate": "Generate Token", + "tokens_toast_refreshed": "Tokens refreshed successfully", + "tokens_empty_title": "No API tokens", + "tokens_empty_desc": "Generate a token to authenticate with the OpenShock API.", + "tokens_created_on": "Created {{date}}", + "tokens_last_used": "Last used {{time}}", + "tokens_never_expires": "Never expires", + "tokens_load_failed": "Failed to load API tokens.", + "token_toast_edited": "Token edited successfully", + "token_name_required": "Name is required", + "token_name_too_long": "Name is too long", + "token_edit_title": "Edit API token", + "token_name_label": "Token Name", + "token_name_placeholder": "Token name...", + "token_permissions": "Permissions", + "token_perm_category_shockers": "Shockers", + "token_perm_category_devices": "Hubs", + "token_perm_category_usershares": "User Shares", + "token_perm_category_publicshares": "Public Shares", + "token_perm_use": "Use", + "token_perm_edit": "Edit", + "token_perm_pause": "Pause", + "token_perm_auth": "Authenticate", + "token_shocker_control": "Shocker Control", + "token_toast_paused": "Token paused", + "token_toast_resumed": "Token resumed", + "token_delete_title": "Delete API token", + "token_delete_desc": "Are you sure you want to delete {{name}}?", + "token_delete_permanent": "This action cannot be undone. This will permanently delete the token.", + "token_toast_deleted": "Token deleted successfully", + "token_resume": "Resume token", + "token_pause": "Pause token", + "token_mode_clamp_desc": "Clamp: requests outside the allowed range are capped to the nearest limit (the min or the max).", + "token_mode_lerp_desc": "Lerp: the full input range is linearly rescaled so it fits within your allowed min–max range.", + "token_paused_desc": "A paused token may not send shocker control messages.", + "token_intensity_range": "Intensity range", + "token_duration_range": "Duration range", + "token_new_breadcrumb": "New", + "token_redirect_not_allowed": "The provided redirect_uri is not allowed. Only loopback addresses or custom application schemes are permitted.", + "token_params_missing": "Required get parameters are missing. Make sure name, redirect_uri, and permissions are provided.", + "token_invalid_permissions": "Invalid permissions provided: {{list}}", + "token_toast_created": "Token created successfully", + "token_request_title": "API Token Request", + "token_access_granted": "Access granted", + "token_shared_redirecting": "The token has been created and shared with the application. Redirecting you back to {{uri}}.", + "token_not_redirected": "If you are not redirected automatically, use the button below.", + "token_finish": "Finish", + "token_generated_title": "API Token Generated", + "token_copy_now": "Please copy your API Token now, you will not be able to view it again later!", + "token_new_title": "New API Token", + "token_external_desc": "An external application is requesting access to your account. Review and adjust the permissions below before allowing access.", + "token_new_desc": "Configure and generate a new API token for your account.", + "token_external_requesting": "{{name}} is requesting an API Token. Your token will be shared with the application at {{uri}}.", + "token_allow": "Allow", + "token_generate": "Generate", + "token_deny": "Deny", + "sessions_subtitle": "Every active session on your account. Revoke any you do not recognize.", + "sessions_unknown_device": "Unknown device", + "sessions_toast_refreshed": "Sessions refreshed successfully", + "sessions_load_failed": "Failed to load sessions.", + "sessions_empty_title": "No active sessions", + "sessions_empty_desc": "Sessions appear here once you sign in from a browser or app.", + "sessions_last_seen": "Last seen {{time}}", + "sessions_signed_in": "Signed in {{time}}", + "session_toast_revoked": "Session revoked successfully", + "session_revoke_title": "Revoke session", + "session_revoke": "Revoke", + "session_revoke_desc": "Are you sure you want to revoke this session?", + "session_revoke_from": "Session logged in from {{ip}} using {{agent}}", + "connections_title": "OAuth Connections", + "connections_subtitle": "Link or unlink third-party accounts to sign in faster and keep your profile in sync.", + "connections_toast_linked": "Account linked.", + "connections_toast_cancelled": "Link flow cancelled.", + "connections_toast_failed": "Linking failed.", + "connections_toast_removed": "Connection removed", + "connections_refreshing": "Refreshing…", + "connections_link_new": "Link new provider", + "connections_empty_title": "No connections yet", + "connections_empty_desc": "Choose “Link new provider” above to connect available providers.", + "connections_unlink": "Unlink", + "connections_load_failed": "Failed to load OAuth connections.", + "connections_unlink_title": "Unlink {{name}}?", + "connections_unlink_title_generic": "Unlink this account?", + "connections_unlink_desc": "You'll no longer be able to sign in with this provider unless you link it again.", + "provider_starting": "Starting {{name}}...", + "provider_link": "Link {{name}}", + "audit_subtitle": "Security-relevant activity on your account. Review anything you do not recognize.", + "audit_col_time": "Time", + "audit_col_action": "Action", + "audit_col_details": "Details", + "audit_col_reason": "Reason", + "audit_col_ip": "IP address", + "audit_col_device": "Device", + "audit_action_login": "Signed in", + "audit_action_logout": "Signed out", + "audit_action_password_changed": "Password changed", + "audit_action_email_change_requested": "Email change requested", + "audit_action_email_changed": "Email changed", + "audit_action_username_changed": "Username changed", + "audit_action_api_token_created": "API token created", + "audit_action_api_token_deleted": "API token deleted", + "audit_action_oauth_connected": "Connection added", + "audit_action_oauth_disconnected": "Connection removed", + "audit_action_account_deactivated": "Account deactivated", + "audit_action_account_reactivated": "Account reactivated", + "audit_action_account_deleted": "Account deleted", + "audit_action_automation_token_created": "Automation token created", + "audit_action_automation_token_updated": "Automation token updated", + "audit_action_automation_token_rotated": "Automation token rotated", + "audit_action_automation_token_deleted": "Automation token deleted", + "audit_action_automation_token_used": "Automation token used", + "audit_meta_session": "Session {{id}}", + "audit_meta_changed": "{{old}} to {{new}}", + "audit_meta_email_requested": "Requested change to {{email}}", + "audit_meta_accounts_removed_one": "{{name}} ({{count}} account removed)", + "audit_meta_accounts_removed_other": "{{name}} ({{count}} accounts removed)", + "audit_meta_scheduled_deletion": "Scheduled for deletion", + "audit_meta_kept": "Kept for reactivation", + "common_view": "View", + "common_save": "Save", + "common_saving": "Saving...", + "common_back": "Back", + "common_shared_by": "Shared by", + "common_user_avatar": "User Avatar", + "common_toast_saved": "Changes saved successfully", + "pause_reason_shocker": "Paused at shocker level", + "pause_reason_shocker_user_share": "Paused at shocker and user share level", + "pause_reason_shocker_public_share": "Paused at shocker and public share level", + "pause_reason_user_share": "Paused at user share level", + "pause_reason_public_share": "Paused at public share level", + "public_shares_subtitle": "A link anyone can use, no account required.", + "public_shares_new": "New Share", + "public_share_never_expires": "Never expires", + "public_shares_empty_title": "No public shares yet", + "public_shares_empty_desc": "Create a link that anyone can use to control your shockers.", + "public_share_expired": "Expired", + "public_share_no_expiry": "No expiry", + "public_share_label": "Public Share", + "public_share_toast_created": "Created new public share", + "public_share_create_title": "Create public share", + "public_share_toast_deleted": "Deleted public share", + "public_share_delete_title": "Delete public share", + "public_share_delete_desc": "Are you sure you want to delete public share {{name}}?", + "public_share_edit_title": "Public Share: {{name}}", + "public_share_edit_subtitle": "Editing: changes apply when you save.", + "public_share_add_shocker": "Add Shocker", + "public_share_toast_added_one": "Added {{count}} shocker to share", + "public_share_toast_added_other": "Added {{count}} shockers to share", + "public_share_empty_shockers_title": "No shockers in this share", + "public_share_empty_shockers_desc": "Add a shocker and anyone with the link will be able to control it.", + "public_share_load_failed": "Error fetching public share details", + "public_share_paused_here": "Paused for this share", + "public_share_resume_shocker": "Resume shocker", + "public_share_pause_shocker": "Pause shocker", + "public_share_remove": "Remove from share", + "public_share_toast_removed": "Shocker removed from share", + "public_share_add_title": "Add shockers", + "public_share_add_desc": "Add shockers to this public share. You can set their limits once they are added.", + "public_share_add_placeholder": "Select shockers to share...", + "public_share_add_no_match": "No matching shockers", + "public_share_add_submit": "Add Shockers", + "public_share_view_loading": "Loading share details...", + "public_share_view_title": "Public Share Link", + "public_share_view_desc": "Enter as a guest or login with your OpenShock account", + "public_share_view_guest_name": "Guest Name", + "public_share_view_enter": "Enter", + "public_share_view_enter_guest": "Enter as Guest", + "public_share_login": "Login", + "perm_shock_on": "Shock enabled", + "perm_shock_off": "Shock disabled", + "perm_vibrate_on": "Vibrate enabled", + "perm_vibrate_off": "Vibrate disabled", + "perm_sound_on": "Sound enabled", + "perm_sound_off": "Sound disabled", + "perm_live_on": "Live enabled", + "perm_live_off": "Live disabled", + "perm_live_control": "Live Control", + "user_selector_avatar_of": "{{name}}'s avatar", + "user_selector_placeholder": "Enter user name", + "user_selector_aria": "Username to search", + "user_selector_search": "Search user", + "user_selector_found": "User found", + "common_remove": "Remove", + "user_shares_subtitle": "Direct permanent shares with other users.", + "user_shares_toast_invited": "Sent a shocker invite to {{name}}", + "user_shares_redeem": "Redeem Code", + "user_shares_new": "New Share", + "user_shares_tab_shares": "Shares", + "user_shares_tab_incoming": "Shared with Me", + "user_shares_tab_invites": "Invites", + "share_code_create_title": "New share code", + "share_code_create_desc": "Create a Share Code or Invite", + "share_code_shocker_placeholder": "Select shockers to share...", + "share_code_no_match": "No matching shockers", + "share_code_send_invite": "Send Share Invite", + "share_code_create": "Create Share Code", + "share_code_created_title": "Share code generated", + "share_code_created_desc": "Please copy share code or code link!", + "share_code_redeem_title": "Redeem share code", + "share_code_redeem_desc": "Enter the share code to redeem", + "share_code_redeem_placeholder": "Enter share code", + "share_code_redeemed": "Redeemed successfully!", + "share_code_shared_shockers": "Shared shockers", + "share_code_redeeming": "Redeeming...", + "share_code_redeem": "Redeem", + "incoming_shares_empty_title": "Nothing shared with you", + "incoming_shares_empty_desc": "No one has shared a shocker with you yet.", + "incoming_share_toast_removed": "Removed share for {{name}}", + "incoming_share_remove_title": "Remove Share", + "incoming_share_remove_desc": "Are you sure you want to remove the share for {{name}}?", + "incoming_share_toast_removed_shocker": "Removed {{shocker}} shared by {{name}}", + "incoming_share_remove_shocker_title": "Remove this shared shocker?", + "incoming_share_remove_shocker_desc": "Are you sure you want to remove the shocker share {{shocker}} by {{name}}?", + "incoming_share_manage_from": "Manage shares from", + "share_remove": "Remove share", + "invites_empty_title": "No invites yet", + "invites_empty_desc": "You have no incoming or outgoing share invites.", + "invites_outgoing": "Outgoing", + "invites_outgoing_empty_title": "No outgoing invites", + "invites_outgoing_empty_desc": "You have no outgoing share invites.", + "invites_incoming": "Incoming", + "invites_incoming_empty_title": "No incoming invites", + "invites_incoming_empty_desc": "You have no incoming share invites.", + "invite_toast_accepted": "Accepted share invite from {{name}}", + "invite_toast_declined": "Declined share invite from {{name}}", + "invite_deny_title": "Deny Invite", + "invite_deny_label": "Deny Invite", + "invite_deny": "Deny", + "invite_deny_desc": "Are you sure you want to deny the invite from {{name}}?", + "invite_accept": "Accept Invite", + "invite_toast_cancelled_for": "Cancelled invite for {{name}} ({{id}})", + "invite_toast_cancelled": "Cancelled invite {{id}}", + "invite_cancel_title": "Cancel Invite", + "invite_cancel": "Cancel", + "invite_cancel_for_desc": "Are you sure you want to cancel the invite for {{name}}?", + "invite_cancel_code_desc": "Are you sure you want to cancel the invite with code {{code}}?", + "invite_cancel_outstanding": "Cancel Outstanding Invite", + "outgoing_shares_empty_title": "No shared shockers", + "outgoing_shares_empty_desc": "You haven't shared any shockers with other users yet.", + "outgoing_share_toast_removed": "Removed shocker share {{name}}", + "outgoing_share_remove_title": "Stop sharing this shocker?", + "outgoing_share_editing_for": "Editing shares for", + "outgoing_share_limits": "Limits & Permissions", + "outgoing_share_same": "Same restrictions on every shocker", + "outgoing_share_per_desc": "Tune restrictions per shocker", + "outgoing_share_all": "All", + "outgoing_share_per": "Per shocker", + "outgoing_share_remove_desc": "Are you sure you want to stop sharing {{shocker}} with {{name}}?", + "report_breadcrumb": "Report API Tokens", + "report_toast_clipboard_failed": "Failed to read clipboard: {{error}}", + "report_title": "Report Leaked API Tokens", + "report_paste": "Paste from clipboard", + "report_warning": "This form is only for reporting accidentally leaked API tokens.", + "report_abuse_warning": "Intentional abuse will result in bans or severe endpoint restrictions.", + "report_detected": "Detected Tokens", + "report_invalid": "One or more tokens appear to be invalid. Please check for formatting issues.", + "report_acknowledge": "I confirm I understand what this feature is for and accept responsibility.", + "report_submit": "Submit Report", + "turnstile_disabled": "Turnstile disabled", + "common_internal_error": "Internal error", + "resend_toast_sent": "Activation email sent. Check your inbox and spam folder.", + "resend_toast_throttled": "Too many activation emails have been requested. Please try again later.", + "resend_toast_unavailable": "No activation email can be resent from this browser. If your account isn't activated yet, logging in sends a new link.", + "resend_button": "Didn't get the email? Resend", + "expiration_label": "Expiration", + "expiration_never": "Never", + "expiration_custom": "Custom", + "expiration_days_one": "{{count}} Day", + "expiration_days_other": "{{count}} Days", + "expiration_required": "Expire date is required", + "expiration_never_desc": "This will never expire", + "expiration_expires_at": "Expires {{time}} ({{date}})", + "date_picker_placeholder": "Pick a date", + "telemetry_toast_title": "Help improve OpenShock?", + "telemetry_toast_desc": "Send diagnostics to help us fix crashes and slow API calls. Reports include the error message, stack trace and your IP. You can change this any time in Account settings.", + "telemetry_toast_no": "No thanks", + "telemetry_toast_errors": "Errors only", + "telemetry_toast_full": "Full", + "table_show_details": "Show details", + "table_hide_details": "Hide details", + "table_no_results": "No results.", + "table_sort_asc": "Sort by {{name}}, ascending", + "table_sort_desc": "Sort by {{name}}, descending", + "table_sort_none": "Sort by {{name}}, unsorted", + "cell_na": "N/A", + "cell_not_applicable": "Not applicable", + "cell_invalid": "Invalid", + "cell_unavailable": "Unavailable", + "cell_none": "None", + "oauth_login_with": "Login with {{provider}}", + "oauth_signup_with": "Signup with {{provider}}", + "signalr_connect_failed": "Failed to connect to server!", + "signalr_disconnect_failed": "Encountered error while disconnecting from server!", + "signalr_invalid_update": "Received invalid update from server!", + "signalr_invalid_log": "Received invalid log data from server!", + "signalr_invalid_ota": "Received invalid firmware update data from server!", + "ota_toast_failed": "Hub firmware update failed: {{message}}", + "ota_toast_succeeded": "Hub firmware update completed successfully!", + "ota_toast_rolled_back": "Hub firmware rolled back to previous version", + "lcg_connect_failed": "Failed to connect to live control gateway", + "terminal_toast_bootloader_failed": "Failed to enter bootloader: {{error}}", + "terminal_toast_app_mode_failed": "Failed to enter application mode: {{error}}", + "problem_account_account_not_activated_title": "Account not activated", + "problem_account_account_not_activated_desc": "Check your inbox for the activation email.", + "problem_account_activation_not_found_title": "Activation link is invalid", + "problem_account_activation_not_found_desc": "The link may have expired or already been used.", + "problem_account_activation_resend_too_many_title": "Too many activation emails requested", + "problem_account_activation_resend_too_many_desc": "Please wait a while before trying again.", + "problem_account_activation_resend_unavailable_title": "Cannot resend activation email", + "problem_account_activation_resend_unavailable_desc": "Log in again to request a new activation link.", + "problem_account_deactivate_already_deactivated_title": "Account is already deactivated", + "problem_account_deactivate_denied_privileged_title": "Privileged accounts cannot be deactivated", + "problem_account_deactivate_unauthorized_title": "You are not allowed to do this", + "problem_account_deactivated_title": "This account has been deactivated", + "problem_account_email_already_in_use_title": "That email address is already in use", + "problem_account_email_invalid_title": "That email address is not valid", + "problem_account_email_taken_title": "That email address is already in use", + "problem_account_email_too_many_requests_title": "Too many email change requests", + "problem_account_email_too_many_requests_desc": "Please wait a while before trying again.", + "problem_account_email_unchanged_title": "That is already your email address", + "problem_account_email_verify_not_found_title": "Verification link is invalid", + "problem_account_email_verify_not_found_desc": "The link may have expired or already been used.", + "problem_account_o_auth_only_title": "This account has no password", + "problem_account_o_auth_only_desc": "Sign in with the provider you signed up with.", + "problem_account_password_not_set_title": "No password set", + "problem_account_password_not_set_desc": "This account signs in through an external provider.", + "problem_account_password_old_password_invalid_title": "Current password is incorrect", + "problem_account_username_invalid_title": "That username is not allowed", + "problem_account_username_recently_changed_title": "Username changed too recently", + "problem_account_username_recently_changed_desc": "You can change your username once every 7 days.", + "problem_account_username_taken_title": "That username is already taken", + "problem_admin_user_deactivated_title": "This user is deactivated", + "problem_admin_user_not_activated_title": "This user has not been activated yet", + "problem_api_token_can_only_delete_self_title": "An API token can only delete itself", + "problem_api_token_not_found_title": "API token not found", + "problem_api_token_paused_title": "This API token is paused", + "problem_assign_lcg_bad_schema_version_title": "Unsupported hub protocol version", + "problem_assign_lcg_bad_schema_version_desc": "Update the hub firmware to connect.", + "problem_assign_lcg_no_lcg_available_title": "No gateway available", + "problem_assign_lcg_no_lcg_available_desc": "No live control gateway is available right now. Please try again later.", + "problem_authentication_account_deactivated_title": "This account has been deactivated", + "problem_authentication_account_not_activated_title": "This account has not been activated", + "problem_authentication_cookie_missing_or_invalid_title": "You are not logged in", + "problem_authentication_cookie_missing_or_invalid_desc": "Your session may have expired. Please log in again.", + "problem_authentication_header_missing_or_invalid_title": "Invalid API token", + "problem_authentication_session_invalid_title": "Session expired", + "problem_authentication_session_invalid_desc": "Please log in again.", + "problem_authentication_token_invalid_title": "Invalid API token", + "problem_authentication_unknown_error_title": "Authentication failed", + "problem_authorization_policy_not_met_title": "You do not have permission to do this", + "problem_authorization_token_only_title": "This action requires an API token", + "problem_authorization_token_permission_missing_title": "This API token is missing a required permission", + "problem_authorization_unknown_error_title": "Authorization failed", + "problem_authorization_user_session_only_title": "This action requires a logged-in session", + "problem_automation_token_not_allowed_for_account_title": "Automation tokens cannot be used with privileged accounts", + "problem_configuration_already_exists_title": "A configuration entry with that name already exists", + "problem_configuration_invalid_name_format_title": "Invalid configuration name", + "problem_configuration_invalid_name_format_desc": "Only A to Z and underscores are allowed.", + "problem_configuration_invalid_value_format_title": "Value does not match the configuration type", + "problem_configuration_not_found_title": "Configuration entry not found", + "problem_control_stats_invalid_range_title": "The from date must not be after the to date", + "problem_control_stats_invalid_time_zone_title": "Unknown time zone", + "problem_control_stats_missing_capability_title": "Control statistics are not available on this server", + "problem_device_not_found_title": "Hub not found", + "problem_device_not_online_title": "Hub is offline", + "problem_device_too_many_hubs_title": "You have reached the maximum number of hubs", + "problem_device_too_many_shockers_title": "This hub has reached its maximum number of shockers", + "problem_endpoint_retired_title": "This feature is no longer available", + "problem_expression_error_title": "Invalid filter expression", + "problem_internal_server_error_title": "Something went wrong on our end", + "problem_login_invalid_credentials_title": "Invalid username or password", + "problem_login_invalid_domain_title": "Logging in from this address is not allowed", + "problem_o_auth_connection_already_exists_title": "Your account is already connected to this provider", + "problem_o_auth_connection_already_linked_title": "This external account is already linked to another user", + "problem_o_auth_flow_anonymous_only_title": "You are already signed in", + "problem_o_auth_flow_mismatch_title": "Sign-in attempt does not match", + "problem_o_auth_flow_mismatch_desc": "Please start over.", + "problem_o_auth_flow_missing_data_title": "The provider did not return your account details", + "problem_o_auth_flow_missing_data_desc": "Please try again.", + "problem_o_auth_flow_not_found_title": "Sign-in attempt expired", + "problem_o_auth_flow_not_found_desc": "Please start over.", + "problem_o_auth_flow_unsupported_title": "Unsupported sign-in flow", + "problem_o_auth_internal_error_title": "Something went wrong during sign-in", + "problem_o_auth_internal_error_desc": "Please try again in a moment.", + "problem_o_auth_link_authenticated_user_only_title": "You must be signed in to link an external account", + "problem_o_auth_provider_mismatch_title": "Sign-in attempt does not match the provider", + "problem_o_auth_provider_mismatch_desc": "Please start over.", + "problem_o_auth_provider_unsupported_title": "This sign-in provider is not supported", + "problem_pair_code_not_found_title": "Pair code not found", + "problem_password_reset_not_found_title": "Password reset link is invalid", + "problem_password_reset_not_found_desc": "The link may have expired or already been used.", + "problem_session_not_found_title": "Session not found", + "problem_share_get_no_shares_title": "You have no shares with this user", + "problem_share_request_create_cannot_share_with_self_title": "You cannot share with yourself", + "problem_share_request_create_shocker_not_found_title": "One or more shockers were not found", + "problem_share_request_create_shocker_not_found_desc": "They may have been removed or do not belong to you.", + "problem_share_request_not_found_title": "Share invite not found", + "problem_share_user_not_found_title": "Share not found", + "problem_share_code_already_linked_title": "Shocker is already linked to your account", + "problem_share_code_cant_link_own_share_code_title": "You cannot redeem your own share code", + "problem_share_code_not_found_title": "Share code not found", + "problem_share_link_expiry_date_in_past_title": "Expiry date cannot be in the past", + "problem_share_link_not_found_title": "Public share not found", + "problem_share_link_shocker_already_in_share_link_title": "Shocker is already in this public share", + "problem_share_link_shocker_not_in_share_link_title": "Shocker is not in this public share", + "problem_shocker_control_no_permission_title": "You do not have permission to control this shocker", + "problem_shocker_control_not_found_title": "Shocker not found", + "problem_shocker_control_paused_title": "Shocker is paused", + "problem_shocker_not_found_title": "Shocker not found", + "problem_signup_registration_disabled_title": "Registration is currently disabled", + "problem_signup_username_or_email_exists_title": "That username or email is already in use", + "problem_turnstile_invalid_title": "Verification failed", + "problem_turnstile_invalid_desc": "Please complete the challenge again and retry.", + "problem_user_not_found_title": "User not found", + "problem_user_privileged_delete_denied_title": "Privileged users cannot be deleted", + "problem_validation_error_title": "Some fields are invalid", + "problem_webhook_not_found_title": "Webhook not found", + "problem_webhook_unsupported_title": "Only Discord webhooks are supported", + "problem_webhook_unsupported_desc": "Use a discord.com URL, not canary or ptb.", + "error_too_many_requests": "Too many requests", + "error_retry_after_one": "Try again in {{count}} second.", + "error_retry_after_other": "Try again in {{count}} seconds.", + "error_unexpected_response": "Unexpected server response", + "error_internal": "Internal error occurred", + "error_network": "Network error occurred", + "dev_banner": "This is the OpenShock DEVELOPMENT environment. No data is saved, and it is regularly overwritten by production data.", + "firmware_channel_bugs_warning": "This channel might contain bugs." +} From 40fe08e68ec9406491c2d78344d9df40922ac430 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Luc=20=E2=99=A5?= Date: Thu, 12 Nov 2026 17:43:30 +0100 Subject: [PATCH 21/27] New translations en.json (Russian) [ci skip] --- messages/ru.json | 1055 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 1055 insertions(+) create mode 100644 messages/ru.json diff --git a/messages/ru.json b/messages/ru.json new file mode 100644 index 00000000..ef4df56c --- /dev/null +++ b/messages/ru.json @@ -0,0 +1,1055 @@ +{ + "landing_tagline": "The go-to platform for safe, reliable, real low-latency remote shocking.", + "landing_section_label": "Home", + "landing_hubs_online": "Hubs online right now: ", + "landing_learn_more": "Learn More", + "landing_wiki": "Wiki", + "landing_meta_description": "Welcome to OpenShock, a free and open-source ecosystem to control various shock collars over the internet.", + "instance_meta_description": "Welcome to {{siteName}}, an independent instance of OpenShock, a free and open-source ecosystem to control various shock collars over the internet.", + "header_sidebar_toggle": "Toggle Sidebar", + "header_avatar_alt": "{{name}}'s avatar", + "header_menu_profile": "Profile", + "header_menu_settings": "Settings", + "header_menu_logout": "Logout", + "header_login": "Login", + "header_signup": "Sign Up", + "header_github_title": "OpenShock on GitHub", + "header_discord_title": "Community Discord", + "footer_made_with": "Made with by the OpenShock Team", + "footer_connection_status_label": "Server connection status", + "footer_signalr_state": "SignalR State", + "footer_frontend_version": "Frontend Version", + "footer_frontend_commit_title": "Commit {{commit}}", + "footer_backend_version": "Backend Version", + "footer_backend_commit_title": "Commit {{commit}}", + "footer_language_label": "Language", + "sidebar_home_link_label": "OpenShock home", + "sidebar_group_general": "General", + "sidebar_home": "Home", + "sidebar_shockers": "Shockers", + "sidebar_shared_shockers": "Shared Shockers", + "sidebar_hubs": "Hubs", + "sidebar_user_shares": "User Shares", + "sidebar_public_shares": "Public Shares", + "sidebar_serial_terminal": "Serial Terminal", + "sidebar_group_admin": "Admin", + "sidebar_admin_monitoring": "Monitoring", + "sidebar_admin_online_hubs": "Online Hubs", + "sidebar_admin_online_gateways": "Online Gateways", + "sidebar_admin_management": "Management", + "sidebar_admin_users": "Users", + "sidebar_admin_blacklists": "Blacklists", + "sidebar_admin_webhooks": "Webhooks", + "sidebar_admin_mail": "Mail", + "sidebar_admin_automation_tokens": "Automation Tokens", + "sidebar_admin_configuration": "Configuration", + "sidebar_group_settings": "Settings", + "sidebar_settings_api_tokens": "API Tokens", + "sidebar_settings_sessions": "Sessions", + "sidebar_settings_audit_log": "Audit Log", + "sidebar_settings_connections": "Connections", + "sidebar_settings_account": "Account Settings", + "error_meta_title": "Service Unavailable", + "error_meta_description": "OpenShock is currently unavailable", + "error_meta_logo_alt": "OpenShock Logo", + "error_fallback_message": "Something went wrong.", + "error_not_found_message": "Page not found", + "error_not_found_description": "The page you're looking for doesn't exist.", + "error_unexpected_description": "An unexpected error occurred.", + "error_go_back": "Go back", + "auth_layout_logo_alt": "OpenShock Logo", + "auth_layout_invalid_redirect_removed": "An invalid redirect URL was removed for your safety.", + "auth_activate_breadcrumb": "Activate Account", + "auth_activate_title": "Activate Account", + "auth_activate_activating": "Activating your account...", + "auth_activate_success": "Your account has been activated", + "auth_activate_failed": "This activation link is invalid or has expired", + "auth_activate_missing_token": "Missing activation token", + "auth_activate_continue": "Continue to login", + "auth_activate_toast_success": "Account activated", + "auth_forgot_breadcrumb": "Forgot Password", + "auth_forgot_title": "Forgot Password", + "auth_forgot_description": "Enter your email to reset your password", + "auth_forgot_email_label": "Email", + "auth_forgot_email_placeholder": "Email", + "auth_forgot_submit": "Reset Password", + "auth_forgot_signin_prompt": "Remember your password? Sign in", + "auth_forgot_mail_disabled": "Password resets are unavailable on this instance because it has no mail provider configured. Please contact your administrator for help recovering your account.", + "auth_forgot_toast_sent": "Reset password request has been sent to the given email", + "auth_login_breadcrumb": "Login", + "auth_login_title": "Welcome back", + "auth_login_loading_methods": "Loading available login methods", + "auth_login_choose_method": "Login with one of these methods", + "auth_login_with_account": "Login with your OpenShock Account", + "auth_login_activation_after_signup": "Your account has been created. We've sent an activation link to your email address. Check your inbox and spam folder.", + "auth_login_activation_pending": "Your account isn't activated yet. We've sent an activation link to your email address. Check your inbox and spam folder. If nothing arrives, try logging in again later to get a new link.", + "auth_login_oauth_only": "This account has no password. Sign in with the provider you signed up with.", + "auth_login_oauth_only_with_buttons": "This account has no password. Sign in with the provider you signed up with using the buttons above.", + "auth_login_or_continue_with": "Or continue with", + "auth_login_username_label": "Username or Email", + "auth_login_password_label": "Password", + "auth_login_submit": "Login", + "auth_login_signup_prompt": "Don't have an account? Sign up", + "auth_login_legal": "By clicking Login, you agree to our Terms of Service and Privacy Policy.", + "auth_oauth_create_breadcrumb": "Sign Up With {{provider}}", + "auth_oauth_create_title": "Sign Up With {{provider}}", + "auth_oauth_create_description": "Complete your account details", + "auth_oauth_create_username_label": "Username", + "auth_oauth_create_username_placeholder": "Username", + "auth_oauth_create_email_label": "Email", + "auth_oauth_create_email_placeholder": "Email", + "auth_oauth_create_submit": "Sign Up", + "auth_oauth_create_legal": "By clicking Sign Up, you agree to our Terms of Service and Privacy Policy.", + "auth_oauth_error_breadcrumb": "Authentication Error", + "auth_oauth_error_title": "Authentication Error", + "auth_oauth_error_back": "Back to login", + "auth_reset_breadcrumb": "Reset Password", + "auth_reset_title": "Reset Password", + "auth_reset_checking": "Verifying reset link...", + "auth_reset_choose_password": "Choose a new password for your account", + "auth_reset_invalid": "This reset link is invalid or has expired", + "auth_reset_password_label": "New Password", + "auth_reset_password_placeholder": "New Password", + "auth_reset_confirm_label": "Confirm New Password", + "auth_reset_confirm_placeholder": "Confirm New Password", + "auth_reset_submit": "Reset Password", + "auth_reset_request_new": "Request a new reset link", + "auth_reset_toast_success": "Password has been reset", + "auth_signup_breadcrumb": "Sign Up", + "auth_signup_toast_created_mail": "Account created successfully. Please check your email to verify your account.", + "auth_signup_toast_created_no_mail": "Account created successfully. You can log in now.", + "auth_signup_dialog_title": "Welcome! Thank you for signing up! ❤️", + "auth_signup_dialog_created_mail": "Your account has been created. 🎉 Please check your email to verify your account.", + "auth_signup_dialog_verify_then_login": "After verifying your email, you can log in to your account.", + "auth_signup_dialog_created_no_mail": "Your account has been created and is ready to use. 🎉", + "auth_signup_dialog_login_now": "You can log in to your account now.", + "auth_signup_title": "Create your account", + "auth_signup_loading_methods": "Loading available sign-up methods", + "auth_signup_using_email": "Signing up using email", + "auth_signup_choose_method": "Choose your preferred sign-up method", + "auth_signup_back": "Back", + "auth_signup_username_label": "Username", + "auth_signup_username_placeholder": "John OpenShock", + "auth_signup_email_label": "Email", + "auth_signup_email_placeholder": "john@example.com", + "auth_signup_password_label": "Password", + "auth_signup_password_placeholder": "Password", + "auth_signup_confirm_label": "Confirm Password", + "auth_signup_confirm_placeholder": "Confirm Password", + "auth_signup_submit": "Create Account", + "auth_signup_signin_prompt": "Already have an account? Sign in", + "auth_signup_or": "Or", + "auth_signup_with_email": "Signup with Email", + "auth_signup_legal": "By clicking Create Account, you agree to our Terms of Service and Privacy Policy.", + "auth_verify_breadcrumb": "Verify Email", + "auth_verify_title": "Verify Email", + "auth_verify_verifying": "Verifying your email address...", + "auth_verify_success": "Your email has been verified", + "auth_verify_failed": "This verification link is invalid or has expired", + "auth_verify_missing_token": "Missing verification token", + "auth_verify_continue": "Continue to login", + "auth_verify_toast_success": "Email verified", + "common_cancel": "Cancel", + "common_delete": "Delete", + "common_edit": "Edit", + "common_share": "Share", + "common_copy_id": "Copy ID", + "common_id_copied": "ID copied to clipboard", + "common_open_menu": "Open menu", + "common_refresh": "Refresh", + "common_settings": "Settings", + "common_clear": "Clear", + "common_online": "Online", + "common_offline": "Offline", + "common_paused": "Paused", + "common_resume": "Resume", + "common_resuming": "Resuming...", + "common_coming_soon": "(Coming soon)", + "common_save_changes": "Save Changes", + "common_danger_zone": "Danger Zone", + "common_name": "Name", + "control_intensity": "Intensity", + "control_duration": "Duration", + "control_max_intensity": "Max Intensity", + "control_max_duration": "Max Duration", + "control_vibration": "Vibration", + "control_value": "Value", + "control_live_intensity": "Live intensity", + "control_type_stop": "Stop", + "control_type_shock": "Shock", + "control_type_vibrate": "Vibrate", + "control_type_sound": "Sound", + "live_tooltip_active": "Live via {{gateway}} ({{country}}), {{latency}}ms", + "live_tooltip_connecting": "Connecting...", + "live_tooltip_connect": "Connect to Live Control", + "live_tooltip_hub_start": "Ctrl+click to start the whole hub", + "live_tooltip_hub_stop": "Ctrl+click to stop the whole hub", + "pause_resume_shocker": "Resume shocker", + "pause_pause_shocker": "Pause shocker", + "pause_resume_all": "Resume all shockers", + "pause_pause_all": "Pause all shockers", + "shocker_label": "Shocker", + "shocker_hub": "Hub", + "shocker_select_hub": "Select hub", + "shocker_rf_id": "RF ID", + "shocker_rf_id_invalid": "RF ID must be a whole number between {{min}} and {{max}}.", + "shocker_model": "Model", + "shocker_select_model": "Select model", + "shocker_name_placeholder": "Shocker name", + "shocker_menu_view_logs": "View Logs", + "shocker_delete_title": "Delete Shocker", + "shocker_delete_desc": "Are you sure you want to delete \"{{name}}\"? This action cannot be undone.", + "shocker_toast_deleted": "Shocker \"{{name}}\" deleted", + "shocker_toast_paused": "Shocker paused", + "shocker_toast_resumed": "Shocker resumed", + "shocker_add_desc": "Register a new shocker to one of your hubs.", + "shocker_add_name_placeholder": "My Shocker", + "shockers_title": "Shockers", + "shockers_subtitle": "Every shocker paired to your hubs.", + "shockers_loading": "Loading shockers...", + "shockers_toast_refreshed": "Shockers refreshed", + "shockers_toast_need_hub": "You need to create a hub before adding shockers.", + "shockers_toast_added": "Shocker added", + "shockers_unknown_module": "Unknown module type", + "shockers_add": "Add Shocker", + "shockers_view_mode": "View mode", + "shockers_mode_classic": "Classic", + "shockers_mode_rich": "Rich", + "shockers_mode_simple": "Simple", + "shockers_mode_map": "Map", + "shockers_group_by_hub": "Group by Hub", + "shockers_global_limits": "Global Limits", + "shockers_logs_label": "Logs", + "shockers_empty_title": "No shockers yet", + "shockers_empty_no_hubs": "Create a hub first, then add shockers to it.", + "shockers_empty_has_hubs": "Add a shocker to one of your hubs to get started.", + "shockers_create_hub": "Create a Hub", + "shockers_count_one": "{{count}} shocker", + "shockers_count_other": "{{count}} shockers", + "shared_shockers_title": "Shared Shockers", + "shared_shockers_subtitle": "Shockers other users have shared with you.", + "shared_shockers_empty_title": "No shockers have been shared with you yet.", + "shared_shockers_empty_desc": "When someone shares their shockers with you, they'll appear here.", + "shocker_logs_title": "Shocker Logs", + "shocker_logs_subtitle": "Every control command sent to your shockers.", + "shocker_logs_live_title": "New logs appear in real time", + "shocker_logs_paused_title": "Live updates pause when sorting or viewing a page other than the first", + "shocker_logs_live": "Live", + "shocker_logs_col_time": "Time", + "shocker_logs_col_type": "Type", + "shocker_logs_col_by": "By", + "shocker_logs_filter_label": "Filter by shocker", + "shocker_logs_filter_placeholder": "Search shockers...", + "shocker_logs_filter_all": "All shockers", + "shocker_logs_filter_none": "No matching shockers", + "shocker_edit_title": "Edit Shocker", + "shocker_edit_subtitle": "Change this shocker's details or remove it.", + "shocker_edit_back": "Back to Shockers", + "shocker_edit_load_failed": "Failed to load shocker.", + "shocker_edit_loading": "Loading shocker...", + "shocker_edit_details_title": "Shocker Details", + "shocker_edit_details_desc": "Update the name, RF ID, and model for this shocker.", + "shocker_edit_pause_state": "Pause State", + "shocker_edit_is_paused": "Shocker is paused", + "shocker_edit_is_active": "Shocker is active", + "shocker_edit_toast_updated": "Shocker updated", + "shocker_edit_delete_desc": "Permanently delete this shocker. This action cannot be undone.", + "common_close": "Close", + "common_continue": "Continue", + "common_loading": "Loading...", + "common_previous": "Previous", + "common_next": "Next", + "common_steps": "Steps", + "common_step_label": "Step {{number}}: {{title}}", + "common_copy": "Copy", + "common_copied": "Copied", + "common_never": "Never", + "common_error": "Error: {{message}}", + "terminal_title": "Serial Terminal", + "terminal_connecting": "Connecting...", + "terminal_help_button": "I'm having trouble, help?", + "terminal_back_to_modes": "Back to mode picker", + "terminal_mode_configure": "Configure Device", + "terminal_mode_configure_desc": "Configure WiFi, authentication, and more. Includes an interactive serial console.", + "terminal_mode_flash": "Flash Firmware", + "terminal_mode_flash_desc": "Install or update firmware on a connected device.", + "terminal_mode_raw": "Serial Monitor", + "terminal_mode_raw_desc": "Just the console. Read device logs and send commands.", + "terminal_step_channel": "Select Channel", + "terminal_step_board": "Select Board", + "terminal_go_to_step": "Go to step {{number}}: {{title}}", + "terminal_erase": "Erase before flashing", + "terminal_erase_desc": "Clears all data on the device including existing configs", + "terminal_unsupported": "Your browser does not support this feature.", + "terminal_update_browser": "Please update your browser to the latest version.", + "terminal_use_browsers": "Please use one of the following browsers:", + "terminal_connect_failed_bootloader": "Could not enter bootloader mode", + "terminal_connect_failed": "Device connection failed", + "terminal_connect_failed_desc": "We couldn't establish a serial connection with the device.", + "terminal_quick_tries": "Quick things to try:", + "terminal_try_replug": "Unplug and replug the device.", + "terminal_try_cable": "Try a different USB cable or port.", + "terminal_try_driver": "Make sure the serial driver is installed.", + "terminal_open_troubleshooter": "Open troubleshooter", + "terminal_log_reset_no_device": "Host-side error during reset: no device!", + "terminal_log_reset_error": "Host-side error during reset: {{error}}", + "terminal_log_send_no_device": "Couldn't send: no device!", + "terminal_log_send_error": "Couldn't send: {{error}}", + "terminal_log_firmware_disconnected": "Firmware disconnected: {{error}}", + "terminal_log_erase_failed": "Failed to erase flash: {{error}}", + "terminal_log_hard_reset_failed": "Failed to hard reset: {{error}}", + "terminal_log_flash_complete": "Flash complete", + "terminal_log_flash_failed": "Failed to flash: {{error}}", + "terminal_log_command_failed": "Failed to write application command: {{error}}", + "terminal_help_title": "Troubleshooter", + "terminal_help_desc": "Work through these steps in order. Each one rules out a common cause.", + "terminal_help_step_cable": "USB cable", + "terminal_help_step_port": "USB port", + "terminal_help_step_driver": "Install driver", + "terminal_help_step_manual": "Manual driver update", + "terminal_help_step_discord": "Ask on Discord", + "terminal_help_cable_body": "Many USB-C and micro-USB cables are charge-only and don't carry data. Swap to a known-good data cable (one you've used to transfer files or connect other devices) and reconnect the hub.", + "terminal_help_port_body": "Plug the device directly into a USB port on your computer. Avoid USB hubs, docking stations, and front-panel ports if possible; these are common sources of power and signal issues. If you're on a desktop, try a port on the back of the machine.", + "terminal_help_driver_download": "Download the CP210x driver:", + "terminal_help_driver_extract": "Extract the contents of the zip file to a folder on your computer.", + "terminal_help_driver_run": "Open the folder and run {{installer}}. Follow the prompts to install.", + "terminal_help_driver_reconnect": "Reconnect the device.", + "terminal_help_manual_intro": "If the driver installer ran but the device still doesn't show up:", + "terminal_help_manual_open": "Open Device Manager (press Win + X and select Device Manager).", + "terminal_help_manual_ports": "Under Ports (COM & LPT), look for an entry like:", + "terminal_help_manual_missing": "If it's missing, the device isn't being detected by Windows at all; revisit the cable and port steps.", + "terminal_help_manual_update": "Right-click the device and pick Update Driver.", + "terminal_help_manual_browse": "Choose Browse my computer for drivers and select the folder you extracted the driver zip into. Make sure Include subfolders is checked.", + "terminal_help_manual_success": "On success, the entry should now read {{deviceName}}.", + "terminal_help_discord_intro": "Still stuck after all of the above? Hop into our Discord server and ask in the {{channel}} channel. Please include:", + "terminal_help_discord_os": "your operating system and browser", + "terminal_help_discord_device": "the device you're using (board model, where you got it)", + "terminal_help_discord_tried": "what you've already tried from the previous steps", + "terminal_help_discord_errors": "any error messages or relevant terminal output", + "terminal_help_discord_join": "Join our Discord server", + "terminal_risk_title": "⚠️ UNSTABLE FIRMWARE", + "terminal_risk_intro": "You are about to flash experimental firmware that is known to be unstable.", + "terminal_risk_brick": "This may permanently brick your device, require manual recovery, or render it unusable.", + "terminal_risk_no_support": "We will NOT provide support for issues caused by this firmware.", + "terminal_risk_acknowledge": "I understand this is entirely my responsibility", + "terminal_risk_abort": "Abort", + "terminal_risk_accept": "I ACCEPT FULL RESPONSIBILITY", + "firmware_channel_recommended": "This is the recommended channel.", + "firmware_channel_danger": "DO NOT USE THIS UNLESS YOU KNOW WHAT YOU ARE DOING", + "firmware_channel_stable": "Stable", + "firmware_channel_beta": "Beta", + "firmware_channel_develop": "Develop", + "terminal_board_select": "Select a board...", + "terminal_board_search": "Search boards...", + "terminal_board_none": "No board found.", + "terminal_flash_button": "Flash", + "terminal_flash_progress": "Flash Progress: {{status}}", + "terminal_flash_idle": "Idle", + "terminal_flash_no_device": "No device selected.", + "terminal_flash_resetting": "Resetting...", + "terminal_flash_downloading": "Downloading firmware...", + "terminal_flash_download_failed": "Failed to download firmware.", + "terminal_flash_flashing": "Flashing firmware...", + "terminal_flash_rebooting": "Rebooting device... (Reconnect to power manually if stuck)", + "terminal_flash_done": "Rebooted device! Flashing complete.", + "terminal_port_select": "Select Device", + "terminal_port_disconnect": "Disconnect Device", + "terminal_port_connected": "Device connected: {{id}}", + "terminal_console": "Console", + "terminal_connected_device": "Connected device", + "terminal_resize": "Resize terminal panel", + "terminal_reboot": "Reboot", + "terminal_disconnect": "Disconnect", + "terminal_fullscreen_exit_esc": "Exit fullscreen (Esc)", + "terminal_fullscreen_exit": "Exit fullscreen", + "terminal_fullscreen_fill": "Fill the window", + "terminal_command_label": "Serial command", + "terminal_command_placeholder": "Type a command...", + "terminal_command_send": "Send command", + "terminal_colors": "Colors", + "terminal_colors_menu": "Colors...", + "terminal_colors_label": "Console colors", + "terminal_colors_close": "Close colors", + "terminal_color_input": "{{name}} color", + "terminal_colors_reset": "Reset to defaults", + "terminal_color_bg": "Background", + "terminal_color_fg": "Text", + "terminal_color_ts": "Timestamp", + "terminal_color_error": "Error", + "terminal_color_warning": "Warning", + "terminal_color_info": "Info", + "terminal_color_debug": "Debug", + "terminal_color_verbose": "Verbose", + "terminal_options": "Options", + "terminal_options_label": "Console options", + "terminal_hide_system": "Hide system messages", + "terminal_stick_bottom": "Stick to bottom", + "terminal_raw_output": "Raw output", + "terminal_timestamps": "Timestamps", + "terminal_timestamp_uptime": "Uptime", + "terminal_timestamp_local": "Local", + "terminal_timestamp_ms": "Ms", + "terminal_timestamp_off": "Off", + "terminal_copy_settings": "Copy settings", + "terminal_import_settings": "Import settings", + "terminal_copy_selection": "Copy selection", + "terminal_copy_all": "Copy all output", + "terminal_toast_selection_copied": "Selection copied", + "terminal_toast_output_copied": "Console output copied", + "terminal_toast_settings_copied": "Console settings copied", + "terminal_toast_clipboard_unreadable": "Could not read the clipboard", + "terminal_toast_settings_imported": "Console settings imported", + "terminal_toast_settings_invalid": "Clipboard does not contain console settings", + "common_try_again": "Try again", + "terminal_cfg_intro": "Values are sent to the device via UART. Read the device's response in the console below. Commands without an argument act as getters; use the button next to each field to read the current value.", + "terminal_cfg_rf_title": "RF Transmitter", + "terminal_cfg_rf_desc": "Controls the shocker RF output.", + "terminal_cfg_tx_pin": "TX GPIO pin", + "terminal_cfg_example": "e.g. {{value}}", + "terminal_cfg_read_value": "Read current value", + "terminal_cfg_set": "Set", + "terminal_cfg_read": "Read", + "terminal_cfg_reading": "Reading…", + "terminal_cfg_apply": "Apply", + "terminal_cfg_keepalive": "Keepalive enabled", + "terminal_cfg_keepalive_desc": "Periodically pings paired shockers to keep them awake.", + "terminal_cfg_estop_title": "Emergency Stop", + "terminal_cfg_estop_desc": "Hardware button that halts all output.", + "terminal_cfg_estop_enabled": "EStop enabled", + "terminal_cfg_estop_pin": "EStop GPIO pin", + "terminal_cfg_estop_note": "Note: {{latching}} and {{active}} have no dedicated commands; set them via the JSON config below.", + "terminal_cfg_wifi_title": "WiFi", + "terminal_cfg_wifi_desc": "Station credentials and device hostname.", + "terminal_cfg_hostname": "Hostname", + "terminal_cfg_networks": "Networks (JSON array)", + "terminal_cfg_invalid_json_array": "Must be a valid JSON array", + "terminal_cfg_ap_note": "AP settings ({{ssid}}, {{password}}, {{disabled}}, {{staDisabled}}, {{offlineMode}}) have no dedicated commands; use the JSON config.", + "terminal_cfg_backend_title": "Backend", + "terminal_cfg_backend_desc": "OpenShock server and authentication.", + "terminal_cfg_domain": "Domain", + "terminal_cfg_domain_restart": "Setting the domain will restart the device.", + "terminal_cfg_auth_token": "Auth token", + "terminal_cfg_auth_token_placeholder": "Paste device token", + "terminal_cfg_hide": "Hide", + "terminal_cfg_show": "Show", + "terminal_cfg_serial_title": "Serial Input", + "terminal_cfg_echo": "Echo enabled", + "terminal_cfg_echo_desc": "Print typed characters back to the console.", + "terminal_cfg_advanced_title": "Advanced: full config", + "terminal_cfg_advanced_desc": "For fields without dedicated commands (captive portal, OTA, LAN, etc.), replace the entire config.", + "terminal_cfg_json_config": "JSON config", + "terminal_cfg_invalid_json": "Must be valid JSON", + "terminal_cfg_read_json": "Read current config as JSON", + "terminal_cfg_json_restart": "Applying a JSON config will restart the device.", + "terminal_cfg_raw_config": "Raw FlatBuffer config (base64)", + "terminal_cfg_invalid_base64": "Must be a valid base64 string", + "terminal_cfg_read_raw": "Read current config as base64", + "terminal_cfg_factory_reset": "Factory reset", + "terminal_cfg_factory_reset_desc": "Wipes the entire device configuration.", + "terminal_cfg_factory_reset_title": "Factory reset device?", + "terminal_cfg_factory_reset_action": "Wipe config", + "terminal_cfg_factory_reset_confirm": "This will erase all configuration on the device; WiFi networks, backend credentials, pins, and all other settings. The device will be reset to defaults.", + "terminal_cfg_read_failed_json_title": "Couldn't read the JSON config", + "terminal_cfg_read_failed_raw_title": "Couldn't read the raw config", + "terminal_cfg_read_failed_desc": "The device didn't respond after {{attempts}} attempts.", + "terminal_cfg_common_causes": "Common causes:", + "terminal_cfg_cause_busy": "The device is busy handling another command.", + "terminal_cfg_cause_disconnected": "The device disconnected or rebooted.", + "terminal_cfg_cause_unsupported": "The firmware version doesn't support this command.", + "common_status": "Status", + "common_version": "Version", + "common_created": "Created", + "common_create": "Create", + "common_done": "Done", + "common_enable": "Enable", + "common_disable": "Disable", + "common_are_you_sure": "Are you sure?", + "common_generating": "Generating...", + "hubs_title": "Hubs", + "hubs_subtitle": "Every hub registered to your account.", + "hubs_add": "Add Hub", + "hubs_load_failed": "Failed to load hubs.", + "hubs_empty_title": "No hubs yet", + "hubs_empty_desc": "A hub is the device that relays commands to your shockers. Add one to get started.", + "hubs_create_title": "Create hub", + "hubs_name_label": "Hub Name", + "hubs_name_placeholder": "My Hub", + "hub_toast_not_connected": "Not connected to the server", + "hub_toast_try_later": "Try again in a moment.", + "hub_reboot_title": "Reboot {{name}}?", + "hub_reboot_desc": "The hub will disconnect and restart. Any shockers paired to it stop responding until it comes back online.", + "hub_reboot": "Reboot", + "hub_hotspot_enable_title": "Enable Wi-Fi hotspot on {{name}}?", + "hub_hotspot_disable_title": "Disable Wi-Fi hotspot on {{name}}?", + "hub_hotspot_enable_desc": "The hub broadcasts its own setup network. It stays reachable on your Wi-Fi, but the hotspot is open to anyone in range until you turn it off.", + "hub_hotspot_disable_desc": "The setup hotspot shuts down. If the hub is not already on your Wi-Fi you will need physical access to set it up again.", + "hub_delete_desc": "You are about to delete hub {{name}}.", + "hub_delete_shockers": "This will also delete the following shockers:", + "hub_edit_title": "Edit hub", + "hub_edit_apply": "Apply", + "hub_pair_title_generate": "Generate pair code?", + "hub_pair_title_generated": "Pair code generated", + "hub_pair_title_paired": "Hub paired", + "hub_pair_consumed": "{{name}} consumed this pair code and is now paired.", + "hub_pair_used": "The code has been used and is no longer valid.", + "hub_pair_generated_for": "Pair code generated for {{name}}.", + "hub_copy_now": "The code below will not be accessible later, please copy it now and update clients with it.", + "hub_pair_generate_for": "You are about to generate a pair code for {{name}}.", + "hub_pair_valid_for": "It will be valid for 15 minutes after its creation.", + "hub_pair_one_active": "There is only one active pair code per hub, newly generated ones will override the older active ones.", + "hub_pair_complete": "Pairing complete", + "hub_pair_code_label": "Pair code:", + "hub_pair_copied_close": "Code has been copied, close", + "hub_pair_get": "Get Pair Code", + "hub_token_generated": "Token generated", + "hub_token_generated_for": "New token generated for {{name}}.", + "hub_token_regenerate_for": "You are about to regenerate the token for {{name}}.", + "hub_token_invalidate": "This action will invalidate the current token and disconnect clients using it.", + "hub_token_confirm": "Are you sure you want to do this?", + "hub_token_label": "New token:", + "hub_token_copied_close": "Token has been copied, close", + "hub_token_regenerate": "Regenerate Token", + "hub_menu_update": "Update", + "hub_menu_label": "Hub", + "hub_menu_hotspot_enable": "Enable Wi-Fi hotspot", + "hub_menu_hotspot_disable": "Disable Wi-Fi hotspot", + "hub_menu_pair": "Pair", + "hub_menu_estop": "Emergency Stop", + "hub_update_breadcrumb": "Update", + "hub_update_unknown_hub": "Unknown Hub", + "hub_update_unknown_task": "Unknown Task", + "hub_update_task_metadata": "Fetching Metadata", + "hub_update_task_preparing": "Preparing for Update", + "hub_update_task_flash_fs": "Flashing Filesystem", + "hub_update_task_verify_fs": "Verifying Filesystem", + "hub_update_task_flash_app": "Flashing Application", + "hub_update_task_bootable": "Marking Application Bootable", + "hub_update_task_rebooting": "Rebooting", + "hub_update_status_started": "Started", + "hub_update_status_running": "Running", + "hub_update_status_finished": "Finished", + "hub_update_status_error": "Error", + "hub_update_status_timeout": "Timeout", + "hub_update_confirm_title": "Confirm firmware update", + "hub_update_confirm_desc": "Update {{name}} to version {{version}}?", + "hub_update_unstable_warning": "This version may not be from the stable channel and could contain bugs.", + "hub_update_title": "Update {{name}}", + "hub_update_subtitle": "Manage firmware updates for this hub.", + "hub_update_status_title": "Hub Status", + "hub_update_firmware": "Firmware: {{version}}", + "hub_update_confirm": "Update", + "hub_update_success": "Update completed successfully", + "hub_update_rolled_back": "Device rolled back to previous version", + "hub_update_back": "Back to Hubs", + "hub_update_flash_again": "Flash Again", + "hub_update_card_title": "Firmware Update", + "hub_update_card_desc": "Select a firmware channel and version to install.", + "hub_update_to": "Update to {{version}}", + "hub_update_must_be_online": "Hub must be online to start an update.", + "hub_update_updating_to": "Updating to {{version}}...", + "hub_update_total": "Total", + "hub_update_task": "Task", + "hub_update_history": "Update History", + "hub_update_no_history": "No update history found for this hub.", + "hub_update_col_id": "ID", + "hub_update_col_started": "Started", + "hub_update_col_message": "Message", + "hub_update_loading": "Loading hub information...", + "hub_update_not_found": "Hub not found.", + "home_breadcrumb": "Home", + "home_welcome": "Welcome back", + "home_welcome_name": "Welcome back, {{name}}", + "home_subtitle": "Here's an overview of your OpenShock setup.", + "home_hubs_online": "{{count}} online", + "home_hub_status": "Hub Status", + "home_no_hubs": "No hubs", + "home_all_online": "All online", + "home_all_offline": "All offline", + "home_some_online": "{{online}}/{{total}} online", + "home_quick_links": "Quick Links", + "home_my_shockers": "My Shockers", + "home_my_shockers_desc": "Control your shockers", + "home_hubs_desc": "Manage your hubs", + "home_shared_desc": "Shockers shared with you", + "home_public_desc": "Manage share links", + "home_get_started": "Get Started", + "home_get_started_desc": "You don't have any hubs yet. Create a hub to connect your first device, then add shockers to it.", + "home_set_up_hub": "Set Up a Hub", + "home_first_shocker": "Add Your First Shocker", + "home_first_shocker_desc_one": "You have {{count}} hub set up. Add a shocker to start controlling it.", + "home_first_shocker_desc_other": "You have {{count}} hubs set up. Add a shocker to start controlling it.", + "home_go_to_shockers": "Go to Shockers", + "profile_title": "Profile", + "profile_coming_soon": "Profile is coming soon", + "profile_coming_soon_desc": "Your public profile is not available yet. Account details live under Settings.", + "common_retry": "Retry", + "common_never_used": "Never used", + "common_expires": "Expires {{time}}", + "common_search_placeholder": "Search...", + "common_unknown": "Unknown", + "settings_breadcrumb_account": "Account", + "account_subtitle": "Your sign-in details and account actions.", + "account_change_username": "Change Username", + "account_change_email": "Change Email", + "account_change_password": "Change Password", + "account_username_label": "Username", + "account_email_label": "Email", + "account_password_label": "Password", + "account_new_password_label": "New Password", + "account_confirm_password_label": "Confirm New Password", + "account_oauth_only": "Not available for OAuth-only accounts", + "account_oauth_no_password": "This account signs in via OAuth and has no password.", + "account_diagnostics": "Diagnostics", + "account_diagnostics_desc": "Help us fix crashes and slow API calls. Reports include the error message, stack trace and your IP. Off by default.", + "account_diagnostics_level": "Diagnostics level", + "account_telemetry_off": "Off", + "account_telemetry_off_desc": "Send nothing.", + "account_telemetry_errors": "Errors", + "account_telemetry_errors_desc": "Send browser error reports only.", + "account_telemetry_full": "Full", + "account_telemetry_full_desc": "Error reports plus traces of API calls (no page navigations).", + "account_toast_deactivated": "Account deactivated successfully", + "account_deactivate_title": "Deactivate account", + "account_deactivate_desc": "Are you sure you want to deactivate your account?", + "account_deactivate": "Deactivate Account", + "account_email_title": "Change email", + "account_email_desc": "Enter your new email address and confirm with your current password.", + "account_email_toast_sent": "Verification email sent to {{email}}. Click the link in that email to apply the change.", + "account_new_email": "New Email", + "account_current_password": "Current Password", + "account_password_title": "Change password", + "account_password_desc": "Enter your current password and choose a new one.", + "account_password_toast": "Password has been changed", + "account_username_title": "Change username", + "account_username_desc": "Enter a new username.", + "account_new_username": "New Username", + "account_username_toast": "Username changed successfully", + "tokens_subtitle": "API Tokens are used to authenticate with the OpenShock API.", + "tokens_generate": "Generate Token", + "tokens_toast_refreshed": "Tokens refreshed successfully", + "tokens_empty_title": "No API tokens", + "tokens_empty_desc": "Generate a token to authenticate with the OpenShock API.", + "tokens_created_on": "Created {{date}}", + "tokens_last_used": "Last used {{time}}", + "tokens_never_expires": "Never expires", + "tokens_load_failed": "Failed to load API tokens.", + "token_toast_edited": "Token edited successfully", + "token_name_required": "Name is required", + "token_name_too_long": "Name is too long", + "token_edit_title": "Edit API token", + "token_name_label": "Token Name", + "token_name_placeholder": "Token name...", + "token_permissions": "Permissions", + "token_perm_category_shockers": "Shockers", + "token_perm_category_devices": "Hubs", + "token_perm_category_usershares": "User Shares", + "token_perm_category_publicshares": "Public Shares", + "token_perm_use": "Use", + "token_perm_edit": "Edit", + "token_perm_pause": "Pause", + "token_perm_auth": "Authenticate", + "token_shocker_control": "Shocker Control", + "token_toast_paused": "Token paused", + "token_toast_resumed": "Token resumed", + "token_delete_title": "Delete API token", + "token_delete_desc": "Are you sure you want to delete {{name}}?", + "token_delete_permanent": "This action cannot be undone. This will permanently delete the token.", + "token_toast_deleted": "Token deleted successfully", + "token_resume": "Resume token", + "token_pause": "Pause token", + "token_mode_clamp_desc": "Clamp: requests outside the allowed range are capped to the nearest limit (the min or the max).", + "token_mode_lerp_desc": "Lerp: the full input range is linearly rescaled so it fits within your allowed min–max range.", + "token_paused_desc": "A paused token may not send shocker control messages.", + "token_intensity_range": "Intensity range", + "token_duration_range": "Duration range", + "token_new_breadcrumb": "New", + "token_redirect_not_allowed": "The provided redirect_uri is not allowed. Only loopback addresses or custom application schemes are permitted.", + "token_params_missing": "Required get parameters are missing. Make sure name, redirect_uri, and permissions are provided.", + "token_invalid_permissions": "Invalid permissions provided: {{list}}", + "token_toast_created": "Token created successfully", + "token_request_title": "API Token Request", + "token_access_granted": "Access granted", + "token_shared_redirecting": "The token has been created and shared with the application. Redirecting you back to {{uri}}.", + "token_not_redirected": "If you are not redirected automatically, use the button below.", + "token_finish": "Finish", + "token_generated_title": "API Token Generated", + "token_copy_now": "Please copy your API Token now, you will not be able to view it again later!", + "token_new_title": "New API Token", + "token_external_desc": "An external application is requesting access to your account. Review and adjust the permissions below before allowing access.", + "token_new_desc": "Configure and generate a new API token for your account.", + "token_external_requesting": "{{name}} is requesting an API Token. Your token will be shared with the application at {{uri}}.", + "token_allow": "Allow", + "token_generate": "Generate", + "token_deny": "Deny", + "sessions_subtitle": "Every active session on your account. Revoke any you do not recognize.", + "sessions_unknown_device": "Unknown device", + "sessions_toast_refreshed": "Sessions refreshed successfully", + "sessions_load_failed": "Failed to load sessions.", + "sessions_empty_title": "No active sessions", + "sessions_empty_desc": "Sessions appear here once you sign in from a browser or app.", + "sessions_last_seen": "Last seen {{time}}", + "sessions_signed_in": "Signed in {{time}}", + "session_toast_revoked": "Session revoked successfully", + "session_revoke_title": "Revoke session", + "session_revoke": "Revoke", + "session_revoke_desc": "Are you sure you want to revoke this session?", + "session_revoke_from": "Session logged in from {{ip}} using {{agent}}", + "connections_title": "OAuth Connections", + "connections_subtitle": "Link or unlink third-party accounts to sign in faster and keep your profile in sync.", + "connections_toast_linked": "Account linked.", + "connections_toast_cancelled": "Link flow cancelled.", + "connections_toast_failed": "Linking failed.", + "connections_toast_removed": "Connection removed", + "connections_refreshing": "Refreshing…", + "connections_link_new": "Link new provider", + "connections_empty_title": "No connections yet", + "connections_empty_desc": "Choose “Link new provider” above to connect available providers.", + "connections_unlink": "Unlink", + "connections_load_failed": "Failed to load OAuth connections.", + "connections_unlink_title": "Unlink {{name}}?", + "connections_unlink_title_generic": "Unlink this account?", + "connections_unlink_desc": "You'll no longer be able to sign in with this provider unless you link it again.", + "provider_starting": "Starting {{name}}...", + "provider_link": "Link {{name}}", + "audit_subtitle": "Security-relevant activity on your account. Review anything you do not recognize.", + "audit_col_time": "Time", + "audit_col_action": "Action", + "audit_col_details": "Details", + "audit_col_reason": "Reason", + "audit_col_ip": "IP address", + "audit_col_device": "Device", + "audit_action_login": "Signed in", + "audit_action_logout": "Signed out", + "audit_action_password_changed": "Password changed", + "audit_action_email_change_requested": "Email change requested", + "audit_action_email_changed": "Email changed", + "audit_action_username_changed": "Username changed", + "audit_action_api_token_created": "API token created", + "audit_action_api_token_deleted": "API token deleted", + "audit_action_oauth_connected": "Connection added", + "audit_action_oauth_disconnected": "Connection removed", + "audit_action_account_deactivated": "Account deactivated", + "audit_action_account_reactivated": "Account reactivated", + "audit_action_account_deleted": "Account deleted", + "audit_action_automation_token_created": "Automation token created", + "audit_action_automation_token_updated": "Automation token updated", + "audit_action_automation_token_rotated": "Automation token rotated", + "audit_action_automation_token_deleted": "Automation token deleted", + "audit_action_automation_token_used": "Automation token used", + "audit_meta_session": "Session {{id}}", + "audit_meta_changed": "{{old}} to {{new}}", + "audit_meta_email_requested": "Requested change to {{email}}", + "audit_meta_accounts_removed_one": "{{name}} ({{count}} account removed)", + "audit_meta_accounts_removed_other": "{{name}} ({{count}} accounts removed)", + "audit_meta_scheduled_deletion": "Scheduled for deletion", + "audit_meta_kept": "Kept for reactivation", + "common_view": "View", + "common_save": "Save", + "common_saving": "Saving...", + "common_back": "Back", + "common_shared_by": "Shared by", + "common_user_avatar": "User Avatar", + "common_toast_saved": "Changes saved successfully", + "pause_reason_shocker": "Paused at shocker level", + "pause_reason_shocker_user_share": "Paused at shocker and user share level", + "pause_reason_shocker_public_share": "Paused at shocker and public share level", + "pause_reason_user_share": "Paused at user share level", + "pause_reason_public_share": "Paused at public share level", + "public_shares_subtitle": "A link anyone can use, no account required.", + "public_shares_new": "New Share", + "public_share_never_expires": "Never expires", + "public_shares_empty_title": "No public shares yet", + "public_shares_empty_desc": "Create a link that anyone can use to control your shockers.", + "public_share_expired": "Expired", + "public_share_no_expiry": "No expiry", + "public_share_label": "Public Share", + "public_share_toast_created": "Created new public share", + "public_share_create_title": "Create public share", + "public_share_toast_deleted": "Deleted public share", + "public_share_delete_title": "Delete public share", + "public_share_delete_desc": "Are you sure you want to delete public share {{name}}?", + "public_share_edit_title": "Public Share: {{name}}", + "public_share_edit_subtitle": "Editing: changes apply when you save.", + "public_share_add_shocker": "Add Shocker", + "public_share_toast_added_one": "Added {{count}} shocker to share", + "public_share_toast_added_other": "Added {{count}} shockers to share", + "public_share_empty_shockers_title": "No shockers in this share", + "public_share_empty_shockers_desc": "Add a shocker and anyone with the link will be able to control it.", + "public_share_load_failed": "Error fetching public share details", + "public_share_paused_here": "Paused for this share", + "public_share_resume_shocker": "Resume shocker", + "public_share_pause_shocker": "Pause shocker", + "public_share_remove": "Remove from share", + "public_share_toast_removed": "Shocker removed from share", + "public_share_add_title": "Add shockers", + "public_share_add_desc": "Add shockers to this public share. You can set their limits once they are added.", + "public_share_add_placeholder": "Select shockers to share...", + "public_share_add_no_match": "No matching shockers", + "public_share_add_submit": "Add Shockers", + "public_share_view_loading": "Loading share details...", + "public_share_view_title": "Public Share Link", + "public_share_view_desc": "Enter as a guest or login with your OpenShock account", + "public_share_view_guest_name": "Guest Name", + "public_share_view_enter": "Enter", + "public_share_view_enter_guest": "Enter as Guest", + "public_share_login": "Login", + "perm_shock_on": "Shock enabled", + "perm_shock_off": "Shock disabled", + "perm_vibrate_on": "Vibrate enabled", + "perm_vibrate_off": "Vibrate disabled", + "perm_sound_on": "Sound enabled", + "perm_sound_off": "Sound disabled", + "perm_live_on": "Live enabled", + "perm_live_off": "Live disabled", + "perm_live_control": "Live Control", + "user_selector_avatar_of": "{{name}}'s avatar", + "user_selector_placeholder": "Enter user name", + "user_selector_aria": "Username to search", + "user_selector_search": "Search user", + "user_selector_found": "User found", + "common_remove": "Remove", + "user_shares_subtitle": "Direct permanent shares with other users.", + "user_shares_toast_invited": "Sent a shocker invite to {{name}}", + "user_shares_redeem": "Redeem Code", + "user_shares_new": "New Share", + "user_shares_tab_shares": "Shares", + "user_shares_tab_incoming": "Shared with Me", + "user_shares_tab_invites": "Invites", + "share_code_create_title": "New share code", + "share_code_create_desc": "Create a Share Code or Invite", + "share_code_shocker_placeholder": "Select shockers to share...", + "share_code_no_match": "No matching shockers", + "share_code_send_invite": "Send Share Invite", + "share_code_create": "Create Share Code", + "share_code_created_title": "Share code generated", + "share_code_created_desc": "Please copy share code or code link!", + "share_code_redeem_title": "Redeem share code", + "share_code_redeem_desc": "Enter the share code to redeem", + "share_code_redeem_placeholder": "Enter share code", + "share_code_redeemed": "Redeemed successfully!", + "share_code_shared_shockers": "Shared shockers", + "share_code_redeeming": "Redeeming...", + "share_code_redeem": "Redeem", + "incoming_shares_empty_title": "Nothing shared with you", + "incoming_shares_empty_desc": "No one has shared a shocker with you yet.", + "incoming_share_toast_removed": "Removed share for {{name}}", + "incoming_share_remove_title": "Remove Share", + "incoming_share_remove_desc": "Are you sure you want to remove the share for {{name}}?", + "incoming_share_toast_removed_shocker": "Removed {{shocker}} shared by {{name}}", + "incoming_share_remove_shocker_title": "Remove this shared shocker?", + "incoming_share_remove_shocker_desc": "Are you sure you want to remove the shocker share {{shocker}} by {{name}}?", + "incoming_share_manage_from": "Manage shares from", + "share_remove": "Remove share", + "invites_empty_title": "No invites yet", + "invites_empty_desc": "You have no incoming or outgoing share invites.", + "invites_outgoing": "Outgoing", + "invites_outgoing_empty_title": "No outgoing invites", + "invites_outgoing_empty_desc": "You have no outgoing share invites.", + "invites_incoming": "Incoming", + "invites_incoming_empty_title": "No incoming invites", + "invites_incoming_empty_desc": "You have no incoming share invites.", + "invite_toast_accepted": "Accepted share invite from {{name}}", + "invite_toast_declined": "Declined share invite from {{name}}", + "invite_deny_title": "Deny Invite", + "invite_deny_label": "Deny Invite", + "invite_deny": "Deny", + "invite_deny_desc": "Are you sure you want to deny the invite from {{name}}?", + "invite_accept": "Accept Invite", + "invite_toast_cancelled_for": "Cancelled invite for {{name}} ({{id}})", + "invite_toast_cancelled": "Cancelled invite {{id}}", + "invite_cancel_title": "Cancel Invite", + "invite_cancel": "Cancel", + "invite_cancel_for_desc": "Are you sure you want to cancel the invite for {{name}}?", + "invite_cancel_code_desc": "Are you sure you want to cancel the invite with code {{code}}?", + "invite_cancel_outstanding": "Cancel Outstanding Invite", + "outgoing_shares_empty_title": "No shared shockers", + "outgoing_shares_empty_desc": "You haven't shared any shockers with other users yet.", + "outgoing_share_toast_removed": "Removed shocker share {{name}}", + "outgoing_share_remove_title": "Stop sharing this shocker?", + "outgoing_share_editing_for": "Editing shares for", + "outgoing_share_limits": "Limits & Permissions", + "outgoing_share_same": "Same restrictions on every shocker", + "outgoing_share_per_desc": "Tune restrictions per shocker", + "outgoing_share_all": "All", + "outgoing_share_per": "Per shocker", + "outgoing_share_remove_desc": "Are you sure you want to stop sharing {{shocker}} with {{name}}?", + "report_breadcrumb": "Report API Tokens", + "report_toast_clipboard_failed": "Failed to read clipboard: {{error}}", + "report_title": "Report Leaked API Tokens", + "report_paste": "Paste from clipboard", + "report_warning": "This form is only for reporting accidentally leaked API tokens.", + "report_abuse_warning": "Intentional abuse will result in bans or severe endpoint restrictions.", + "report_detected": "Detected Tokens", + "report_invalid": "One or more tokens appear to be invalid. Please check for formatting issues.", + "report_acknowledge": "I confirm I understand what this feature is for and accept responsibility.", + "report_submit": "Submit Report", + "turnstile_disabled": "Turnstile disabled", + "common_internal_error": "Internal error", + "resend_toast_sent": "Activation email sent. Check your inbox and spam folder.", + "resend_toast_throttled": "Too many activation emails have been requested. Please try again later.", + "resend_toast_unavailable": "No activation email can be resent from this browser. If your account isn't activated yet, logging in sends a new link.", + "resend_button": "Didn't get the email? Resend", + "expiration_label": "Expiration", + "expiration_never": "Never", + "expiration_custom": "Custom", + "expiration_days_one": "{{count}} Day", + "expiration_days_other": "{{count}} Days", + "expiration_required": "Expire date is required", + "expiration_never_desc": "This will never expire", + "expiration_expires_at": "Expires {{time}} ({{date}})", + "date_picker_placeholder": "Pick a date", + "telemetry_toast_title": "Help improve OpenShock?", + "telemetry_toast_desc": "Send diagnostics to help us fix crashes and slow API calls. Reports include the error message, stack trace and your IP. You can change this any time in Account settings.", + "telemetry_toast_no": "No thanks", + "telemetry_toast_errors": "Errors only", + "telemetry_toast_full": "Full", + "table_show_details": "Show details", + "table_hide_details": "Hide details", + "table_no_results": "No results.", + "table_sort_asc": "Sort by {{name}}, ascending", + "table_sort_desc": "Sort by {{name}}, descending", + "table_sort_none": "Sort by {{name}}, unsorted", + "cell_na": "N/A", + "cell_not_applicable": "Not applicable", + "cell_invalid": "Invalid", + "cell_unavailable": "Unavailable", + "cell_none": "None", + "oauth_login_with": "Login with {{provider}}", + "oauth_signup_with": "Signup with {{provider}}", + "signalr_connect_failed": "Failed to connect to server!", + "signalr_disconnect_failed": "Encountered error while disconnecting from server!", + "signalr_invalid_update": "Received invalid update from server!", + "signalr_invalid_log": "Received invalid log data from server!", + "signalr_invalid_ota": "Received invalid firmware update data from server!", + "ota_toast_failed": "Hub firmware update failed: {{message}}", + "ota_toast_succeeded": "Hub firmware update completed successfully!", + "ota_toast_rolled_back": "Hub firmware rolled back to previous version", + "lcg_connect_failed": "Failed to connect to live control gateway", + "terminal_toast_bootloader_failed": "Failed to enter bootloader: {{error}}", + "terminal_toast_app_mode_failed": "Failed to enter application mode: {{error}}", + "problem_account_account_not_activated_title": "Account not activated", + "problem_account_account_not_activated_desc": "Check your inbox for the activation email.", + "problem_account_activation_not_found_title": "Activation link is invalid", + "problem_account_activation_not_found_desc": "The link may have expired or already been used.", + "problem_account_activation_resend_too_many_title": "Too many activation emails requested", + "problem_account_activation_resend_too_many_desc": "Please wait a while before trying again.", + "problem_account_activation_resend_unavailable_title": "Cannot resend activation email", + "problem_account_activation_resend_unavailable_desc": "Log in again to request a new activation link.", + "problem_account_deactivate_already_deactivated_title": "Account is already deactivated", + "problem_account_deactivate_denied_privileged_title": "Privileged accounts cannot be deactivated", + "problem_account_deactivate_unauthorized_title": "You are not allowed to do this", + "problem_account_deactivated_title": "This account has been deactivated", + "problem_account_email_already_in_use_title": "That email address is already in use", + "problem_account_email_invalid_title": "That email address is not valid", + "problem_account_email_taken_title": "That email address is already in use", + "problem_account_email_too_many_requests_title": "Too many email change requests", + "problem_account_email_too_many_requests_desc": "Please wait a while before trying again.", + "problem_account_email_unchanged_title": "That is already your email address", + "problem_account_email_verify_not_found_title": "Verification link is invalid", + "problem_account_email_verify_not_found_desc": "The link may have expired or already been used.", + "problem_account_o_auth_only_title": "This account has no password", + "problem_account_o_auth_only_desc": "Sign in with the provider you signed up with.", + "problem_account_password_not_set_title": "No password set", + "problem_account_password_not_set_desc": "This account signs in through an external provider.", + "problem_account_password_old_password_invalid_title": "Current password is incorrect", + "problem_account_username_invalid_title": "That username is not allowed", + "problem_account_username_recently_changed_title": "Username changed too recently", + "problem_account_username_recently_changed_desc": "You can change your username once every 7 days.", + "problem_account_username_taken_title": "That username is already taken", + "problem_admin_user_deactivated_title": "This user is deactivated", + "problem_admin_user_not_activated_title": "This user has not been activated yet", + "problem_api_token_can_only_delete_self_title": "An API token can only delete itself", + "problem_api_token_not_found_title": "API token not found", + "problem_api_token_paused_title": "This API token is paused", + "problem_assign_lcg_bad_schema_version_title": "Unsupported hub protocol version", + "problem_assign_lcg_bad_schema_version_desc": "Update the hub firmware to connect.", + "problem_assign_lcg_no_lcg_available_title": "No gateway available", + "problem_assign_lcg_no_lcg_available_desc": "No live control gateway is available right now. Please try again later.", + "problem_authentication_account_deactivated_title": "This account has been deactivated", + "problem_authentication_account_not_activated_title": "This account has not been activated", + "problem_authentication_cookie_missing_or_invalid_title": "You are not logged in", + "problem_authentication_cookie_missing_or_invalid_desc": "Your session may have expired. Please log in again.", + "problem_authentication_header_missing_or_invalid_title": "Invalid API token", + "problem_authentication_session_invalid_title": "Session expired", + "problem_authentication_session_invalid_desc": "Please log in again.", + "problem_authentication_token_invalid_title": "Invalid API token", + "problem_authentication_unknown_error_title": "Authentication failed", + "problem_authorization_policy_not_met_title": "You do not have permission to do this", + "problem_authorization_token_only_title": "This action requires an API token", + "problem_authorization_token_permission_missing_title": "This API token is missing a required permission", + "problem_authorization_unknown_error_title": "Authorization failed", + "problem_authorization_user_session_only_title": "This action requires a logged-in session", + "problem_automation_token_not_allowed_for_account_title": "Automation tokens cannot be used with privileged accounts", + "problem_configuration_already_exists_title": "A configuration entry with that name already exists", + "problem_configuration_invalid_name_format_title": "Invalid configuration name", + "problem_configuration_invalid_name_format_desc": "Only A to Z and underscores are allowed.", + "problem_configuration_invalid_value_format_title": "Value does not match the configuration type", + "problem_configuration_not_found_title": "Configuration entry not found", + "problem_control_stats_invalid_range_title": "The from date must not be after the to date", + "problem_control_stats_invalid_time_zone_title": "Unknown time zone", + "problem_control_stats_missing_capability_title": "Control statistics are not available on this server", + "problem_device_not_found_title": "Hub not found", + "problem_device_not_online_title": "Hub is offline", + "problem_device_too_many_hubs_title": "You have reached the maximum number of hubs", + "problem_device_too_many_shockers_title": "This hub has reached its maximum number of shockers", + "problem_endpoint_retired_title": "This feature is no longer available", + "problem_expression_error_title": "Invalid filter expression", + "problem_internal_server_error_title": "Something went wrong on our end", + "problem_login_invalid_credentials_title": "Invalid username or password", + "problem_login_invalid_domain_title": "Logging in from this address is not allowed", + "problem_o_auth_connection_already_exists_title": "Your account is already connected to this provider", + "problem_o_auth_connection_already_linked_title": "This external account is already linked to another user", + "problem_o_auth_flow_anonymous_only_title": "You are already signed in", + "problem_o_auth_flow_mismatch_title": "Sign-in attempt does not match", + "problem_o_auth_flow_mismatch_desc": "Please start over.", + "problem_o_auth_flow_missing_data_title": "The provider did not return your account details", + "problem_o_auth_flow_missing_data_desc": "Please try again.", + "problem_o_auth_flow_not_found_title": "Sign-in attempt expired", + "problem_o_auth_flow_not_found_desc": "Please start over.", + "problem_o_auth_flow_unsupported_title": "Unsupported sign-in flow", + "problem_o_auth_internal_error_title": "Something went wrong during sign-in", + "problem_o_auth_internal_error_desc": "Please try again in a moment.", + "problem_o_auth_link_authenticated_user_only_title": "You must be signed in to link an external account", + "problem_o_auth_provider_mismatch_title": "Sign-in attempt does not match the provider", + "problem_o_auth_provider_mismatch_desc": "Please start over.", + "problem_o_auth_provider_unsupported_title": "This sign-in provider is not supported", + "problem_pair_code_not_found_title": "Pair code not found", + "problem_password_reset_not_found_title": "Password reset link is invalid", + "problem_password_reset_not_found_desc": "The link may have expired or already been used.", + "problem_session_not_found_title": "Session not found", + "problem_share_get_no_shares_title": "You have no shares with this user", + "problem_share_request_create_cannot_share_with_self_title": "You cannot share with yourself", + "problem_share_request_create_shocker_not_found_title": "One or more shockers were not found", + "problem_share_request_create_shocker_not_found_desc": "They may have been removed or do not belong to you.", + "problem_share_request_not_found_title": "Share invite not found", + "problem_share_user_not_found_title": "Share not found", + "problem_share_code_already_linked_title": "Shocker is already linked to your account", + "problem_share_code_cant_link_own_share_code_title": "You cannot redeem your own share code", + "problem_share_code_not_found_title": "Share code not found", + "problem_share_link_expiry_date_in_past_title": "Expiry date cannot be in the past", + "problem_share_link_not_found_title": "Public share not found", + "problem_share_link_shocker_already_in_share_link_title": "Shocker is already in this public share", + "problem_share_link_shocker_not_in_share_link_title": "Shocker is not in this public share", + "problem_shocker_control_no_permission_title": "You do not have permission to control this shocker", + "problem_shocker_control_not_found_title": "Shocker not found", + "problem_shocker_control_paused_title": "Shocker is paused", + "problem_shocker_not_found_title": "Shocker not found", + "problem_signup_registration_disabled_title": "Registration is currently disabled", + "problem_signup_username_or_email_exists_title": "That username or email is already in use", + "problem_turnstile_invalid_title": "Verification failed", + "problem_turnstile_invalid_desc": "Please complete the challenge again and retry.", + "problem_user_not_found_title": "User not found", + "problem_user_privileged_delete_denied_title": "Privileged users cannot be deleted", + "problem_validation_error_title": "Some fields are invalid", + "problem_webhook_not_found_title": "Webhook not found", + "problem_webhook_unsupported_title": "Only Discord webhooks are supported", + "problem_webhook_unsupported_desc": "Use a discord.com URL, not canary or ptb.", + "error_too_many_requests": "Too many requests", + "error_retry_after_one": "Try again in {{count}} second.", + "error_retry_after_other": "Try again in {{count}} seconds.", + "error_unexpected_response": "Unexpected server response", + "error_internal": "Internal error occurred", + "error_network": "Network error occurred", + "dev_banner": "This is the OpenShock DEVELOPMENT environment. No data is saved, and it is regularly overwritten by production data.", + "firmware_channel_bugs_warning": "This channel might contain bugs." +} From b8f9730bc17faae6e90dec0bb658b4d377cacc04 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Luc=20=E2=99=A5?= Date: Thu, 12 Nov 2026 17:43:31 +0100 Subject: [PATCH 22/27] New translations en.json (Serbian (Cyrillic)) [ci skip] --- messages/sr.json | 1055 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 1055 insertions(+) create mode 100644 messages/sr.json diff --git a/messages/sr.json b/messages/sr.json new file mode 100644 index 00000000..ef4df56c --- /dev/null +++ b/messages/sr.json @@ -0,0 +1,1055 @@ +{ + "landing_tagline": "The go-to platform for safe, reliable, real low-latency remote shocking.", + "landing_section_label": "Home", + "landing_hubs_online": "Hubs online right now: ", + "landing_learn_more": "Learn More", + "landing_wiki": "Wiki", + "landing_meta_description": "Welcome to OpenShock, a free and open-source ecosystem to control various shock collars over the internet.", + "instance_meta_description": "Welcome to {{siteName}}, an independent instance of OpenShock, a free and open-source ecosystem to control various shock collars over the internet.", + "header_sidebar_toggle": "Toggle Sidebar", + "header_avatar_alt": "{{name}}'s avatar", + "header_menu_profile": "Profile", + "header_menu_settings": "Settings", + "header_menu_logout": "Logout", + "header_login": "Login", + "header_signup": "Sign Up", + "header_github_title": "OpenShock on GitHub", + "header_discord_title": "Community Discord", + "footer_made_with": "Made with by the OpenShock Team", + "footer_connection_status_label": "Server connection status", + "footer_signalr_state": "SignalR State", + "footer_frontend_version": "Frontend Version", + "footer_frontend_commit_title": "Commit {{commit}}", + "footer_backend_version": "Backend Version", + "footer_backend_commit_title": "Commit {{commit}}", + "footer_language_label": "Language", + "sidebar_home_link_label": "OpenShock home", + "sidebar_group_general": "General", + "sidebar_home": "Home", + "sidebar_shockers": "Shockers", + "sidebar_shared_shockers": "Shared Shockers", + "sidebar_hubs": "Hubs", + "sidebar_user_shares": "User Shares", + "sidebar_public_shares": "Public Shares", + "sidebar_serial_terminal": "Serial Terminal", + "sidebar_group_admin": "Admin", + "sidebar_admin_monitoring": "Monitoring", + "sidebar_admin_online_hubs": "Online Hubs", + "sidebar_admin_online_gateways": "Online Gateways", + "sidebar_admin_management": "Management", + "sidebar_admin_users": "Users", + "sidebar_admin_blacklists": "Blacklists", + "sidebar_admin_webhooks": "Webhooks", + "sidebar_admin_mail": "Mail", + "sidebar_admin_automation_tokens": "Automation Tokens", + "sidebar_admin_configuration": "Configuration", + "sidebar_group_settings": "Settings", + "sidebar_settings_api_tokens": "API Tokens", + "sidebar_settings_sessions": "Sessions", + "sidebar_settings_audit_log": "Audit Log", + "sidebar_settings_connections": "Connections", + "sidebar_settings_account": "Account Settings", + "error_meta_title": "Service Unavailable", + "error_meta_description": "OpenShock is currently unavailable", + "error_meta_logo_alt": "OpenShock Logo", + "error_fallback_message": "Something went wrong.", + "error_not_found_message": "Page not found", + "error_not_found_description": "The page you're looking for doesn't exist.", + "error_unexpected_description": "An unexpected error occurred.", + "error_go_back": "Go back", + "auth_layout_logo_alt": "OpenShock Logo", + "auth_layout_invalid_redirect_removed": "An invalid redirect URL was removed for your safety.", + "auth_activate_breadcrumb": "Activate Account", + "auth_activate_title": "Activate Account", + "auth_activate_activating": "Activating your account...", + "auth_activate_success": "Your account has been activated", + "auth_activate_failed": "This activation link is invalid or has expired", + "auth_activate_missing_token": "Missing activation token", + "auth_activate_continue": "Continue to login", + "auth_activate_toast_success": "Account activated", + "auth_forgot_breadcrumb": "Forgot Password", + "auth_forgot_title": "Forgot Password", + "auth_forgot_description": "Enter your email to reset your password", + "auth_forgot_email_label": "Email", + "auth_forgot_email_placeholder": "Email", + "auth_forgot_submit": "Reset Password", + "auth_forgot_signin_prompt": "Remember your password? Sign in", + "auth_forgot_mail_disabled": "Password resets are unavailable on this instance because it has no mail provider configured. Please contact your administrator for help recovering your account.", + "auth_forgot_toast_sent": "Reset password request has been sent to the given email", + "auth_login_breadcrumb": "Login", + "auth_login_title": "Welcome back", + "auth_login_loading_methods": "Loading available login methods", + "auth_login_choose_method": "Login with one of these methods", + "auth_login_with_account": "Login with your OpenShock Account", + "auth_login_activation_after_signup": "Your account has been created. We've sent an activation link to your email address. Check your inbox and spam folder.", + "auth_login_activation_pending": "Your account isn't activated yet. We've sent an activation link to your email address. Check your inbox and spam folder. If nothing arrives, try logging in again later to get a new link.", + "auth_login_oauth_only": "This account has no password. Sign in with the provider you signed up with.", + "auth_login_oauth_only_with_buttons": "This account has no password. Sign in with the provider you signed up with using the buttons above.", + "auth_login_or_continue_with": "Or continue with", + "auth_login_username_label": "Username or Email", + "auth_login_password_label": "Password", + "auth_login_submit": "Login", + "auth_login_signup_prompt": "Don't have an account? Sign up", + "auth_login_legal": "By clicking Login, you agree to our Terms of Service and Privacy Policy.", + "auth_oauth_create_breadcrumb": "Sign Up With {{provider}}", + "auth_oauth_create_title": "Sign Up With {{provider}}", + "auth_oauth_create_description": "Complete your account details", + "auth_oauth_create_username_label": "Username", + "auth_oauth_create_username_placeholder": "Username", + "auth_oauth_create_email_label": "Email", + "auth_oauth_create_email_placeholder": "Email", + "auth_oauth_create_submit": "Sign Up", + "auth_oauth_create_legal": "By clicking Sign Up, you agree to our Terms of Service and Privacy Policy.", + "auth_oauth_error_breadcrumb": "Authentication Error", + "auth_oauth_error_title": "Authentication Error", + "auth_oauth_error_back": "Back to login", + "auth_reset_breadcrumb": "Reset Password", + "auth_reset_title": "Reset Password", + "auth_reset_checking": "Verifying reset link...", + "auth_reset_choose_password": "Choose a new password for your account", + "auth_reset_invalid": "This reset link is invalid or has expired", + "auth_reset_password_label": "New Password", + "auth_reset_password_placeholder": "New Password", + "auth_reset_confirm_label": "Confirm New Password", + "auth_reset_confirm_placeholder": "Confirm New Password", + "auth_reset_submit": "Reset Password", + "auth_reset_request_new": "Request a new reset link", + "auth_reset_toast_success": "Password has been reset", + "auth_signup_breadcrumb": "Sign Up", + "auth_signup_toast_created_mail": "Account created successfully. Please check your email to verify your account.", + "auth_signup_toast_created_no_mail": "Account created successfully. You can log in now.", + "auth_signup_dialog_title": "Welcome! Thank you for signing up! ❤️", + "auth_signup_dialog_created_mail": "Your account has been created. 🎉 Please check your email to verify your account.", + "auth_signup_dialog_verify_then_login": "After verifying your email, you can log in to your account.", + "auth_signup_dialog_created_no_mail": "Your account has been created and is ready to use. 🎉", + "auth_signup_dialog_login_now": "You can log in to your account now.", + "auth_signup_title": "Create your account", + "auth_signup_loading_methods": "Loading available sign-up methods", + "auth_signup_using_email": "Signing up using email", + "auth_signup_choose_method": "Choose your preferred sign-up method", + "auth_signup_back": "Back", + "auth_signup_username_label": "Username", + "auth_signup_username_placeholder": "John OpenShock", + "auth_signup_email_label": "Email", + "auth_signup_email_placeholder": "john@example.com", + "auth_signup_password_label": "Password", + "auth_signup_password_placeholder": "Password", + "auth_signup_confirm_label": "Confirm Password", + "auth_signup_confirm_placeholder": "Confirm Password", + "auth_signup_submit": "Create Account", + "auth_signup_signin_prompt": "Already have an account? Sign in", + "auth_signup_or": "Or", + "auth_signup_with_email": "Signup with Email", + "auth_signup_legal": "By clicking Create Account, you agree to our Terms of Service and Privacy Policy.", + "auth_verify_breadcrumb": "Verify Email", + "auth_verify_title": "Verify Email", + "auth_verify_verifying": "Verifying your email address...", + "auth_verify_success": "Your email has been verified", + "auth_verify_failed": "This verification link is invalid or has expired", + "auth_verify_missing_token": "Missing verification token", + "auth_verify_continue": "Continue to login", + "auth_verify_toast_success": "Email verified", + "common_cancel": "Cancel", + "common_delete": "Delete", + "common_edit": "Edit", + "common_share": "Share", + "common_copy_id": "Copy ID", + "common_id_copied": "ID copied to clipboard", + "common_open_menu": "Open menu", + "common_refresh": "Refresh", + "common_settings": "Settings", + "common_clear": "Clear", + "common_online": "Online", + "common_offline": "Offline", + "common_paused": "Paused", + "common_resume": "Resume", + "common_resuming": "Resuming...", + "common_coming_soon": "(Coming soon)", + "common_save_changes": "Save Changes", + "common_danger_zone": "Danger Zone", + "common_name": "Name", + "control_intensity": "Intensity", + "control_duration": "Duration", + "control_max_intensity": "Max Intensity", + "control_max_duration": "Max Duration", + "control_vibration": "Vibration", + "control_value": "Value", + "control_live_intensity": "Live intensity", + "control_type_stop": "Stop", + "control_type_shock": "Shock", + "control_type_vibrate": "Vibrate", + "control_type_sound": "Sound", + "live_tooltip_active": "Live via {{gateway}} ({{country}}), {{latency}}ms", + "live_tooltip_connecting": "Connecting...", + "live_tooltip_connect": "Connect to Live Control", + "live_tooltip_hub_start": "Ctrl+click to start the whole hub", + "live_tooltip_hub_stop": "Ctrl+click to stop the whole hub", + "pause_resume_shocker": "Resume shocker", + "pause_pause_shocker": "Pause shocker", + "pause_resume_all": "Resume all shockers", + "pause_pause_all": "Pause all shockers", + "shocker_label": "Shocker", + "shocker_hub": "Hub", + "shocker_select_hub": "Select hub", + "shocker_rf_id": "RF ID", + "shocker_rf_id_invalid": "RF ID must be a whole number between {{min}} and {{max}}.", + "shocker_model": "Model", + "shocker_select_model": "Select model", + "shocker_name_placeholder": "Shocker name", + "shocker_menu_view_logs": "View Logs", + "shocker_delete_title": "Delete Shocker", + "shocker_delete_desc": "Are you sure you want to delete \"{{name}}\"? This action cannot be undone.", + "shocker_toast_deleted": "Shocker \"{{name}}\" deleted", + "shocker_toast_paused": "Shocker paused", + "shocker_toast_resumed": "Shocker resumed", + "shocker_add_desc": "Register a new shocker to one of your hubs.", + "shocker_add_name_placeholder": "My Shocker", + "shockers_title": "Shockers", + "shockers_subtitle": "Every shocker paired to your hubs.", + "shockers_loading": "Loading shockers...", + "shockers_toast_refreshed": "Shockers refreshed", + "shockers_toast_need_hub": "You need to create a hub before adding shockers.", + "shockers_toast_added": "Shocker added", + "shockers_unknown_module": "Unknown module type", + "shockers_add": "Add Shocker", + "shockers_view_mode": "View mode", + "shockers_mode_classic": "Classic", + "shockers_mode_rich": "Rich", + "shockers_mode_simple": "Simple", + "shockers_mode_map": "Map", + "shockers_group_by_hub": "Group by Hub", + "shockers_global_limits": "Global Limits", + "shockers_logs_label": "Logs", + "shockers_empty_title": "No shockers yet", + "shockers_empty_no_hubs": "Create a hub first, then add shockers to it.", + "shockers_empty_has_hubs": "Add a shocker to one of your hubs to get started.", + "shockers_create_hub": "Create a Hub", + "shockers_count_one": "{{count}} shocker", + "shockers_count_other": "{{count}} shockers", + "shared_shockers_title": "Shared Shockers", + "shared_shockers_subtitle": "Shockers other users have shared with you.", + "shared_shockers_empty_title": "No shockers have been shared with you yet.", + "shared_shockers_empty_desc": "When someone shares their shockers with you, they'll appear here.", + "shocker_logs_title": "Shocker Logs", + "shocker_logs_subtitle": "Every control command sent to your shockers.", + "shocker_logs_live_title": "New logs appear in real time", + "shocker_logs_paused_title": "Live updates pause when sorting or viewing a page other than the first", + "shocker_logs_live": "Live", + "shocker_logs_col_time": "Time", + "shocker_logs_col_type": "Type", + "shocker_logs_col_by": "By", + "shocker_logs_filter_label": "Filter by shocker", + "shocker_logs_filter_placeholder": "Search shockers...", + "shocker_logs_filter_all": "All shockers", + "shocker_logs_filter_none": "No matching shockers", + "shocker_edit_title": "Edit Shocker", + "shocker_edit_subtitle": "Change this shocker's details or remove it.", + "shocker_edit_back": "Back to Shockers", + "shocker_edit_load_failed": "Failed to load shocker.", + "shocker_edit_loading": "Loading shocker...", + "shocker_edit_details_title": "Shocker Details", + "shocker_edit_details_desc": "Update the name, RF ID, and model for this shocker.", + "shocker_edit_pause_state": "Pause State", + "shocker_edit_is_paused": "Shocker is paused", + "shocker_edit_is_active": "Shocker is active", + "shocker_edit_toast_updated": "Shocker updated", + "shocker_edit_delete_desc": "Permanently delete this shocker. This action cannot be undone.", + "common_close": "Close", + "common_continue": "Continue", + "common_loading": "Loading...", + "common_previous": "Previous", + "common_next": "Next", + "common_steps": "Steps", + "common_step_label": "Step {{number}}: {{title}}", + "common_copy": "Copy", + "common_copied": "Copied", + "common_never": "Never", + "common_error": "Error: {{message}}", + "terminal_title": "Serial Terminal", + "terminal_connecting": "Connecting...", + "terminal_help_button": "I'm having trouble, help?", + "terminal_back_to_modes": "Back to mode picker", + "terminal_mode_configure": "Configure Device", + "terminal_mode_configure_desc": "Configure WiFi, authentication, and more. Includes an interactive serial console.", + "terminal_mode_flash": "Flash Firmware", + "terminal_mode_flash_desc": "Install or update firmware on a connected device.", + "terminal_mode_raw": "Serial Monitor", + "terminal_mode_raw_desc": "Just the console. Read device logs and send commands.", + "terminal_step_channel": "Select Channel", + "terminal_step_board": "Select Board", + "terminal_go_to_step": "Go to step {{number}}: {{title}}", + "terminal_erase": "Erase before flashing", + "terminal_erase_desc": "Clears all data on the device including existing configs", + "terminal_unsupported": "Your browser does not support this feature.", + "terminal_update_browser": "Please update your browser to the latest version.", + "terminal_use_browsers": "Please use one of the following browsers:", + "terminal_connect_failed_bootloader": "Could not enter bootloader mode", + "terminal_connect_failed": "Device connection failed", + "terminal_connect_failed_desc": "We couldn't establish a serial connection with the device.", + "terminal_quick_tries": "Quick things to try:", + "terminal_try_replug": "Unplug and replug the device.", + "terminal_try_cable": "Try a different USB cable or port.", + "terminal_try_driver": "Make sure the serial driver is installed.", + "terminal_open_troubleshooter": "Open troubleshooter", + "terminal_log_reset_no_device": "Host-side error during reset: no device!", + "terminal_log_reset_error": "Host-side error during reset: {{error}}", + "terminal_log_send_no_device": "Couldn't send: no device!", + "terminal_log_send_error": "Couldn't send: {{error}}", + "terminal_log_firmware_disconnected": "Firmware disconnected: {{error}}", + "terminal_log_erase_failed": "Failed to erase flash: {{error}}", + "terminal_log_hard_reset_failed": "Failed to hard reset: {{error}}", + "terminal_log_flash_complete": "Flash complete", + "terminal_log_flash_failed": "Failed to flash: {{error}}", + "terminal_log_command_failed": "Failed to write application command: {{error}}", + "terminal_help_title": "Troubleshooter", + "terminal_help_desc": "Work through these steps in order. Each one rules out a common cause.", + "terminal_help_step_cable": "USB cable", + "terminal_help_step_port": "USB port", + "terminal_help_step_driver": "Install driver", + "terminal_help_step_manual": "Manual driver update", + "terminal_help_step_discord": "Ask on Discord", + "terminal_help_cable_body": "Many USB-C and micro-USB cables are charge-only and don't carry data. Swap to a known-good data cable (one you've used to transfer files or connect other devices) and reconnect the hub.", + "terminal_help_port_body": "Plug the device directly into a USB port on your computer. Avoid USB hubs, docking stations, and front-panel ports if possible; these are common sources of power and signal issues. If you're on a desktop, try a port on the back of the machine.", + "terminal_help_driver_download": "Download the CP210x driver:", + "terminal_help_driver_extract": "Extract the contents of the zip file to a folder on your computer.", + "terminal_help_driver_run": "Open the folder and run {{installer}}. Follow the prompts to install.", + "terminal_help_driver_reconnect": "Reconnect the device.", + "terminal_help_manual_intro": "If the driver installer ran but the device still doesn't show up:", + "terminal_help_manual_open": "Open Device Manager (press Win + X and select Device Manager).", + "terminal_help_manual_ports": "Under Ports (COM & LPT), look for an entry like:", + "terminal_help_manual_missing": "If it's missing, the device isn't being detected by Windows at all; revisit the cable and port steps.", + "terminal_help_manual_update": "Right-click the device and pick Update Driver.", + "terminal_help_manual_browse": "Choose Browse my computer for drivers and select the folder you extracted the driver zip into. Make sure Include subfolders is checked.", + "terminal_help_manual_success": "On success, the entry should now read {{deviceName}}.", + "terminal_help_discord_intro": "Still stuck after all of the above? Hop into our Discord server and ask in the {{channel}} channel. Please include:", + "terminal_help_discord_os": "your operating system and browser", + "terminal_help_discord_device": "the device you're using (board model, where you got it)", + "terminal_help_discord_tried": "what you've already tried from the previous steps", + "terminal_help_discord_errors": "any error messages or relevant terminal output", + "terminal_help_discord_join": "Join our Discord server", + "terminal_risk_title": "⚠️ UNSTABLE FIRMWARE", + "terminal_risk_intro": "You are about to flash experimental firmware that is known to be unstable.", + "terminal_risk_brick": "This may permanently brick your device, require manual recovery, or render it unusable.", + "terminal_risk_no_support": "We will NOT provide support for issues caused by this firmware.", + "terminal_risk_acknowledge": "I understand this is entirely my responsibility", + "terminal_risk_abort": "Abort", + "terminal_risk_accept": "I ACCEPT FULL RESPONSIBILITY", + "firmware_channel_recommended": "This is the recommended channel.", + "firmware_channel_danger": "DO NOT USE THIS UNLESS YOU KNOW WHAT YOU ARE DOING", + "firmware_channel_stable": "Stable", + "firmware_channel_beta": "Beta", + "firmware_channel_develop": "Develop", + "terminal_board_select": "Select a board...", + "terminal_board_search": "Search boards...", + "terminal_board_none": "No board found.", + "terminal_flash_button": "Flash", + "terminal_flash_progress": "Flash Progress: {{status}}", + "terminal_flash_idle": "Idle", + "terminal_flash_no_device": "No device selected.", + "terminal_flash_resetting": "Resetting...", + "terminal_flash_downloading": "Downloading firmware...", + "terminal_flash_download_failed": "Failed to download firmware.", + "terminal_flash_flashing": "Flashing firmware...", + "terminal_flash_rebooting": "Rebooting device... (Reconnect to power manually if stuck)", + "terminal_flash_done": "Rebooted device! Flashing complete.", + "terminal_port_select": "Select Device", + "terminal_port_disconnect": "Disconnect Device", + "terminal_port_connected": "Device connected: {{id}}", + "terminal_console": "Console", + "terminal_connected_device": "Connected device", + "terminal_resize": "Resize terminal panel", + "terminal_reboot": "Reboot", + "terminal_disconnect": "Disconnect", + "terminal_fullscreen_exit_esc": "Exit fullscreen (Esc)", + "terminal_fullscreen_exit": "Exit fullscreen", + "terminal_fullscreen_fill": "Fill the window", + "terminal_command_label": "Serial command", + "terminal_command_placeholder": "Type a command...", + "terminal_command_send": "Send command", + "terminal_colors": "Colors", + "terminal_colors_menu": "Colors...", + "terminal_colors_label": "Console colors", + "terminal_colors_close": "Close colors", + "terminal_color_input": "{{name}} color", + "terminal_colors_reset": "Reset to defaults", + "terminal_color_bg": "Background", + "terminal_color_fg": "Text", + "terminal_color_ts": "Timestamp", + "terminal_color_error": "Error", + "terminal_color_warning": "Warning", + "terminal_color_info": "Info", + "terminal_color_debug": "Debug", + "terminal_color_verbose": "Verbose", + "terminal_options": "Options", + "terminal_options_label": "Console options", + "terminal_hide_system": "Hide system messages", + "terminal_stick_bottom": "Stick to bottom", + "terminal_raw_output": "Raw output", + "terminal_timestamps": "Timestamps", + "terminal_timestamp_uptime": "Uptime", + "terminal_timestamp_local": "Local", + "terminal_timestamp_ms": "Ms", + "terminal_timestamp_off": "Off", + "terminal_copy_settings": "Copy settings", + "terminal_import_settings": "Import settings", + "terminal_copy_selection": "Copy selection", + "terminal_copy_all": "Copy all output", + "terminal_toast_selection_copied": "Selection copied", + "terminal_toast_output_copied": "Console output copied", + "terminal_toast_settings_copied": "Console settings copied", + "terminal_toast_clipboard_unreadable": "Could not read the clipboard", + "terminal_toast_settings_imported": "Console settings imported", + "terminal_toast_settings_invalid": "Clipboard does not contain console settings", + "common_try_again": "Try again", + "terminal_cfg_intro": "Values are sent to the device via UART. Read the device's response in the console below. Commands without an argument act as getters; use the button next to each field to read the current value.", + "terminal_cfg_rf_title": "RF Transmitter", + "terminal_cfg_rf_desc": "Controls the shocker RF output.", + "terminal_cfg_tx_pin": "TX GPIO pin", + "terminal_cfg_example": "e.g. {{value}}", + "terminal_cfg_read_value": "Read current value", + "terminal_cfg_set": "Set", + "terminal_cfg_read": "Read", + "terminal_cfg_reading": "Reading…", + "terminal_cfg_apply": "Apply", + "terminal_cfg_keepalive": "Keepalive enabled", + "terminal_cfg_keepalive_desc": "Periodically pings paired shockers to keep them awake.", + "terminal_cfg_estop_title": "Emergency Stop", + "terminal_cfg_estop_desc": "Hardware button that halts all output.", + "terminal_cfg_estop_enabled": "EStop enabled", + "terminal_cfg_estop_pin": "EStop GPIO pin", + "terminal_cfg_estop_note": "Note: {{latching}} and {{active}} have no dedicated commands; set them via the JSON config below.", + "terminal_cfg_wifi_title": "WiFi", + "terminal_cfg_wifi_desc": "Station credentials and device hostname.", + "terminal_cfg_hostname": "Hostname", + "terminal_cfg_networks": "Networks (JSON array)", + "terminal_cfg_invalid_json_array": "Must be a valid JSON array", + "terminal_cfg_ap_note": "AP settings ({{ssid}}, {{password}}, {{disabled}}, {{staDisabled}}, {{offlineMode}}) have no dedicated commands; use the JSON config.", + "terminal_cfg_backend_title": "Backend", + "terminal_cfg_backend_desc": "OpenShock server and authentication.", + "terminal_cfg_domain": "Domain", + "terminal_cfg_domain_restart": "Setting the domain will restart the device.", + "terminal_cfg_auth_token": "Auth token", + "terminal_cfg_auth_token_placeholder": "Paste device token", + "terminal_cfg_hide": "Hide", + "terminal_cfg_show": "Show", + "terminal_cfg_serial_title": "Serial Input", + "terminal_cfg_echo": "Echo enabled", + "terminal_cfg_echo_desc": "Print typed characters back to the console.", + "terminal_cfg_advanced_title": "Advanced: full config", + "terminal_cfg_advanced_desc": "For fields without dedicated commands (captive portal, OTA, LAN, etc.), replace the entire config.", + "terminal_cfg_json_config": "JSON config", + "terminal_cfg_invalid_json": "Must be valid JSON", + "terminal_cfg_read_json": "Read current config as JSON", + "terminal_cfg_json_restart": "Applying a JSON config will restart the device.", + "terminal_cfg_raw_config": "Raw FlatBuffer config (base64)", + "terminal_cfg_invalid_base64": "Must be a valid base64 string", + "terminal_cfg_read_raw": "Read current config as base64", + "terminal_cfg_factory_reset": "Factory reset", + "terminal_cfg_factory_reset_desc": "Wipes the entire device configuration.", + "terminal_cfg_factory_reset_title": "Factory reset device?", + "terminal_cfg_factory_reset_action": "Wipe config", + "terminal_cfg_factory_reset_confirm": "This will erase all configuration on the device; WiFi networks, backend credentials, pins, and all other settings. The device will be reset to defaults.", + "terminal_cfg_read_failed_json_title": "Couldn't read the JSON config", + "terminal_cfg_read_failed_raw_title": "Couldn't read the raw config", + "terminal_cfg_read_failed_desc": "The device didn't respond after {{attempts}} attempts.", + "terminal_cfg_common_causes": "Common causes:", + "terminal_cfg_cause_busy": "The device is busy handling another command.", + "terminal_cfg_cause_disconnected": "The device disconnected or rebooted.", + "terminal_cfg_cause_unsupported": "The firmware version doesn't support this command.", + "common_status": "Status", + "common_version": "Version", + "common_created": "Created", + "common_create": "Create", + "common_done": "Done", + "common_enable": "Enable", + "common_disable": "Disable", + "common_are_you_sure": "Are you sure?", + "common_generating": "Generating...", + "hubs_title": "Hubs", + "hubs_subtitle": "Every hub registered to your account.", + "hubs_add": "Add Hub", + "hubs_load_failed": "Failed to load hubs.", + "hubs_empty_title": "No hubs yet", + "hubs_empty_desc": "A hub is the device that relays commands to your shockers. Add one to get started.", + "hubs_create_title": "Create hub", + "hubs_name_label": "Hub Name", + "hubs_name_placeholder": "My Hub", + "hub_toast_not_connected": "Not connected to the server", + "hub_toast_try_later": "Try again in a moment.", + "hub_reboot_title": "Reboot {{name}}?", + "hub_reboot_desc": "The hub will disconnect and restart. Any shockers paired to it stop responding until it comes back online.", + "hub_reboot": "Reboot", + "hub_hotspot_enable_title": "Enable Wi-Fi hotspot on {{name}}?", + "hub_hotspot_disable_title": "Disable Wi-Fi hotspot on {{name}}?", + "hub_hotspot_enable_desc": "The hub broadcasts its own setup network. It stays reachable on your Wi-Fi, but the hotspot is open to anyone in range until you turn it off.", + "hub_hotspot_disable_desc": "The setup hotspot shuts down. If the hub is not already on your Wi-Fi you will need physical access to set it up again.", + "hub_delete_desc": "You are about to delete hub {{name}}.", + "hub_delete_shockers": "This will also delete the following shockers:", + "hub_edit_title": "Edit hub", + "hub_edit_apply": "Apply", + "hub_pair_title_generate": "Generate pair code?", + "hub_pair_title_generated": "Pair code generated", + "hub_pair_title_paired": "Hub paired", + "hub_pair_consumed": "{{name}} consumed this pair code and is now paired.", + "hub_pair_used": "The code has been used and is no longer valid.", + "hub_pair_generated_for": "Pair code generated for {{name}}.", + "hub_copy_now": "The code below will not be accessible later, please copy it now and update clients with it.", + "hub_pair_generate_for": "You are about to generate a pair code for {{name}}.", + "hub_pair_valid_for": "It will be valid for 15 minutes after its creation.", + "hub_pair_one_active": "There is only one active pair code per hub, newly generated ones will override the older active ones.", + "hub_pair_complete": "Pairing complete", + "hub_pair_code_label": "Pair code:", + "hub_pair_copied_close": "Code has been copied, close", + "hub_pair_get": "Get Pair Code", + "hub_token_generated": "Token generated", + "hub_token_generated_for": "New token generated for {{name}}.", + "hub_token_regenerate_for": "You are about to regenerate the token for {{name}}.", + "hub_token_invalidate": "This action will invalidate the current token and disconnect clients using it.", + "hub_token_confirm": "Are you sure you want to do this?", + "hub_token_label": "New token:", + "hub_token_copied_close": "Token has been copied, close", + "hub_token_regenerate": "Regenerate Token", + "hub_menu_update": "Update", + "hub_menu_label": "Hub", + "hub_menu_hotspot_enable": "Enable Wi-Fi hotspot", + "hub_menu_hotspot_disable": "Disable Wi-Fi hotspot", + "hub_menu_pair": "Pair", + "hub_menu_estop": "Emergency Stop", + "hub_update_breadcrumb": "Update", + "hub_update_unknown_hub": "Unknown Hub", + "hub_update_unknown_task": "Unknown Task", + "hub_update_task_metadata": "Fetching Metadata", + "hub_update_task_preparing": "Preparing for Update", + "hub_update_task_flash_fs": "Flashing Filesystem", + "hub_update_task_verify_fs": "Verifying Filesystem", + "hub_update_task_flash_app": "Flashing Application", + "hub_update_task_bootable": "Marking Application Bootable", + "hub_update_task_rebooting": "Rebooting", + "hub_update_status_started": "Started", + "hub_update_status_running": "Running", + "hub_update_status_finished": "Finished", + "hub_update_status_error": "Error", + "hub_update_status_timeout": "Timeout", + "hub_update_confirm_title": "Confirm firmware update", + "hub_update_confirm_desc": "Update {{name}} to version {{version}}?", + "hub_update_unstable_warning": "This version may not be from the stable channel and could contain bugs.", + "hub_update_title": "Update {{name}}", + "hub_update_subtitle": "Manage firmware updates for this hub.", + "hub_update_status_title": "Hub Status", + "hub_update_firmware": "Firmware: {{version}}", + "hub_update_confirm": "Update", + "hub_update_success": "Update completed successfully", + "hub_update_rolled_back": "Device rolled back to previous version", + "hub_update_back": "Back to Hubs", + "hub_update_flash_again": "Flash Again", + "hub_update_card_title": "Firmware Update", + "hub_update_card_desc": "Select a firmware channel and version to install.", + "hub_update_to": "Update to {{version}}", + "hub_update_must_be_online": "Hub must be online to start an update.", + "hub_update_updating_to": "Updating to {{version}}...", + "hub_update_total": "Total", + "hub_update_task": "Task", + "hub_update_history": "Update History", + "hub_update_no_history": "No update history found for this hub.", + "hub_update_col_id": "ID", + "hub_update_col_started": "Started", + "hub_update_col_message": "Message", + "hub_update_loading": "Loading hub information...", + "hub_update_not_found": "Hub not found.", + "home_breadcrumb": "Home", + "home_welcome": "Welcome back", + "home_welcome_name": "Welcome back, {{name}}", + "home_subtitle": "Here's an overview of your OpenShock setup.", + "home_hubs_online": "{{count}} online", + "home_hub_status": "Hub Status", + "home_no_hubs": "No hubs", + "home_all_online": "All online", + "home_all_offline": "All offline", + "home_some_online": "{{online}}/{{total}} online", + "home_quick_links": "Quick Links", + "home_my_shockers": "My Shockers", + "home_my_shockers_desc": "Control your shockers", + "home_hubs_desc": "Manage your hubs", + "home_shared_desc": "Shockers shared with you", + "home_public_desc": "Manage share links", + "home_get_started": "Get Started", + "home_get_started_desc": "You don't have any hubs yet. Create a hub to connect your first device, then add shockers to it.", + "home_set_up_hub": "Set Up a Hub", + "home_first_shocker": "Add Your First Shocker", + "home_first_shocker_desc_one": "You have {{count}} hub set up. Add a shocker to start controlling it.", + "home_first_shocker_desc_other": "You have {{count}} hubs set up. Add a shocker to start controlling it.", + "home_go_to_shockers": "Go to Shockers", + "profile_title": "Profile", + "profile_coming_soon": "Profile is coming soon", + "profile_coming_soon_desc": "Your public profile is not available yet. Account details live under Settings.", + "common_retry": "Retry", + "common_never_used": "Never used", + "common_expires": "Expires {{time}}", + "common_search_placeholder": "Search...", + "common_unknown": "Unknown", + "settings_breadcrumb_account": "Account", + "account_subtitle": "Your sign-in details and account actions.", + "account_change_username": "Change Username", + "account_change_email": "Change Email", + "account_change_password": "Change Password", + "account_username_label": "Username", + "account_email_label": "Email", + "account_password_label": "Password", + "account_new_password_label": "New Password", + "account_confirm_password_label": "Confirm New Password", + "account_oauth_only": "Not available for OAuth-only accounts", + "account_oauth_no_password": "This account signs in via OAuth and has no password.", + "account_diagnostics": "Diagnostics", + "account_diagnostics_desc": "Help us fix crashes and slow API calls. Reports include the error message, stack trace and your IP. Off by default.", + "account_diagnostics_level": "Diagnostics level", + "account_telemetry_off": "Off", + "account_telemetry_off_desc": "Send nothing.", + "account_telemetry_errors": "Errors", + "account_telemetry_errors_desc": "Send browser error reports only.", + "account_telemetry_full": "Full", + "account_telemetry_full_desc": "Error reports plus traces of API calls (no page navigations).", + "account_toast_deactivated": "Account deactivated successfully", + "account_deactivate_title": "Deactivate account", + "account_deactivate_desc": "Are you sure you want to deactivate your account?", + "account_deactivate": "Deactivate Account", + "account_email_title": "Change email", + "account_email_desc": "Enter your new email address and confirm with your current password.", + "account_email_toast_sent": "Verification email sent to {{email}}. Click the link in that email to apply the change.", + "account_new_email": "New Email", + "account_current_password": "Current Password", + "account_password_title": "Change password", + "account_password_desc": "Enter your current password and choose a new one.", + "account_password_toast": "Password has been changed", + "account_username_title": "Change username", + "account_username_desc": "Enter a new username.", + "account_new_username": "New Username", + "account_username_toast": "Username changed successfully", + "tokens_subtitle": "API Tokens are used to authenticate with the OpenShock API.", + "tokens_generate": "Generate Token", + "tokens_toast_refreshed": "Tokens refreshed successfully", + "tokens_empty_title": "No API tokens", + "tokens_empty_desc": "Generate a token to authenticate with the OpenShock API.", + "tokens_created_on": "Created {{date}}", + "tokens_last_used": "Last used {{time}}", + "tokens_never_expires": "Never expires", + "tokens_load_failed": "Failed to load API tokens.", + "token_toast_edited": "Token edited successfully", + "token_name_required": "Name is required", + "token_name_too_long": "Name is too long", + "token_edit_title": "Edit API token", + "token_name_label": "Token Name", + "token_name_placeholder": "Token name...", + "token_permissions": "Permissions", + "token_perm_category_shockers": "Shockers", + "token_perm_category_devices": "Hubs", + "token_perm_category_usershares": "User Shares", + "token_perm_category_publicshares": "Public Shares", + "token_perm_use": "Use", + "token_perm_edit": "Edit", + "token_perm_pause": "Pause", + "token_perm_auth": "Authenticate", + "token_shocker_control": "Shocker Control", + "token_toast_paused": "Token paused", + "token_toast_resumed": "Token resumed", + "token_delete_title": "Delete API token", + "token_delete_desc": "Are you sure you want to delete {{name}}?", + "token_delete_permanent": "This action cannot be undone. This will permanently delete the token.", + "token_toast_deleted": "Token deleted successfully", + "token_resume": "Resume token", + "token_pause": "Pause token", + "token_mode_clamp_desc": "Clamp: requests outside the allowed range are capped to the nearest limit (the min or the max).", + "token_mode_lerp_desc": "Lerp: the full input range is linearly rescaled so it fits within your allowed min–max range.", + "token_paused_desc": "A paused token may not send shocker control messages.", + "token_intensity_range": "Intensity range", + "token_duration_range": "Duration range", + "token_new_breadcrumb": "New", + "token_redirect_not_allowed": "The provided redirect_uri is not allowed. Only loopback addresses or custom application schemes are permitted.", + "token_params_missing": "Required get parameters are missing. Make sure name, redirect_uri, and permissions are provided.", + "token_invalid_permissions": "Invalid permissions provided: {{list}}", + "token_toast_created": "Token created successfully", + "token_request_title": "API Token Request", + "token_access_granted": "Access granted", + "token_shared_redirecting": "The token has been created and shared with the application. Redirecting you back to {{uri}}.", + "token_not_redirected": "If you are not redirected automatically, use the button below.", + "token_finish": "Finish", + "token_generated_title": "API Token Generated", + "token_copy_now": "Please copy your API Token now, you will not be able to view it again later!", + "token_new_title": "New API Token", + "token_external_desc": "An external application is requesting access to your account. Review and adjust the permissions below before allowing access.", + "token_new_desc": "Configure and generate a new API token for your account.", + "token_external_requesting": "{{name}} is requesting an API Token. Your token will be shared with the application at {{uri}}.", + "token_allow": "Allow", + "token_generate": "Generate", + "token_deny": "Deny", + "sessions_subtitle": "Every active session on your account. Revoke any you do not recognize.", + "sessions_unknown_device": "Unknown device", + "sessions_toast_refreshed": "Sessions refreshed successfully", + "sessions_load_failed": "Failed to load sessions.", + "sessions_empty_title": "No active sessions", + "sessions_empty_desc": "Sessions appear here once you sign in from a browser or app.", + "sessions_last_seen": "Last seen {{time}}", + "sessions_signed_in": "Signed in {{time}}", + "session_toast_revoked": "Session revoked successfully", + "session_revoke_title": "Revoke session", + "session_revoke": "Revoke", + "session_revoke_desc": "Are you sure you want to revoke this session?", + "session_revoke_from": "Session logged in from {{ip}} using {{agent}}", + "connections_title": "OAuth Connections", + "connections_subtitle": "Link or unlink third-party accounts to sign in faster and keep your profile in sync.", + "connections_toast_linked": "Account linked.", + "connections_toast_cancelled": "Link flow cancelled.", + "connections_toast_failed": "Linking failed.", + "connections_toast_removed": "Connection removed", + "connections_refreshing": "Refreshing…", + "connections_link_new": "Link new provider", + "connections_empty_title": "No connections yet", + "connections_empty_desc": "Choose “Link new provider” above to connect available providers.", + "connections_unlink": "Unlink", + "connections_load_failed": "Failed to load OAuth connections.", + "connections_unlink_title": "Unlink {{name}}?", + "connections_unlink_title_generic": "Unlink this account?", + "connections_unlink_desc": "You'll no longer be able to sign in with this provider unless you link it again.", + "provider_starting": "Starting {{name}}...", + "provider_link": "Link {{name}}", + "audit_subtitle": "Security-relevant activity on your account. Review anything you do not recognize.", + "audit_col_time": "Time", + "audit_col_action": "Action", + "audit_col_details": "Details", + "audit_col_reason": "Reason", + "audit_col_ip": "IP address", + "audit_col_device": "Device", + "audit_action_login": "Signed in", + "audit_action_logout": "Signed out", + "audit_action_password_changed": "Password changed", + "audit_action_email_change_requested": "Email change requested", + "audit_action_email_changed": "Email changed", + "audit_action_username_changed": "Username changed", + "audit_action_api_token_created": "API token created", + "audit_action_api_token_deleted": "API token deleted", + "audit_action_oauth_connected": "Connection added", + "audit_action_oauth_disconnected": "Connection removed", + "audit_action_account_deactivated": "Account deactivated", + "audit_action_account_reactivated": "Account reactivated", + "audit_action_account_deleted": "Account deleted", + "audit_action_automation_token_created": "Automation token created", + "audit_action_automation_token_updated": "Automation token updated", + "audit_action_automation_token_rotated": "Automation token rotated", + "audit_action_automation_token_deleted": "Automation token deleted", + "audit_action_automation_token_used": "Automation token used", + "audit_meta_session": "Session {{id}}", + "audit_meta_changed": "{{old}} to {{new}}", + "audit_meta_email_requested": "Requested change to {{email}}", + "audit_meta_accounts_removed_one": "{{name}} ({{count}} account removed)", + "audit_meta_accounts_removed_other": "{{name}} ({{count}} accounts removed)", + "audit_meta_scheduled_deletion": "Scheduled for deletion", + "audit_meta_kept": "Kept for reactivation", + "common_view": "View", + "common_save": "Save", + "common_saving": "Saving...", + "common_back": "Back", + "common_shared_by": "Shared by", + "common_user_avatar": "User Avatar", + "common_toast_saved": "Changes saved successfully", + "pause_reason_shocker": "Paused at shocker level", + "pause_reason_shocker_user_share": "Paused at shocker and user share level", + "pause_reason_shocker_public_share": "Paused at shocker and public share level", + "pause_reason_user_share": "Paused at user share level", + "pause_reason_public_share": "Paused at public share level", + "public_shares_subtitle": "A link anyone can use, no account required.", + "public_shares_new": "New Share", + "public_share_never_expires": "Never expires", + "public_shares_empty_title": "No public shares yet", + "public_shares_empty_desc": "Create a link that anyone can use to control your shockers.", + "public_share_expired": "Expired", + "public_share_no_expiry": "No expiry", + "public_share_label": "Public Share", + "public_share_toast_created": "Created new public share", + "public_share_create_title": "Create public share", + "public_share_toast_deleted": "Deleted public share", + "public_share_delete_title": "Delete public share", + "public_share_delete_desc": "Are you sure you want to delete public share {{name}}?", + "public_share_edit_title": "Public Share: {{name}}", + "public_share_edit_subtitle": "Editing: changes apply when you save.", + "public_share_add_shocker": "Add Shocker", + "public_share_toast_added_one": "Added {{count}} shocker to share", + "public_share_toast_added_other": "Added {{count}} shockers to share", + "public_share_empty_shockers_title": "No shockers in this share", + "public_share_empty_shockers_desc": "Add a shocker and anyone with the link will be able to control it.", + "public_share_load_failed": "Error fetching public share details", + "public_share_paused_here": "Paused for this share", + "public_share_resume_shocker": "Resume shocker", + "public_share_pause_shocker": "Pause shocker", + "public_share_remove": "Remove from share", + "public_share_toast_removed": "Shocker removed from share", + "public_share_add_title": "Add shockers", + "public_share_add_desc": "Add shockers to this public share. You can set their limits once they are added.", + "public_share_add_placeholder": "Select shockers to share...", + "public_share_add_no_match": "No matching shockers", + "public_share_add_submit": "Add Shockers", + "public_share_view_loading": "Loading share details...", + "public_share_view_title": "Public Share Link", + "public_share_view_desc": "Enter as a guest or login with your OpenShock account", + "public_share_view_guest_name": "Guest Name", + "public_share_view_enter": "Enter", + "public_share_view_enter_guest": "Enter as Guest", + "public_share_login": "Login", + "perm_shock_on": "Shock enabled", + "perm_shock_off": "Shock disabled", + "perm_vibrate_on": "Vibrate enabled", + "perm_vibrate_off": "Vibrate disabled", + "perm_sound_on": "Sound enabled", + "perm_sound_off": "Sound disabled", + "perm_live_on": "Live enabled", + "perm_live_off": "Live disabled", + "perm_live_control": "Live Control", + "user_selector_avatar_of": "{{name}}'s avatar", + "user_selector_placeholder": "Enter user name", + "user_selector_aria": "Username to search", + "user_selector_search": "Search user", + "user_selector_found": "User found", + "common_remove": "Remove", + "user_shares_subtitle": "Direct permanent shares with other users.", + "user_shares_toast_invited": "Sent a shocker invite to {{name}}", + "user_shares_redeem": "Redeem Code", + "user_shares_new": "New Share", + "user_shares_tab_shares": "Shares", + "user_shares_tab_incoming": "Shared with Me", + "user_shares_tab_invites": "Invites", + "share_code_create_title": "New share code", + "share_code_create_desc": "Create a Share Code or Invite", + "share_code_shocker_placeholder": "Select shockers to share...", + "share_code_no_match": "No matching shockers", + "share_code_send_invite": "Send Share Invite", + "share_code_create": "Create Share Code", + "share_code_created_title": "Share code generated", + "share_code_created_desc": "Please copy share code or code link!", + "share_code_redeem_title": "Redeem share code", + "share_code_redeem_desc": "Enter the share code to redeem", + "share_code_redeem_placeholder": "Enter share code", + "share_code_redeemed": "Redeemed successfully!", + "share_code_shared_shockers": "Shared shockers", + "share_code_redeeming": "Redeeming...", + "share_code_redeem": "Redeem", + "incoming_shares_empty_title": "Nothing shared with you", + "incoming_shares_empty_desc": "No one has shared a shocker with you yet.", + "incoming_share_toast_removed": "Removed share for {{name}}", + "incoming_share_remove_title": "Remove Share", + "incoming_share_remove_desc": "Are you sure you want to remove the share for {{name}}?", + "incoming_share_toast_removed_shocker": "Removed {{shocker}} shared by {{name}}", + "incoming_share_remove_shocker_title": "Remove this shared shocker?", + "incoming_share_remove_shocker_desc": "Are you sure you want to remove the shocker share {{shocker}} by {{name}}?", + "incoming_share_manage_from": "Manage shares from", + "share_remove": "Remove share", + "invites_empty_title": "No invites yet", + "invites_empty_desc": "You have no incoming or outgoing share invites.", + "invites_outgoing": "Outgoing", + "invites_outgoing_empty_title": "No outgoing invites", + "invites_outgoing_empty_desc": "You have no outgoing share invites.", + "invites_incoming": "Incoming", + "invites_incoming_empty_title": "No incoming invites", + "invites_incoming_empty_desc": "You have no incoming share invites.", + "invite_toast_accepted": "Accepted share invite from {{name}}", + "invite_toast_declined": "Declined share invite from {{name}}", + "invite_deny_title": "Deny Invite", + "invite_deny_label": "Deny Invite", + "invite_deny": "Deny", + "invite_deny_desc": "Are you sure you want to deny the invite from {{name}}?", + "invite_accept": "Accept Invite", + "invite_toast_cancelled_for": "Cancelled invite for {{name}} ({{id}})", + "invite_toast_cancelled": "Cancelled invite {{id}}", + "invite_cancel_title": "Cancel Invite", + "invite_cancel": "Cancel", + "invite_cancel_for_desc": "Are you sure you want to cancel the invite for {{name}}?", + "invite_cancel_code_desc": "Are you sure you want to cancel the invite with code {{code}}?", + "invite_cancel_outstanding": "Cancel Outstanding Invite", + "outgoing_shares_empty_title": "No shared shockers", + "outgoing_shares_empty_desc": "You haven't shared any shockers with other users yet.", + "outgoing_share_toast_removed": "Removed shocker share {{name}}", + "outgoing_share_remove_title": "Stop sharing this shocker?", + "outgoing_share_editing_for": "Editing shares for", + "outgoing_share_limits": "Limits & Permissions", + "outgoing_share_same": "Same restrictions on every shocker", + "outgoing_share_per_desc": "Tune restrictions per shocker", + "outgoing_share_all": "All", + "outgoing_share_per": "Per shocker", + "outgoing_share_remove_desc": "Are you sure you want to stop sharing {{shocker}} with {{name}}?", + "report_breadcrumb": "Report API Tokens", + "report_toast_clipboard_failed": "Failed to read clipboard: {{error}}", + "report_title": "Report Leaked API Tokens", + "report_paste": "Paste from clipboard", + "report_warning": "This form is only for reporting accidentally leaked API tokens.", + "report_abuse_warning": "Intentional abuse will result in bans or severe endpoint restrictions.", + "report_detected": "Detected Tokens", + "report_invalid": "One or more tokens appear to be invalid. Please check for formatting issues.", + "report_acknowledge": "I confirm I understand what this feature is for and accept responsibility.", + "report_submit": "Submit Report", + "turnstile_disabled": "Turnstile disabled", + "common_internal_error": "Internal error", + "resend_toast_sent": "Activation email sent. Check your inbox and spam folder.", + "resend_toast_throttled": "Too many activation emails have been requested. Please try again later.", + "resend_toast_unavailable": "No activation email can be resent from this browser. If your account isn't activated yet, logging in sends a new link.", + "resend_button": "Didn't get the email? Resend", + "expiration_label": "Expiration", + "expiration_never": "Never", + "expiration_custom": "Custom", + "expiration_days_one": "{{count}} Day", + "expiration_days_other": "{{count}} Days", + "expiration_required": "Expire date is required", + "expiration_never_desc": "This will never expire", + "expiration_expires_at": "Expires {{time}} ({{date}})", + "date_picker_placeholder": "Pick a date", + "telemetry_toast_title": "Help improve OpenShock?", + "telemetry_toast_desc": "Send diagnostics to help us fix crashes and slow API calls. Reports include the error message, stack trace and your IP. You can change this any time in Account settings.", + "telemetry_toast_no": "No thanks", + "telemetry_toast_errors": "Errors only", + "telemetry_toast_full": "Full", + "table_show_details": "Show details", + "table_hide_details": "Hide details", + "table_no_results": "No results.", + "table_sort_asc": "Sort by {{name}}, ascending", + "table_sort_desc": "Sort by {{name}}, descending", + "table_sort_none": "Sort by {{name}}, unsorted", + "cell_na": "N/A", + "cell_not_applicable": "Not applicable", + "cell_invalid": "Invalid", + "cell_unavailable": "Unavailable", + "cell_none": "None", + "oauth_login_with": "Login with {{provider}}", + "oauth_signup_with": "Signup with {{provider}}", + "signalr_connect_failed": "Failed to connect to server!", + "signalr_disconnect_failed": "Encountered error while disconnecting from server!", + "signalr_invalid_update": "Received invalid update from server!", + "signalr_invalid_log": "Received invalid log data from server!", + "signalr_invalid_ota": "Received invalid firmware update data from server!", + "ota_toast_failed": "Hub firmware update failed: {{message}}", + "ota_toast_succeeded": "Hub firmware update completed successfully!", + "ota_toast_rolled_back": "Hub firmware rolled back to previous version", + "lcg_connect_failed": "Failed to connect to live control gateway", + "terminal_toast_bootloader_failed": "Failed to enter bootloader: {{error}}", + "terminal_toast_app_mode_failed": "Failed to enter application mode: {{error}}", + "problem_account_account_not_activated_title": "Account not activated", + "problem_account_account_not_activated_desc": "Check your inbox for the activation email.", + "problem_account_activation_not_found_title": "Activation link is invalid", + "problem_account_activation_not_found_desc": "The link may have expired or already been used.", + "problem_account_activation_resend_too_many_title": "Too many activation emails requested", + "problem_account_activation_resend_too_many_desc": "Please wait a while before trying again.", + "problem_account_activation_resend_unavailable_title": "Cannot resend activation email", + "problem_account_activation_resend_unavailable_desc": "Log in again to request a new activation link.", + "problem_account_deactivate_already_deactivated_title": "Account is already deactivated", + "problem_account_deactivate_denied_privileged_title": "Privileged accounts cannot be deactivated", + "problem_account_deactivate_unauthorized_title": "You are not allowed to do this", + "problem_account_deactivated_title": "This account has been deactivated", + "problem_account_email_already_in_use_title": "That email address is already in use", + "problem_account_email_invalid_title": "That email address is not valid", + "problem_account_email_taken_title": "That email address is already in use", + "problem_account_email_too_many_requests_title": "Too many email change requests", + "problem_account_email_too_many_requests_desc": "Please wait a while before trying again.", + "problem_account_email_unchanged_title": "That is already your email address", + "problem_account_email_verify_not_found_title": "Verification link is invalid", + "problem_account_email_verify_not_found_desc": "The link may have expired or already been used.", + "problem_account_o_auth_only_title": "This account has no password", + "problem_account_o_auth_only_desc": "Sign in with the provider you signed up with.", + "problem_account_password_not_set_title": "No password set", + "problem_account_password_not_set_desc": "This account signs in through an external provider.", + "problem_account_password_old_password_invalid_title": "Current password is incorrect", + "problem_account_username_invalid_title": "That username is not allowed", + "problem_account_username_recently_changed_title": "Username changed too recently", + "problem_account_username_recently_changed_desc": "You can change your username once every 7 days.", + "problem_account_username_taken_title": "That username is already taken", + "problem_admin_user_deactivated_title": "This user is deactivated", + "problem_admin_user_not_activated_title": "This user has not been activated yet", + "problem_api_token_can_only_delete_self_title": "An API token can only delete itself", + "problem_api_token_not_found_title": "API token not found", + "problem_api_token_paused_title": "This API token is paused", + "problem_assign_lcg_bad_schema_version_title": "Unsupported hub protocol version", + "problem_assign_lcg_bad_schema_version_desc": "Update the hub firmware to connect.", + "problem_assign_lcg_no_lcg_available_title": "No gateway available", + "problem_assign_lcg_no_lcg_available_desc": "No live control gateway is available right now. Please try again later.", + "problem_authentication_account_deactivated_title": "This account has been deactivated", + "problem_authentication_account_not_activated_title": "This account has not been activated", + "problem_authentication_cookie_missing_or_invalid_title": "You are not logged in", + "problem_authentication_cookie_missing_or_invalid_desc": "Your session may have expired. Please log in again.", + "problem_authentication_header_missing_or_invalid_title": "Invalid API token", + "problem_authentication_session_invalid_title": "Session expired", + "problem_authentication_session_invalid_desc": "Please log in again.", + "problem_authentication_token_invalid_title": "Invalid API token", + "problem_authentication_unknown_error_title": "Authentication failed", + "problem_authorization_policy_not_met_title": "You do not have permission to do this", + "problem_authorization_token_only_title": "This action requires an API token", + "problem_authorization_token_permission_missing_title": "This API token is missing a required permission", + "problem_authorization_unknown_error_title": "Authorization failed", + "problem_authorization_user_session_only_title": "This action requires a logged-in session", + "problem_automation_token_not_allowed_for_account_title": "Automation tokens cannot be used with privileged accounts", + "problem_configuration_already_exists_title": "A configuration entry with that name already exists", + "problem_configuration_invalid_name_format_title": "Invalid configuration name", + "problem_configuration_invalid_name_format_desc": "Only A to Z and underscores are allowed.", + "problem_configuration_invalid_value_format_title": "Value does not match the configuration type", + "problem_configuration_not_found_title": "Configuration entry not found", + "problem_control_stats_invalid_range_title": "The from date must not be after the to date", + "problem_control_stats_invalid_time_zone_title": "Unknown time zone", + "problem_control_stats_missing_capability_title": "Control statistics are not available on this server", + "problem_device_not_found_title": "Hub not found", + "problem_device_not_online_title": "Hub is offline", + "problem_device_too_many_hubs_title": "You have reached the maximum number of hubs", + "problem_device_too_many_shockers_title": "This hub has reached its maximum number of shockers", + "problem_endpoint_retired_title": "This feature is no longer available", + "problem_expression_error_title": "Invalid filter expression", + "problem_internal_server_error_title": "Something went wrong on our end", + "problem_login_invalid_credentials_title": "Invalid username or password", + "problem_login_invalid_domain_title": "Logging in from this address is not allowed", + "problem_o_auth_connection_already_exists_title": "Your account is already connected to this provider", + "problem_o_auth_connection_already_linked_title": "This external account is already linked to another user", + "problem_o_auth_flow_anonymous_only_title": "You are already signed in", + "problem_o_auth_flow_mismatch_title": "Sign-in attempt does not match", + "problem_o_auth_flow_mismatch_desc": "Please start over.", + "problem_o_auth_flow_missing_data_title": "The provider did not return your account details", + "problem_o_auth_flow_missing_data_desc": "Please try again.", + "problem_o_auth_flow_not_found_title": "Sign-in attempt expired", + "problem_o_auth_flow_not_found_desc": "Please start over.", + "problem_o_auth_flow_unsupported_title": "Unsupported sign-in flow", + "problem_o_auth_internal_error_title": "Something went wrong during sign-in", + "problem_o_auth_internal_error_desc": "Please try again in a moment.", + "problem_o_auth_link_authenticated_user_only_title": "You must be signed in to link an external account", + "problem_o_auth_provider_mismatch_title": "Sign-in attempt does not match the provider", + "problem_o_auth_provider_mismatch_desc": "Please start over.", + "problem_o_auth_provider_unsupported_title": "This sign-in provider is not supported", + "problem_pair_code_not_found_title": "Pair code not found", + "problem_password_reset_not_found_title": "Password reset link is invalid", + "problem_password_reset_not_found_desc": "The link may have expired or already been used.", + "problem_session_not_found_title": "Session not found", + "problem_share_get_no_shares_title": "You have no shares with this user", + "problem_share_request_create_cannot_share_with_self_title": "You cannot share with yourself", + "problem_share_request_create_shocker_not_found_title": "One or more shockers were not found", + "problem_share_request_create_shocker_not_found_desc": "They may have been removed or do not belong to you.", + "problem_share_request_not_found_title": "Share invite not found", + "problem_share_user_not_found_title": "Share not found", + "problem_share_code_already_linked_title": "Shocker is already linked to your account", + "problem_share_code_cant_link_own_share_code_title": "You cannot redeem your own share code", + "problem_share_code_not_found_title": "Share code not found", + "problem_share_link_expiry_date_in_past_title": "Expiry date cannot be in the past", + "problem_share_link_not_found_title": "Public share not found", + "problem_share_link_shocker_already_in_share_link_title": "Shocker is already in this public share", + "problem_share_link_shocker_not_in_share_link_title": "Shocker is not in this public share", + "problem_shocker_control_no_permission_title": "You do not have permission to control this shocker", + "problem_shocker_control_not_found_title": "Shocker not found", + "problem_shocker_control_paused_title": "Shocker is paused", + "problem_shocker_not_found_title": "Shocker not found", + "problem_signup_registration_disabled_title": "Registration is currently disabled", + "problem_signup_username_or_email_exists_title": "That username or email is already in use", + "problem_turnstile_invalid_title": "Verification failed", + "problem_turnstile_invalid_desc": "Please complete the challenge again and retry.", + "problem_user_not_found_title": "User not found", + "problem_user_privileged_delete_denied_title": "Privileged users cannot be deleted", + "problem_validation_error_title": "Some fields are invalid", + "problem_webhook_not_found_title": "Webhook not found", + "problem_webhook_unsupported_title": "Only Discord webhooks are supported", + "problem_webhook_unsupported_desc": "Use a discord.com URL, not canary or ptb.", + "error_too_many_requests": "Too many requests", + "error_retry_after_one": "Try again in {{count}} second.", + "error_retry_after_other": "Try again in {{count}} seconds.", + "error_unexpected_response": "Unexpected server response", + "error_internal": "Internal error occurred", + "error_network": "Network error occurred", + "dev_banner": "This is the OpenShock DEVELOPMENT environment. No data is saved, and it is regularly overwritten by production data.", + "firmware_channel_bugs_warning": "This channel might contain bugs." +} From 46ac183017d2f30cb9af578601a845bb3f3e3d02 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Luc=20=E2=99=A5?= Date: Thu, 12 Nov 2026 17:43:33 +0100 Subject: [PATCH 23/27] New translations en.json (Swedish) [ci skip] --- messages/sv.json | 302 ++++++++++++++++++----------------------------- 1 file changed, 117 insertions(+), 185 deletions(-) diff --git a/messages/sv.json b/messages/sv.json index 172b6ed8..65e9bea1 100644 --- a/messages/sv.json +++ b/messages/sv.json @@ -1,15 +1,13 @@ { - "$schema": "https://inlang.com/schema/inlang-message-format", - "landing_tagline": "Plattformen för säker och pålitlig fjärrstyrning av shockers med riktigt låg fördröjning.", "landing_section_label": "Hem", "landing_hubs_online": "Hubbar online just nu: ", "landing_learn_more": "Läs mer", "landing_wiki": "Wiki", "landing_meta_description": "Välkommen till OpenShock, ett fritt ekosystem med öppen källkod för att styra olika shockers över internet.", - "instance_meta_description": "Välkommen till {siteName}, en oberoende instans av OpenShock, ett fritt ekosystem med öppen källkod för att styra olika shockers över internet.", + "instance_meta_description": "Välkommen till {{siteName}}, en oberoende instans av OpenShock, ett fritt ekosystem med öppen källkod för att styra olika shockers över internet.", "header_sidebar_toggle": "Visa/dölj sidopanelen", - "header_avatar_alt": "{name}s avatar", + "header_avatar_alt": "{{name}}s avatar", "header_menu_profile": "Profil", "header_menu_settings": "Inställningar", "header_menu_logout": "Logga ut", @@ -17,16 +15,14 @@ "header_signup": "Registrera dig", "header_github_title": "OpenShock på GitHub", "header_discord_title": "Communityns Discord", - - "footer_made_with": "Gjort med {#heart/} av {#team}OpenShock-teamet{/team}", + "footer_made_with": "Gjort med av OpenShock-teamet", "footer_connection_status_label": "Anslutningsstatus till servern", "footer_signalr_state": "SignalR-status", "footer_frontend_version": "Frontend-version", - "footer_frontend_commit_title": "Commit {commit}", + "footer_frontend_commit_title": "Commit {{commit}}", "footer_backend_version": "Backend-version", - "footer_backend_commit_title": "Commit {commit}", + "footer_backend_commit_title": "Commit {{commit}}", "footer_language_label": "Språk", - "sidebar_home_link_label": "OpenShocks startsida", "sidebar_group_general": "Allmänt", "sidebar_home": "Hem", @@ -53,7 +49,6 @@ "sidebar_settings_audit_log": "Aktivitetslogg", "sidebar_settings_connections": "Kopplingar", "sidebar_settings_account": "Kontoinställningar", - "error_meta_title": "Tjänsten är inte tillgänglig", "error_meta_description": "OpenShock är inte tillgängligt just nu", "error_meta_logo_alt": "OpenShocks logotyp", @@ -62,10 +57,8 @@ "error_not_found_description": "Sidan du letar efter finns inte.", "error_unexpected_description": "Ett oväntat fel inträffade.", "error_go_back": "Gå tillbaka", - "auth_layout_logo_alt": "OpenShocks logotyp", "auth_layout_invalid_redirect_removed": "En ogiltig omdirigerings-URL togs bort för din säkerhet.", - "auth_activate_breadcrumb": "Aktivera konto", "auth_activate_title": "Aktivera konto", "auth_activate_activating": "Aktiverar ditt konto...", @@ -74,17 +67,15 @@ "auth_activate_missing_token": "Aktiveringstoken saknas", "auth_activate_continue": "Fortsätt till inloggningen", "auth_activate_toast_success": "Kontot har aktiverats", - "auth_forgot_breadcrumb": "Glömt lösenord", "auth_forgot_title": "Glömt lösenord", "auth_forgot_description": "Ange din e-postadress för att återställa ditt lösenord", "auth_forgot_email_label": "E-post", "auth_forgot_email_placeholder": "E-post", "auth_forgot_submit": "Återställ lösenord", - "auth_forgot_signin_prompt": "Kommer du ihåg ditt lösenord? {#signin}Logga in{/signin}", + "auth_forgot_signin_prompt": "Kommer du ihåg ditt lösenord? Logga in", "auth_forgot_mail_disabled": "Det går inte att återställa lösenord på den här instansen eftersom ingen e-postleverantör är konfigurerad. Kontakta din administratör för att få hjälp att återfå åtkomst till ditt konto.", "auth_forgot_toast_sent": "En begäran om att återställa lösenordet har skickats till den angivna e-postadressen", - "auth_login_breadcrumb": "Logga in", "auth_login_title": "Välkommen tillbaka", "auth_login_loading_methods": "Läser in tillgängliga inloggningsmetoder", @@ -98,23 +89,20 @@ "auth_login_username_label": "Användarnamn eller e-post", "auth_login_password_label": "Lösenord", "auth_login_submit": "Logga in", - "auth_login_signup_prompt": "Har du inget konto? {#signup}Registrera dig{/signup}", - "auth_login_legal": "Genom att klicka på ”Logga in” godkänner du våra {#tos}användarvillkor{/tos} och vår {#privacy}integritetspolicy{/privacy}.", - - "auth_oauth_create_breadcrumb": "Registrera dig med {provider}", - "auth_oauth_create_title": "Registrera dig med {#provider}{provider}{/provider}", + "auth_login_signup_prompt": "Har du inget konto? Registrera dig", + "auth_login_legal": "Genom att klicka på ”Logga in” godkänner du våra användarvillkor och vår integritetspolicy.", + "auth_oauth_create_breadcrumb": "Registrera dig med {{provider}}", + "auth_oauth_create_title": "Registrera dig med {{provider}}", "auth_oauth_create_description": "Fyll i dina kontouppgifter", "auth_oauth_create_username_label": "Användarnamn", "auth_oauth_create_username_placeholder": "Användarnamn", "auth_oauth_create_email_label": "E-post", "auth_oauth_create_email_placeholder": "E-post", "auth_oauth_create_submit": "Registrera dig", - "auth_oauth_create_legal": "Genom att klicka på ”Registrera dig” godkänner du våra {#tos}användarvillkor{/tos} och vår {#privacy}integritetspolicy{/privacy}.", - + "auth_oauth_create_legal": "Genom att klicka på ”Registrera dig” godkänner du våra användarvillkor och vår integritetspolicy.", "auth_oauth_error_breadcrumb": "Autentiseringsfel", "auth_oauth_error_title": "Autentiseringsfel", "auth_oauth_error_back": "Tillbaka till inloggningen", - "auth_reset_breadcrumb": "Återställ lösenord", "auth_reset_title": "Återställ lösenord", "auth_reset_checking": "Kontrollerar återställningslänken...", @@ -127,7 +115,6 @@ "auth_reset_submit": "Återställ lösenord", "auth_reset_request_new": "Begär en ny länk", "auth_reset_toast_success": "Lösenordet har återställts", - "auth_signup_breadcrumb": "Registrera dig", "auth_signup_toast_created_mail": "Kontot har skapats. Kontrollera din e-post för att verifiera kontot.", "auth_signup_toast_created_no_mail": "Kontot har skapats. Du kan logga in nu.", @@ -150,11 +137,10 @@ "auth_signup_confirm_label": "Bekräfta lösenord", "auth_signup_confirm_placeholder": "Bekräfta lösenord", "auth_signup_submit": "Skapa konto", - "auth_signup_signin_prompt": "Har du redan ett konto? {#signin}Logga in{/signin}", + "auth_signup_signin_prompt": "Har du redan ett konto? Logga in", "auth_signup_or": "Eller", "auth_signup_with_email": "Registrera dig med e-post", - "auth_signup_legal": "Genom att klicka på ”Skapa konto” godkänner du våra {#tos}användarvillkor{/tos} och vår {#privacy}integritetspolicy{/privacy}.", - + "auth_signup_legal": "Genom att klicka på ”Skapa konto” godkänner du våra användarvillkor och vår integritetspolicy.", "auth_verify_breadcrumb": "Verifiera e-post", "auth_verify_title": "Verifiera e-post", "auth_verify_verifying": "Verifierar din e-postadress...", @@ -163,7 +149,6 @@ "auth_verify_missing_token": "Verifieringstoken saknas", "auth_verify_continue": "Fortsätt till inloggningen", "auth_verify_toast_success": "E-postadressen har verifierats", - "common_cancel": "Avbryt", "common_delete": "Ta bort", "common_edit": "Redigera", @@ -194,7 +179,7 @@ "control_type_shock": "Stöt", "control_type_vibrate": "Vibrera", "control_type_sound": "Ljud", - "live_tooltip_active": "Live via {gateway} ({country}), {latency} ms", + "live_tooltip_active": "Live via {{gateway}} ({{country}}), {{latency}} ms", "live_tooltip_connecting": "Ansluter...", "live_tooltip_connect": "Anslut till livestyrning", "live_tooltip_hub_start": "Ctrl+klicka för att starta hela hubben", @@ -207,14 +192,14 @@ "shocker_hub": "Hubb", "shocker_select_hub": "Välj hubb", "shocker_rf_id": "RF-ID", - "shocker_rf_id_invalid": "RF-ID måste vara ett heltal mellan {min} och {max}.", + "shocker_rf_id_invalid": "RF-ID måste vara ett heltal mellan {{min}} och {{max}}.", "shocker_model": "Modell", "shocker_select_model": "Välj modell", "shocker_name_placeholder": "Shockerns namn", "shocker_menu_view_logs": "Visa loggar", "shocker_delete_title": "Ta bort shocker", - "shocker_delete_desc": "Vill du verkligen ta bort ”{name}”? Det går inte att ångra.", - "shocker_toast_deleted": "Shockern ”{name}” har tagits bort", + "shocker_delete_desc": "Vill du verkligen ta bort ”{{name}}”? Det går inte att ångra.", + "shocker_toast_deleted": "Shockern ”{{name}}” har tagits bort", "shocker_toast_paused": "Shockern har pausats", "shocker_toast_resumed": "Shockern har återupptagits", "shocker_add_desc": "Registrera en ny shocker på en av dina hubbar.", @@ -239,13 +224,8 @@ "shockers_empty_no_hubs": "Skapa en hubb först och lägg sedan till shockers.", "shockers_empty_has_hubs": "Lägg till en shocker i en av dina hubbar för att komma igång.", "shockers_create_hub": "Skapa en hubb", - "shockers_count": [ - { - "declarations": ["input count", "local countPlural = count: plural"], - "selectors": ["countPlural"], - "match": { "countPlural=one": "{count} shocker", "countPlural=other": "{count} shockers" } - } - ], + "shockers_count_one": "{{count}} shocker", + "shockers_count_other": "{{count}} shockers", "shared_shockers_title": "Delade shockers", "shared_shockers_subtitle": "Shockers som andra användare har delat med dig.", "shared_shockers_empty_title": "Inga shockers har delats med dig än.", @@ -274,18 +254,17 @@ "shocker_edit_is_active": "Shockern är aktiv", "shocker_edit_toast_updated": "Shockern har uppdaterats", "shocker_edit_delete_desc": "Ta bort den här shockern permanent. Det går inte att ångra.", - "common_close": "Stäng", "common_continue": "Fortsätt", "common_loading": "Läser in...", "common_previous": "Föregående", "common_next": "Nästa", "common_steps": "Steg", - "common_step_label": "Steg {number}: {title}", + "common_step_label": "Steg {{number}}: {{title}}", "common_copy": "Kopiera", "common_copied": "Kopierat", "common_never": "Aldrig", - "common_error": "Fel: {message}", + "common_error": "Fel: {{message}}", "terminal_title": "Seriell terminal", "terminal_connecting": "Ansluter...", "terminal_help_button": "Har du problem? Få hjälp", @@ -298,7 +277,7 @@ "terminal_mode_raw_desc": "Bara konsolen. Läs enhetsloggar och skicka kommandon.", "terminal_step_channel": "Välj kanal", "terminal_step_board": "Välj kort", - "terminal_go_to_step": "Gå till steg {number}: {title}", + "terminal_go_to_step": "Gå till steg {{number}}: {{title}}", "terminal_erase": "Radera före flashning", "terminal_erase_desc": "Raderar all data på enheten, inklusive befintliga konfigurationer", "terminal_unsupported": "Din webbläsare stöder inte den här funktionen.", @@ -313,15 +292,15 @@ "terminal_try_driver": "Kontrollera att den seriella drivrutinen är installerad.", "terminal_open_troubleshooter": "Öppna felsökning", "terminal_log_reset_no_device": "Fel på värdsidan vid omstart: ingen enhet!", - "terminal_log_reset_error": "Fel på värdsidan vid omstart: {error}", + "terminal_log_reset_error": "Fel på värdsidan vid omstart: {{error}}", "terminal_log_send_no_device": "Kunde inte skicka: ingen enhet!", - "terminal_log_send_error": "Kunde inte skicka: {error}", - "terminal_log_firmware_disconnected": "Firmware frånkopplad: {error}", - "terminal_log_erase_failed": "Det gick inte att radera flash: {error}", - "terminal_log_hard_reset_failed": "Hårdvaruåterställning misslyckades: {error}", + "terminal_log_send_error": "Kunde inte skicka: {{error}}", + "terminal_log_firmware_disconnected": "Firmware frånkopplad: {{error}}", + "terminal_log_erase_failed": "Det gick inte att radera flash: {{error}}", + "terminal_log_hard_reset_failed": "Hårdvaruåterställning misslyckades: {{error}}", "terminal_log_flash_complete": "Flashningen är klar", - "terminal_log_flash_failed": "Flashningen misslyckades: {error}", - "terminal_log_command_failed": "Det gick inte att skriva kommandot: {error}", + "terminal_log_flash_failed": "Flashningen misslyckades: {{error}}", + "terminal_log_command_failed": "Det gick inte att skriva kommandot: {{error}}", "terminal_help_title": "Felsökning", "terminal_help_desc": "Gå igenom stegen i ordning. Varje steg utesluter en vanlig orsak.", "terminal_help_step_cable": "USB-kabel", @@ -333,23 +312,23 @@ "terminal_help_port_body": "Anslut enheten direkt till en USB-port på datorn. Undvik om möjligt USB-hubbar, dockningsstationer och portar på frontpanelen; de är vanliga orsaker till ström- och signalproblem. Har du en stationär dator kan du prova en port på baksidan.", "terminal_help_driver_download": "Ladda ned CP210x-drivrutinen:", "terminal_help_driver_extract": "Packa upp innehållet i zip-filen till en mapp på datorn.", - "terminal_help_driver_run": "Öppna mappen och kör {#code}{installer}{/code}. Följ anvisningarna för att installera.", + "terminal_help_driver_run": "Öppna mappen och kör {{installer}}. Följ anvisningarna för att installera.", "terminal_help_driver_reconnect": "Anslut enheten igen.", "terminal_help_manual_intro": "Om drivrutinen installerades men enheten fortfarande inte visas:", - "terminal_help_manual_open": "Öppna Enhetshanteraren (tryck på {#key}Win{/key} + {#key}X{/key} och välj {#code}Device Manager{/code}).", - "terminal_help_manual_ports": "Leta under {#code}Ports (COM & LPT){/code} efter en post som:", + "terminal_help_manual_open": "Öppna Enhetshanteraren (tryck på Win + X och välj Device Manager).", + "terminal_help_manual_ports": "Leta under Ports (COM & LPT) efter en post som:", "terminal_help_manual_missing": "Om den saknas upptäcker Windows inte enheten alls; gå igenom stegen om kabel och port igen.", - "terminal_help_manual_update": "Högerklicka på enheten och välj {#code}Update Driver{/code}.", - "terminal_help_manual_browse": "Välj {#code}Browse my computer for drivers{/code} och välj mappen där du packade upp drivrutinens zip-fil. Se till att {#code}Include subfolders{/code} är markerat.", - "terminal_help_manual_success": "Om det lyckas ska posten nu heta {#code}{deviceName}{/code}.", - "terminal_help_discord_intro": "Sitter du fortfarande fast? Gå med i vår Discord-server och fråga i kanalen {#code}{channel}{/code}. Ange:", + "terminal_help_manual_update": "Högerklicka på enheten och välj Update Driver.", + "terminal_help_manual_browse": "Välj Browse my computer for drivers och välj mappen där du packade upp drivrutinens zip-fil. Se till att Include subfolders är markerat.", + "terminal_help_manual_success": "Om det lyckas ska posten nu heta {{deviceName}}.", + "terminal_help_discord_intro": "Sitter du fortfarande fast? Gå med i vår Discord-server och fråga i kanalen {{channel}}. Ange:", "terminal_help_discord_os": "ditt operativsystem och din webbläsare", "terminal_help_discord_device": "enheten du använder (kortmodell, var du fick tag på den)", "terminal_help_discord_tried": "vad du redan har provat av stegen ovan", "terminal_help_discord_errors": "eventuella felmeddelanden eller relevant terminalutdata", "terminal_help_discord_join": "Gå med i vår Discord-server", "terminal_risk_title": "⚠️ INSTABIL FIRMWARE", - "terminal_risk_intro": "Du håller på att flasha {#strong}experimentell firmware{/strong} som är {#strong}känd för att vara instabil{/strong}.", + "terminal_risk_intro": "Du håller på att flasha experimentell firmware som är känd för att vara instabil.", "terminal_risk_brick": "Detta kan göra enheten permanent obrukbar eller kräva manuell återställning.", "terminal_risk_no_support": "Vi ger INTE support för problem som orsakas av den här firmwaren.", "terminal_risk_acknowledge": "Jag förstår att detta är helt mitt eget ansvar", @@ -364,7 +343,7 @@ "terminal_board_search": "Sök kort...", "terminal_board_none": "Inget kort hittades.", "terminal_flash_button": "Flasha", - "terminal_flash_progress": "Förlopp: {status}", + "terminal_flash_progress": "Förlopp: {{status}}", "terminal_flash_idle": "Väntar", "terminal_flash_no_device": "Ingen enhet är vald.", "terminal_flash_resetting": "Återställer...", @@ -375,7 +354,7 @@ "terminal_flash_done": "Enheten har startats om! Flashningen är klar.", "terminal_port_select": "Välj enhet", "terminal_port_disconnect": "Koppla från enheten", - "terminal_port_connected": "Enhet ansluten: {#strong}{id}{/strong}", + "terminal_port_connected": "Enhet ansluten: {{id}}", "terminal_console": "Konsol", "terminal_connected_device": "Ansluten enhet", "terminal_resize": "Ändra storlek på terminalpanelen", @@ -391,7 +370,7 @@ "terminal_colors_menu": "Färger...", "terminal_colors_label": "Konsolfärger", "terminal_colors_close": "Stäng färger", - "terminal_color_input": "Färg för {name}", + "terminal_color_input": "Färg för {{name}}", "terminal_colors_reset": "Återställ till standard", "terminal_color_bg": "Bakgrund", "terminal_color_fg": "Text", @@ -421,13 +400,12 @@ "terminal_toast_clipboard_unreadable": "Det gick inte att läsa urklipp", "terminal_toast_settings_imported": "Konsolinställningarna har importerats", "terminal_toast_settings_invalid": "Urklipp innehåller inga konsolinställningar", - "common_try_again": "Försök igen", - "terminal_cfg_intro": "Värden skickas till enheten via UART. Enhetens svar visas i konsolen nedan. Kommandon utan argument läser värdet; använd {#eye/}-knappen vid varje fält för att läsa det aktuella värdet.", + "terminal_cfg_intro": "Värden skickas till enheten via UART. Enhetens svar visas i konsolen nedan. Kommandon utan argument läser värdet; använd -knappen vid varje fält för att läsa det aktuella värdet.", "terminal_cfg_rf_title": "RF-sändare", "terminal_cfg_rf_desc": "Styr RF-signalen till shockers.", "terminal_cfg_tx_pin": "TX GPIO-stift", - "terminal_cfg_example": "t.ex. {value}", + "terminal_cfg_example": "t.ex. {{value}}", "terminal_cfg_read_value": "Läs aktuellt värde", "terminal_cfg_set": "Ange", "terminal_cfg_read": "Läs", @@ -439,13 +417,13 @@ "terminal_cfg_estop_desc": "Hårdvaruknapp som stoppar alla signaler.", "terminal_cfg_estop_enabled": "Nödstopp aktiverat", "terminal_cfg_estop_pin": "GPIO-stift för nödstopp", - "terminal_cfg_estop_note": "Obs: {#code}{latching}{/code} och {#code}{active}{/code} har inga egna kommandon; ange dem via JSON-konfigurationen nedan.", + "terminal_cfg_estop_note": "Obs: {{latching}} och {{active}} har inga egna kommandon; ange dem via JSON-konfigurationen nedan.", "terminal_cfg_wifi_title": "Wifi", "terminal_cfg_wifi_desc": "Inloggningsuppgifter för nätverk och enhetens värdnamn.", "terminal_cfg_hostname": "Värdnamn", "terminal_cfg_networks": "Nätverk (JSON-array)", "terminal_cfg_invalid_json_array": "Måste vara en giltig JSON-array", - "terminal_cfg_ap_note": "AP-inställningar ({#code}{ssid}{/code}, {#code}{password}{/code}, {#code}{disabled}{/code}, {#code}{staDisabled}{/code}, {#code}{offlineMode}{/code}) har inga egna kommandon; använd JSON-konfigurationen.", + "terminal_cfg_ap_note": "AP-inställningar ({{ssid}}, {{password}}, {{disabled}}, {{staDisabled}}, {{offlineMode}}) har inga egna kommandon; använd JSON-konfigurationen.", "terminal_cfg_backend_title": "Backend", "terminal_cfg_backend_desc": "OpenShock-server och autentisering.", "terminal_cfg_domain": "Domän", @@ -473,12 +451,11 @@ "terminal_cfg_factory_reset_confirm": "Detta raderar all konfiguration på enheten: wifi-nätverk, inloggningsuppgifter för backend, stift och alla andra inställningar. Enheten återställs till standard.", "terminal_cfg_read_failed_json_title": "Kunde inte läsa JSON-konfigurationen", "terminal_cfg_read_failed_raw_title": "Kunde inte läsa råkonfigurationen", - "terminal_cfg_read_failed_desc": "Enheten svarade inte efter {attempts} försök.", + "terminal_cfg_read_failed_desc": "Enheten svarade inte efter {{attempts}} försök.", "terminal_cfg_common_causes": "Vanliga orsaker:", "terminal_cfg_cause_busy": "Enheten är upptagen med ett annat kommando.", "terminal_cfg_cause_disconnected": "Enheten kopplades från eller startades om.", "terminal_cfg_cause_unsupported": "Firmwareversionen stöder inte det här kommandot.", - "common_status": "Status", "common_version": "Version", "common_created": "Skapad", @@ -499,25 +476,25 @@ "hubs_name_placeholder": "Min hubb", "hub_toast_not_connected": "Inte ansluten till servern", "hub_toast_try_later": "Försök igen om en stund.", - "hub_reboot_title": "Starta om {name}?", + "hub_reboot_title": "Starta om {{name}}?", "hub_reboot_desc": "Hubben kopplas från och startar om. Shockers som är parkopplade med den svarar inte förrän den är ansluten igen.", "hub_reboot": "Starta om", - "hub_hotspot_enable_title": "Aktivera wifi-surfzon på {name}?", - "hub_hotspot_disable_title": "Inaktivera wifi-surfzon på {name}?", + "hub_hotspot_enable_title": "Aktivera wifi-surfzon på {{name}}?", + "hub_hotspot_disable_title": "Inaktivera wifi-surfzon på {{name}}?", "hub_hotspot_enable_desc": "Hubben sänder ut ett eget installationsnätverk. Den går fortfarande att nå via ditt wifi, men surfzonen är öppen för alla inom räckhåll tills du stänger av den.", "hub_hotspot_disable_desc": "Installationssurfzonen stängs av. Om hubben inte redan är ansluten till ditt wifi behöver du fysisk åtkomst för att konfigurera den igen.", - "hub_delete_desc": "Du håller på att ta bort hubben {#strong}{name}{/strong}.", + "hub_delete_desc": "Du håller på att ta bort hubben {{name}}.", "hub_delete_shockers": "Detta tar även bort följande shockers:", "hub_edit_title": "Redigera hubb", "hub_edit_apply": "Tillämpa", "hub_pair_title_generate": "Generera parkopplingskod?", "hub_pair_title_generated": "Parkopplingskod genererad", "hub_pair_title_paired": "Hubb parkopplad", - "hub_pair_consumed": "{#strong}{name}{/strong} använde den här parkopplingskoden och är nu parkopplad.", + "hub_pair_consumed": "{{name}} använde den här parkopplingskoden och är nu parkopplad.", "hub_pair_used": "Koden har använts och är inte längre giltig.", - "hub_pair_generated_for": "Parkopplingskod genererad för {#strong}{name}{/strong}.", + "hub_pair_generated_for": "Parkopplingskod genererad för {{name}}.", "hub_copy_now": "Koden nedan går inte att visa senare. Kopiera den nu och uppdatera dina klienter med den.", - "hub_pair_generate_for": "Du håller på att generera en parkopplingskod för {#strong}{name}{/strong}.", + "hub_pair_generate_for": "Du håller på att generera en parkopplingskod för {{name}}.", "hub_pair_valid_for": "Den är giltig i 15 minuter efter att den har skapats.", "hub_pair_one_active": "Det finns bara en aktiv parkopplingskod per hubb; nya koder ersätter den äldre.", "hub_pair_complete": "Parkopplingen är klar", @@ -525,8 +502,8 @@ "hub_pair_copied_close": "Koden är kopierad, stäng", "hub_pair_get": "Hämta parkopplingskod", "hub_token_generated": "Token genererad", - "hub_token_generated_for": "Ny token genererad för {#strong}{name}{/strong}.", - "hub_token_regenerate_for": "Du håller på att generera en ny token för {#strong}{name}{/strong}.", + "hub_token_generated_for": "Ny token genererad för {{name}}.", + "hub_token_regenerate_for": "Du håller på att generera en ny token för {{name}}.", "hub_token_invalidate": "Detta gör den nuvarande token ogiltig och kopplar från klienter som använder den.", "hub_token_confirm": "Är du säker på att du vill göra detta?", "hub_token_label": "Ny token:", @@ -554,12 +531,12 @@ "hub_update_status_error": "Fel", "hub_update_status_timeout": "Tidsgräns", "hub_update_confirm_title": "Bekräfta firmwareuppdatering", - "hub_update_confirm_desc": "Uppdatera {#strong}{name}{/strong} till version {#strong}{version}{/strong}?", + "hub_update_confirm_desc": "Uppdatera {{name}} till version {{version}}?", "hub_update_unstable_warning": "Den här versionen kanske inte kommer från den stabila kanalen och kan innehålla buggar.", - "hub_update_title": "Uppdatera {name}", + "hub_update_title": "Uppdatera {{name}}", "hub_update_subtitle": "Hantera firmwareuppdateringar för den här hubben.", "hub_update_status_title": "Hubbstatus", - "hub_update_firmware": "Firmware: {#mono}{version}{/mono}", + "hub_update_firmware": "Firmware: {{version}}", "hub_update_confirm": "Uppdatera", "hub_update_success": "Uppdateringen är klar", "hub_update_rolled_back": "Enheten återgick till föregående version", @@ -567,9 +544,9 @@ "hub_update_flash_again": "Flasha igen", "hub_update_card_title": "Firmwareuppdatering", "hub_update_card_desc": "Välj en firmwarekanal och version att installera.", - "hub_update_to": "Uppdatera till {version}", + "hub_update_to": "Uppdatera till {{version}}", "hub_update_must_be_online": "Hubben måste vara ansluten för att starta en uppdatering.", - "hub_update_updating_to": "Uppdaterar till {version}...", + "hub_update_updating_to": "Uppdaterar till {{version}}...", "hub_update_total": "Totalt", "hub_update_task": "Uppgift", "hub_update_history": "Uppdateringshistorik", @@ -581,14 +558,14 @@ "hub_update_not_found": "Hubben hittades inte.", "home_breadcrumb": "Hem", "home_welcome": "Välkommen tillbaka", - "home_welcome_name": "Välkommen tillbaka, {name}", + "home_welcome_name": "Välkommen tillbaka, {{name}}", "home_subtitle": "Här är en översikt över din OpenShock-konfiguration.", - "home_hubs_online": "{count} anslutna", + "home_hubs_online": "{{count}} anslutna", "home_hub_status": "Hubbstatus", "home_no_hubs": "Inga hubbar", "home_all_online": "Alla anslutna", "home_all_offline": "Alla frånkopplade", - "home_some_online": "{online}/{total} anslutna", + "home_some_online": "{{online}}/{{total}} anslutna", "home_quick_links": "Snabblänkar", "home_my_shockers": "Mina shockers", "home_my_shockers_desc": "Styr dina shockers", @@ -599,24 +576,15 @@ "home_get_started_desc": "Du har inga hubbar än. Skapa en hubb för att ansluta din första enhet och lägg sedan till shockers.", "home_set_up_hub": "Konfigurera en hubb", "home_first_shocker": "Lägg till din första shocker", - "home_first_shocker_desc": [ - { - "declarations": ["input count", "local countPlural = count: plural"], - "selectors": ["countPlural"], - "match": { - "countPlural=one": "Du har konfigurerat {count} hubb. Lägg till en shocker för att börja styra den.", - "countPlural=other": "Du har konfigurerat {count} hubbar. Lägg till en shocker för att börja styra den." - } - } - ], + "home_first_shocker_desc_one": "Du har konfigurerat {{count}} hubb. Lägg till en shocker för att börja styra den.", + "home_first_shocker_desc_other": "Du har konfigurerat {{count}} hubbar. Lägg till en shocker för att börja styra den.", "home_go_to_shockers": "Gå till shockers", "profile_title": "Profil", "profile_coming_soon": "Profilen kommer snart", "profile_coming_soon_desc": "Din offentliga profil är inte tillgänglig än. Kontouppgifterna finns under Inställningar.", - "common_retry": "Försök igen", "common_never_used": "Aldrig använd", - "common_expires": "Går ut {time}", + "common_expires": "Går ut {{time}}", "common_search_placeholder": "Sök...", "common_unknown": "Okänd", "settings_breadcrumb_account": "Konto", @@ -646,7 +614,7 @@ "account_deactivate": "Inaktivera konto", "account_email_title": "Ändra e-post", "account_email_desc": "Ange din nya e-postadress och bekräfta med ditt nuvarande lösenord.", - "account_email_toast_sent": "Verifieringsmejl skickat till {email}. Klicka på länken i mejlet för att genomföra ändringen.", + "account_email_toast_sent": "Verifieringsmejl skickat till {{email}}. Klicka på länken i mejlet för att genomföra ändringen.", "account_new_email": "Ny e-post", "account_current_password": "Nuvarande lösenord", "account_password_title": "Ändra lösenord", @@ -661,8 +629,8 @@ "tokens_toast_refreshed": "Tokens uppdaterade", "tokens_empty_title": "Inga API-tokens", "tokens_empty_desc": "Generera en token för att autentisera mot OpenShock-API:et.", - "tokens_created_on": "Skapad {date}", - "tokens_last_used": "Senast använd {time}", + "tokens_created_on": "Skapad {{date}}", + "tokens_last_used": "Senast använd {{time}}", "tokens_never_expires": "Går aldrig ut", "tokens_load_failed": "Det gick inte att läsa in API-tokens.", "token_toast_edited": "Token redigerad", @@ -684,7 +652,7 @@ "token_toast_paused": "Token pausad", "token_toast_resumed": "Token återupptagen", "token_delete_title": "Ta bort API-token", - "token_delete_desc": "Är du säker på att du vill ta bort {#strong}{name}{/strong}?", + "token_delete_desc": "Är du säker på att du vill ta bort {{name}}?", "token_delete_permanent": "Detta går inte att ångra. Token tas bort permanent.", "token_toast_deleted": "Token borttagen", "token_resume": "Återuppta token", @@ -697,11 +665,11 @@ "token_new_breadcrumb": "Ny", "token_redirect_not_allowed": "Angiven redirect_uri är inte tillåten. Endast loopback-adresser eller egna applikationsscheman tillåts.", "token_params_missing": "Obligatoriska GET-parametrar saknas. Se till att name, redirect_uri och permissions anges.", - "token_invalid_permissions": "Ogiltiga behörigheter angavs: {list}", + "token_invalid_permissions": "Ogiltiga behörigheter angavs: {{list}}", "token_toast_created": "Token skapad", "token_request_title": "Begäran om API-token", "token_access_granted": "Åtkomst beviljad", - "token_shared_redirecting": "Token har skapats och delats med applikationen. Du skickas tillbaka till {#b}{uri}{/b}.", + "token_shared_redirecting": "Token har skapats och delats med applikationen. Du skickas tillbaka till {{uri}}.", "token_not_redirected": "Om du inte skickas vidare automatiskt kan du använda knappen nedan.", "token_finish": "Slutför", "token_generated_title": "API-token genererad", @@ -709,7 +677,7 @@ "token_new_title": "Ny API-token", "token_external_desc": "En extern applikation begär åtkomst till ditt konto. Granska och justera behörigheterna nedan innan du tillåter åtkomst.", "token_new_desc": "Konfigurera och generera en ny API-token för ditt konto.", - "token_external_requesting": "{#b}{name}{/b} begär en API-token. Din token delas med applikationen på {#b}{uri}{/b}.", + "token_external_requesting": "{{name}} begär en API-token. Din token delas med applikationen på {{uri}}.", "token_allow": "Tillåt", "token_generate": "Generera", "token_deny": "Neka", @@ -719,13 +687,13 @@ "sessions_load_failed": "Det gick inte att läsa in sessioner.", "sessions_empty_title": "Inga aktiva sessioner", "sessions_empty_desc": "Sessioner visas här när du loggar in från en webbläsare eller app.", - "sessions_last_seen": "Senast sedd {time}", - "sessions_signed_in": "Inloggad {time}", + "sessions_last_seen": "Senast sedd {{time}}", + "sessions_signed_in": "Inloggad {{time}}", "session_toast_revoked": "Sessionen har återkallats", "session_revoke_title": "Återkalla session", "session_revoke": "Återkalla", "session_revoke_desc": "Är du säker på att du vill återkalla den här sessionen?", - "session_revoke_from": "Session inloggad från {#strong}{ip}{/strong} med {#strong}{agent}{/strong}", + "session_revoke_from": "Session inloggad från {{ip}} med {{agent}}", "connections_title": "OAuth-anslutningar", "connections_subtitle": "Länka eller ta bort länkar till tredjepartskonton för att logga in snabbare och hålla din profil synkad.", "connections_toast_linked": "Kontot har länkats.", @@ -738,11 +706,11 @@ "connections_empty_desc": "Välj ”Länka ny leverantör” ovan för att ansluta tillgängliga leverantörer.", "connections_unlink": "Ta bort länk", "connections_load_failed": "Det gick inte att läsa in OAuth-anslutningar.", - "connections_unlink_title": "Ta bort länken till {name}?", + "connections_unlink_title": "Ta bort länken till {{name}}?", "connections_unlink_title_generic": "Ta bort länken till det här kontot?", "connections_unlink_desc": "Du kan inte längre logga in med den här leverantören om du inte länkar den igen.", - "provider_starting": "Startar {name}...", - "provider_link": "Länka {name}", + "provider_starting": "Startar {{name}}...", + "provider_link": "Länka {{name}}", "audit_subtitle": "Säkerhetsrelevant aktivitet på ditt konto. Granska allt du inte känner igen.", "audit_col_time": "Tid", "audit_col_action": "Åtgärd", @@ -768,22 +736,13 @@ "audit_action_automation_token_rotated": "Automatiseringstoken roterad", "audit_action_automation_token_deleted": "Automatiseringstoken borttagen", "audit_action_automation_token_used": "Automatiseringstoken använd", - "audit_meta_session": "Session {id}", - "audit_meta_changed": "{old} till {new}", - "audit_meta_email_requested": "Begärde ändring till {email}", - "audit_meta_accounts_removed": [ - { - "declarations": ["input count", "local countPlural = count: plural"], - "selectors": ["countPlural"], - "match": { - "countPlural=one": "{name} ({count} konto borttaget)", - "countPlural=other": "{name} ({count} konton borttagna)" - } - } - ], + "audit_meta_session": "Session {{id}}", + "audit_meta_changed": "{{old}} till {{new}}", + "audit_meta_email_requested": "Begärde ändring till {{email}}", + "audit_meta_accounts_removed_one": "{{name}} ({{count}} konto borttaget)", + "audit_meta_accounts_removed_other": "{{name}} ({{count}} konton borttagna)", "audit_meta_scheduled_deletion": "Schemalagd för borttagning", "audit_meta_kept": "Sparat för återaktivering", - "common_view": "Visa", "common_save": "Spara", "common_saving": "Sparar...", @@ -808,20 +767,12 @@ "public_share_create_title": "Skapa offentlig delning", "public_share_toast_deleted": "Offentlig delning borttagen", "public_share_delete_title": "Ta bort offentlig delning", - "public_share_delete_desc": "Är du säker på att du vill ta bort den offentliga delningen {#strong}{name}{/strong}?", - "public_share_edit_title": "Offentlig delning: {name}", + "public_share_delete_desc": "Är du säker på att du vill ta bort den offentliga delningen {{name}}?", + "public_share_edit_title": "Offentlig delning: {{name}}", "public_share_edit_subtitle": "Redigering: ändringarna gäller när du sparar.", "public_share_add_shocker": "Lägg till shocker", - "public_share_toast_added": [ - { - "declarations": ["input count", "local countPlural = count: plural"], - "selectors": ["countPlural"], - "match": { - "countPlural=one": "Lade till {count} shocker i delningen", - "countPlural=other": "Lade till {count} shockers i delningen" - } - } - ], + "public_share_toast_added_one": "Lade till {{count}} shocker i delningen", + "public_share_toast_added_other": "Lade till {{count}} shockers i delningen", "public_share_empty_shockers_title": "Inga shockers i den här delningen", "public_share_empty_shockers_desc": "Lägg till en shocker så kan alla med länken styra den.", "public_share_load_failed": "Fel vid hämtning av delningsdetaljer", @@ -851,15 +802,14 @@ "perm_live_on": "Live aktiverat", "perm_live_off": "Live inaktiverat", "perm_live_control": "Livestyrning", - "user_selector_avatar_of": "{name}s profilbild", + "user_selector_avatar_of": "{{name}}s profilbild", "user_selector_placeholder": "Ange användarnamn", "user_selector_aria": "Användarnamn att söka efter", "user_selector_search": "Sök användare", "user_selector_found": "Användare hittad", - "common_remove": "Ta bort", "user_shares_subtitle": "Direkta, permanenta delningar med andra användare.", - "user_shares_toast_invited": "Skickade en shocker-inbjudan till {name}", + "user_shares_toast_invited": "Skickade en shocker-inbjudan till {{name}}", "user_shares_redeem": "Lös in kod", "user_shares_new": "Ny delning", "user_shares_tab_shares": "Delningar", @@ -882,12 +832,12 @@ "share_code_redeem": "Lös in", "incoming_shares_empty_title": "Inget delat med dig", "incoming_shares_empty_desc": "Ingen har delat en shocker med dig än.", - "incoming_share_toast_removed": "Tog bort delningen från {name}", + "incoming_share_toast_removed": "Tog bort delningen från {{name}}", "incoming_share_remove_title": "Ta bort delning", - "incoming_share_remove_desc": "Är du säker på att du vill ta bort delningen från {#strong}{name}{/strong}?", - "incoming_share_toast_removed_shocker": "Tog bort {shocker} som delats av {name}", + "incoming_share_remove_desc": "Är du säker på att du vill ta bort delningen från {{name}}?", + "incoming_share_toast_removed_shocker": "Tog bort {{shocker}} som delats av {{name}}", "incoming_share_remove_shocker_title": "Ta bort den här delade shockern?", - "incoming_share_remove_shocker_desc": "Är du säker på att du vill ta bort den delade shockern {#strong}{shocker}{/strong} från {#strong}{name}{/strong}?", + "incoming_share_remove_shocker_desc": "Är du säker på att du vill ta bort den delade shockern {{shocker}} från {{name}}?", "incoming_share_manage_from": "Hantera delningar från", "share_remove": "Ta bort delning", "invites_empty_title": "Inga inbjudningar än", @@ -898,23 +848,23 @@ "invites_incoming": "Inkommande", "invites_incoming_empty_title": "Inga inkommande inbjudningar", "invites_incoming_empty_desc": "Du har inga inkommande inbjudningar.", - "invite_toast_accepted": "Accepterade inbjudan från {name}", - "invite_toast_declined": "Avböjde inbjudan från {name}", + "invite_toast_accepted": "Accepterade inbjudan från {{name}}", + "invite_toast_declined": "Avböjde inbjudan från {{name}}", "invite_deny_title": "Avböj inbjudan", "invite_deny_label": "Avböj inbjudan", "invite_deny": "Avböj", - "invite_deny_desc": "Är du säker på att du vill avböja inbjudan från {#strong}{name}{/strong}?", + "invite_deny_desc": "Är du säker på att du vill avböja inbjudan från {{name}}?", "invite_accept": "Acceptera inbjudan", - "invite_toast_cancelled_for": "Drog tillbaka inbjudan till {name} ({id})", - "invite_toast_cancelled": "Drog tillbaka inbjudan {id}", + "invite_toast_cancelled_for": "Drog tillbaka inbjudan till {{name}} ({{id}})", + "invite_toast_cancelled": "Drog tillbaka inbjudan {{id}}", "invite_cancel_title": "Dra tillbaka inbjudan", "invite_cancel": "Dra tillbaka", - "invite_cancel_for_desc": "Är du säker på att du vill dra tillbaka inbjudan till {#strong}{name}{/strong}?", - "invite_cancel_code_desc": "Är du säker på att du vill dra tillbaka inbjudan med koden {#strong}{code}{/strong}?", + "invite_cancel_for_desc": "Är du säker på att du vill dra tillbaka inbjudan till {{name}}?", + "invite_cancel_code_desc": "Är du säker på att du vill dra tillbaka inbjudan med koden {{code}}?", "invite_cancel_outstanding": "Dra tillbaka väntande inbjudan", "outgoing_shares_empty_title": "Inga delade shockers", "outgoing_shares_empty_desc": "Du har inte delat några shockers med andra användare än.", - "outgoing_share_toast_removed": "Tog bort den delade shockern {name}", + "outgoing_share_toast_removed": "Tog bort den delade shockern {{name}}", "outgoing_share_remove_title": "Sluta dela den här shockern?", "outgoing_share_editing_for": "Redigerar delningar för", "outgoing_share_limits": "Gränser och behörigheter", @@ -922,11 +872,9 @@ "outgoing_share_per_desc": "Justera begränsningar per shocker", "outgoing_share_all": "Alla", "outgoing_share_per": "Per shocker", - - "outgoing_share_remove_desc": "Är du säker på att du vill sluta dela {#strong}{shocker}{/strong} med {#strong}{name}{/strong}?", - + "outgoing_share_remove_desc": "Är du säker på att du vill sluta dela {{shocker}} med {{name}}?", "report_breadcrumb": "Rapportera API-tokens", - "report_toast_clipboard_failed": "Det gick inte att läsa urklipp: {error}", + "report_toast_clipboard_failed": "Det gick inte att läsa urklipp: {{error}}", "report_title": "Rapportera läckta API-tokens", "report_paste": "Klistra in från urklipp", "report_warning": "Det här formuläret är bara till för att rapportera API-tokens som läckt av misstag.", @@ -944,16 +892,11 @@ "expiration_label": "Utgång", "expiration_never": "Aldrig", "expiration_custom": "Anpassad", - "expiration_days": [ - { - "declarations": ["input count", "local countPlural = count: plural"], - "selectors": ["countPlural"], - "match": { "countPlural=one": "{count} dag", "countPlural=other": "{count} dagar" } - } - ], + "expiration_days_one": "{{count}} dag", + "expiration_days_other": "{{count}} dagar", "expiration_required": "Utgångsdatum krävs", "expiration_never_desc": "Går aldrig ut", - "expiration_expires_at": "Går ut {time} ({date})", + "expiration_expires_at": "Går ut {{time}} ({{date}})", "date_picker_placeholder": "Välj ett datum", "telemetry_toast_title": "Vill du hjälpa till att förbättra OpenShock?", "telemetry_toast_desc": "Skicka diagnostik så att vi kan åtgärda krascher och långsamma API-anrop. Rapporterna innehåller felmeddelandet, stackspårningen och din IP-adress. Du kan ändra detta när som helst i kontoinställningarna.", @@ -963,28 +906,27 @@ "table_show_details": "Visa detaljer", "table_hide_details": "Dölj detaljer", "table_no_results": "Inga resultat.", - "table_sort_asc": "Sortera efter {name}, stigande", - "table_sort_desc": "Sortera efter {name}, fallande", - "table_sort_none": "Sortera efter {name}, osorterad", + "table_sort_asc": "Sortera efter {{name}}, stigande", + "table_sort_desc": "Sortera efter {{name}}, fallande", + "table_sort_none": "Sortera efter {{name}}, osorterad", "cell_na": "Ej tillämpligt", "cell_not_applicable": "Inte tillämpligt", "cell_invalid": "Ogiltig", "cell_unavailable": "Inte tillgänglig", "cell_none": "Ingen", - "oauth_login_with": "Logga in med {provider}", - "oauth_signup_with": "Registrera dig med {provider}", + "oauth_login_with": "Logga in med {{provider}}", + "oauth_signup_with": "Registrera dig med {{provider}}", "signalr_connect_failed": "Det gick inte att ansluta till servern!", "signalr_disconnect_failed": "Ett fel uppstod när anslutningen till servern bröts!", "signalr_invalid_update": "Tog emot en ogiltig uppdatering från servern!", "signalr_invalid_log": "Tog emot ogiltiga loggdata från servern!", "signalr_invalid_ota": "Tog emot ogiltiga data om firmwareuppdatering från servern!", - "ota_toast_failed": "Hubbens firmwareuppdatering misslyckades: {message}", + "ota_toast_failed": "Hubbens firmwareuppdatering misslyckades: {{message}}", "ota_toast_succeeded": "Hubbens firmwareuppdatering är klar!", "ota_toast_rolled_back": "Hubbens firmware återgick till föregående version", "lcg_connect_failed": "Det gick inte att ansluta till live-kontrollgatewayen", - "terminal_toast_bootloader_failed": "Det gick inte att gå in i startladdaren: {error}", - "terminal_toast_app_mode_failed": "Det gick inte att gå in i applikationsläge: {error}", - + "terminal_toast_bootloader_failed": "Det gick inte att gå in i startladdaren: {{error}}", + "terminal_toast_app_mode_failed": "Det gick inte att gå in i applikationsläge: {{error}}", "problem_account_account_not_activated_title": "Kontot är inte aktiverat", "problem_account_account_not_activated_desc": "Leta efter aktiveringsmejlet i din inkorg.", "problem_account_activation_not_found_title": "Aktiveringslänken är ogiltig", @@ -1102,22 +1044,12 @@ "problem_webhook_not_found_title": "Webhooken hittades inte", "problem_webhook_unsupported_title": "Endast Discord-webhooks stöds", "problem_webhook_unsupported_desc": "Använd en discord.com-URL, inte canary eller ptb.", - "error_too_many_requests": "För många förfrågningar", - "error_retry_after": [ - { - "declarations": ["input seconds", "local secondsPlural = seconds: plural"], - "selectors": ["secondsPlural"], - "match": { - "secondsPlural=one": "Försök igen om {seconds} sekund.", - "secondsPlural=other": "Försök igen om {seconds} sekunder." - } - } - ], + "error_retry_after_one": "Försök igen om {{count}} sekund.", + "error_retry_after_other": "Försök igen om {{count}} sekunder.", "error_unexpected_response": "Oväntat svar från servern", "error_internal": "Ett internt fel uppstod", "error_network": "Ett nätverksfel uppstod", - - "dev_banner": "Det här är OpenShocks {#b}UTVECKLINGSMILJÖ{/b}. {#u}Ingen data sparas{/u}, och den skrivs regelbundet över med produktionsdata.", + "dev_banner": "Det här är OpenShocks UTVECKLINGSMILJÖ. Ingen data sparas, och den skrivs regelbundet över med produktionsdata.", "firmware_channel_bugs_warning": "Den här kanalen kan innehålla buggar." } From 0a3d3e153308f05b6e9d2a836e9fdd1dafe69da3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Luc=20=E2=99=A5?= Date: Thu, 12 Nov 2026 17:43:35 +0100 Subject: [PATCH 24/27] New translations en.json (Turkish) [ci skip] --- messages/tr.json | 1055 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 1055 insertions(+) create mode 100644 messages/tr.json diff --git a/messages/tr.json b/messages/tr.json new file mode 100644 index 00000000..ef4df56c --- /dev/null +++ b/messages/tr.json @@ -0,0 +1,1055 @@ +{ + "landing_tagline": "The go-to platform for safe, reliable, real low-latency remote shocking.", + "landing_section_label": "Home", + "landing_hubs_online": "Hubs online right now: ", + "landing_learn_more": "Learn More", + "landing_wiki": "Wiki", + "landing_meta_description": "Welcome to OpenShock, a free and open-source ecosystem to control various shock collars over the internet.", + "instance_meta_description": "Welcome to {{siteName}}, an independent instance of OpenShock, a free and open-source ecosystem to control various shock collars over the internet.", + "header_sidebar_toggle": "Toggle Sidebar", + "header_avatar_alt": "{{name}}'s avatar", + "header_menu_profile": "Profile", + "header_menu_settings": "Settings", + "header_menu_logout": "Logout", + "header_login": "Login", + "header_signup": "Sign Up", + "header_github_title": "OpenShock on GitHub", + "header_discord_title": "Community Discord", + "footer_made_with": "Made with by the OpenShock Team", + "footer_connection_status_label": "Server connection status", + "footer_signalr_state": "SignalR State", + "footer_frontend_version": "Frontend Version", + "footer_frontend_commit_title": "Commit {{commit}}", + "footer_backend_version": "Backend Version", + "footer_backend_commit_title": "Commit {{commit}}", + "footer_language_label": "Language", + "sidebar_home_link_label": "OpenShock home", + "sidebar_group_general": "General", + "sidebar_home": "Home", + "sidebar_shockers": "Shockers", + "sidebar_shared_shockers": "Shared Shockers", + "sidebar_hubs": "Hubs", + "sidebar_user_shares": "User Shares", + "sidebar_public_shares": "Public Shares", + "sidebar_serial_terminal": "Serial Terminal", + "sidebar_group_admin": "Admin", + "sidebar_admin_monitoring": "Monitoring", + "sidebar_admin_online_hubs": "Online Hubs", + "sidebar_admin_online_gateways": "Online Gateways", + "sidebar_admin_management": "Management", + "sidebar_admin_users": "Users", + "sidebar_admin_blacklists": "Blacklists", + "sidebar_admin_webhooks": "Webhooks", + "sidebar_admin_mail": "Mail", + "sidebar_admin_automation_tokens": "Automation Tokens", + "sidebar_admin_configuration": "Configuration", + "sidebar_group_settings": "Settings", + "sidebar_settings_api_tokens": "API Tokens", + "sidebar_settings_sessions": "Sessions", + "sidebar_settings_audit_log": "Audit Log", + "sidebar_settings_connections": "Connections", + "sidebar_settings_account": "Account Settings", + "error_meta_title": "Service Unavailable", + "error_meta_description": "OpenShock is currently unavailable", + "error_meta_logo_alt": "OpenShock Logo", + "error_fallback_message": "Something went wrong.", + "error_not_found_message": "Page not found", + "error_not_found_description": "The page you're looking for doesn't exist.", + "error_unexpected_description": "An unexpected error occurred.", + "error_go_back": "Go back", + "auth_layout_logo_alt": "OpenShock Logo", + "auth_layout_invalid_redirect_removed": "An invalid redirect URL was removed for your safety.", + "auth_activate_breadcrumb": "Activate Account", + "auth_activate_title": "Activate Account", + "auth_activate_activating": "Activating your account...", + "auth_activate_success": "Your account has been activated", + "auth_activate_failed": "This activation link is invalid or has expired", + "auth_activate_missing_token": "Missing activation token", + "auth_activate_continue": "Continue to login", + "auth_activate_toast_success": "Account activated", + "auth_forgot_breadcrumb": "Forgot Password", + "auth_forgot_title": "Forgot Password", + "auth_forgot_description": "Enter your email to reset your password", + "auth_forgot_email_label": "Email", + "auth_forgot_email_placeholder": "Email", + "auth_forgot_submit": "Reset Password", + "auth_forgot_signin_prompt": "Remember your password? Sign in", + "auth_forgot_mail_disabled": "Password resets are unavailable on this instance because it has no mail provider configured. Please contact your administrator for help recovering your account.", + "auth_forgot_toast_sent": "Reset password request has been sent to the given email", + "auth_login_breadcrumb": "Login", + "auth_login_title": "Welcome back", + "auth_login_loading_methods": "Loading available login methods", + "auth_login_choose_method": "Login with one of these methods", + "auth_login_with_account": "Login with your OpenShock Account", + "auth_login_activation_after_signup": "Your account has been created. We've sent an activation link to your email address. Check your inbox and spam folder.", + "auth_login_activation_pending": "Your account isn't activated yet. We've sent an activation link to your email address. Check your inbox and spam folder. If nothing arrives, try logging in again later to get a new link.", + "auth_login_oauth_only": "This account has no password. Sign in with the provider you signed up with.", + "auth_login_oauth_only_with_buttons": "This account has no password. Sign in with the provider you signed up with using the buttons above.", + "auth_login_or_continue_with": "Or continue with", + "auth_login_username_label": "Username or Email", + "auth_login_password_label": "Password", + "auth_login_submit": "Login", + "auth_login_signup_prompt": "Don't have an account? Sign up", + "auth_login_legal": "By clicking Login, you agree to our Terms of Service and Privacy Policy.", + "auth_oauth_create_breadcrumb": "Sign Up With {{provider}}", + "auth_oauth_create_title": "Sign Up With {{provider}}", + "auth_oauth_create_description": "Complete your account details", + "auth_oauth_create_username_label": "Username", + "auth_oauth_create_username_placeholder": "Username", + "auth_oauth_create_email_label": "Email", + "auth_oauth_create_email_placeholder": "Email", + "auth_oauth_create_submit": "Sign Up", + "auth_oauth_create_legal": "By clicking Sign Up, you agree to our Terms of Service and Privacy Policy.", + "auth_oauth_error_breadcrumb": "Authentication Error", + "auth_oauth_error_title": "Authentication Error", + "auth_oauth_error_back": "Back to login", + "auth_reset_breadcrumb": "Reset Password", + "auth_reset_title": "Reset Password", + "auth_reset_checking": "Verifying reset link...", + "auth_reset_choose_password": "Choose a new password for your account", + "auth_reset_invalid": "This reset link is invalid or has expired", + "auth_reset_password_label": "New Password", + "auth_reset_password_placeholder": "New Password", + "auth_reset_confirm_label": "Confirm New Password", + "auth_reset_confirm_placeholder": "Confirm New Password", + "auth_reset_submit": "Reset Password", + "auth_reset_request_new": "Request a new reset link", + "auth_reset_toast_success": "Password has been reset", + "auth_signup_breadcrumb": "Sign Up", + "auth_signup_toast_created_mail": "Account created successfully. Please check your email to verify your account.", + "auth_signup_toast_created_no_mail": "Account created successfully. You can log in now.", + "auth_signup_dialog_title": "Welcome! Thank you for signing up! ❤️", + "auth_signup_dialog_created_mail": "Your account has been created. 🎉 Please check your email to verify your account.", + "auth_signup_dialog_verify_then_login": "After verifying your email, you can log in to your account.", + "auth_signup_dialog_created_no_mail": "Your account has been created and is ready to use. 🎉", + "auth_signup_dialog_login_now": "You can log in to your account now.", + "auth_signup_title": "Create your account", + "auth_signup_loading_methods": "Loading available sign-up methods", + "auth_signup_using_email": "Signing up using email", + "auth_signup_choose_method": "Choose your preferred sign-up method", + "auth_signup_back": "Back", + "auth_signup_username_label": "Username", + "auth_signup_username_placeholder": "John OpenShock", + "auth_signup_email_label": "Email", + "auth_signup_email_placeholder": "john@example.com", + "auth_signup_password_label": "Password", + "auth_signup_password_placeholder": "Password", + "auth_signup_confirm_label": "Confirm Password", + "auth_signup_confirm_placeholder": "Confirm Password", + "auth_signup_submit": "Create Account", + "auth_signup_signin_prompt": "Already have an account? Sign in", + "auth_signup_or": "Or", + "auth_signup_with_email": "Signup with Email", + "auth_signup_legal": "By clicking Create Account, you agree to our Terms of Service and Privacy Policy.", + "auth_verify_breadcrumb": "Verify Email", + "auth_verify_title": "Verify Email", + "auth_verify_verifying": "Verifying your email address...", + "auth_verify_success": "Your email has been verified", + "auth_verify_failed": "This verification link is invalid or has expired", + "auth_verify_missing_token": "Missing verification token", + "auth_verify_continue": "Continue to login", + "auth_verify_toast_success": "Email verified", + "common_cancel": "Cancel", + "common_delete": "Delete", + "common_edit": "Edit", + "common_share": "Share", + "common_copy_id": "Copy ID", + "common_id_copied": "ID copied to clipboard", + "common_open_menu": "Open menu", + "common_refresh": "Refresh", + "common_settings": "Settings", + "common_clear": "Clear", + "common_online": "Online", + "common_offline": "Offline", + "common_paused": "Paused", + "common_resume": "Resume", + "common_resuming": "Resuming...", + "common_coming_soon": "(Coming soon)", + "common_save_changes": "Save Changes", + "common_danger_zone": "Danger Zone", + "common_name": "Name", + "control_intensity": "Intensity", + "control_duration": "Duration", + "control_max_intensity": "Max Intensity", + "control_max_duration": "Max Duration", + "control_vibration": "Vibration", + "control_value": "Value", + "control_live_intensity": "Live intensity", + "control_type_stop": "Stop", + "control_type_shock": "Shock", + "control_type_vibrate": "Vibrate", + "control_type_sound": "Sound", + "live_tooltip_active": "Live via {{gateway}} ({{country}}), {{latency}}ms", + "live_tooltip_connecting": "Connecting...", + "live_tooltip_connect": "Connect to Live Control", + "live_tooltip_hub_start": "Ctrl+click to start the whole hub", + "live_tooltip_hub_stop": "Ctrl+click to stop the whole hub", + "pause_resume_shocker": "Resume shocker", + "pause_pause_shocker": "Pause shocker", + "pause_resume_all": "Resume all shockers", + "pause_pause_all": "Pause all shockers", + "shocker_label": "Shocker", + "shocker_hub": "Hub", + "shocker_select_hub": "Select hub", + "shocker_rf_id": "RF ID", + "shocker_rf_id_invalid": "RF ID must be a whole number between {{min}} and {{max}}.", + "shocker_model": "Model", + "shocker_select_model": "Select model", + "shocker_name_placeholder": "Shocker name", + "shocker_menu_view_logs": "View Logs", + "shocker_delete_title": "Delete Shocker", + "shocker_delete_desc": "Are you sure you want to delete \"{{name}}\"? This action cannot be undone.", + "shocker_toast_deleted": "Shocker \"{{name}}\" deleted", + "shocker_toast_paused": "Shocker paused", + "shocker_toast_resumed": "Shocker resumed", + "shocker_add_desc": "Register a new shocker to one of your hubs.", + "shocker_add_name_placeholder": "My Shocker", + "shockers_title": "Shockers", + "shockers_subtitle": "Every shocker paired to your hubs.", + "shockers_loading": "Loading shockers...", + "shockers_toast_refreshed": "Shockers refreshed", + "shockers_toast_need_hub": "You need to create a hub before adding shockers.", + "shockers_toast_added": "Shocker added", + "shockers_unknown_module": "Unknown module type", + "shockers_add": "Add Shocker", + "shockers_view_mode": "View mode", + "shockers_mode_classic": "Classic", + "shockers_mode_rich": "Rich", + "shockers_mode_simple": "Simple", + "shockers_mode_map": "Map", + "shockers_group_by_hub": "Group by Hub", + "shockers_global_limits": "Global Limits", + "shockers_logs_label": "Logs", + "shockers_empty_title": "No shockers yet", + "shockers_empty_no_hubs": "Create a hub first, then add shockers to it.", + "shockers_empty_has_hubs": "Add a shocker to one of your hubs to get started.", + "shockers_create_hub": "Create a Hub", + "shockers_count_one": "{{count}} shocker", + "shockers_count_other": "{{count}} shockers", + "shared_shockers_title": "Shared Shockers", + "shared_shockers_subtitle": "Shockers other users have shared with you.", + "shared_shockers_empty_title": "No shockers have been shared with you yet.", + "shared_shockers_empty_desc": "When someone shares their shockers with you, they'll appear here.", + "shocker_logs_title": "Shocker Logs", + "shocker_logs_subtitle": "Every control command sent to your shockers.", + "shocker_logs_live_title": "New logs appear in real time", + "shocker_logs_paused_title": "Live updates pause when sorting or viewing a page other than the first", + "shocker_logs_live": "Live", + "shocker_logs_col_time": "Time", + "shocker_logs_col_type": "Type", + "shocker_logs_col_by": "By", + "shocker_logs_filter_label": "Filter by shocker", + "shocker_logs_filter_placeholder": "Search shockers...", + "shocker_logs_filter_all": "All shockers", + "shocker_logs_filter_none": "No matching shockers", + "shocker_edit_title": "Edit Shocker", + "shocker_edit_subtitle": "Change this shocker's details or remove it.", + "shocker_edit_back": "Back to Shockers", + "shocker_edit_load_failed": "Failed to load shocker.", + "shocker_edit_loading": "Loading shocker...", + "shocker_edit_details_title": "Shocker Details", + "shocker_edit_details_desc": "Update the name, RF ID, and model for this shocker.", + "shocker_edit_pause_state": "Pause State", + "shocker_edit_is_paused": "Shocker is paused", + "shocker_edit_is_active": "Shocker is active", + "shocker_edit_toast_updated": "Shocker updated", + "shocker_edit_delete_desc": "Permanently delete this shocker. This action cannot be undone.", + "common_close": "Close", + "common_continue": "Continue", + "common_loading": "Loading...", + "common_previous": "Previous", + "common_next": "Next", + "common_steps": "Steps", + "common_step_label": "Step {{number}}: {{title}}", + "common_copy": "Copy", + "common_copied": "Copied", + "common_never": "Never", + "common_error": "Error: {{message}}", + "terminal_title": "Serial Terminal", + "terminal_connecting": "Connecting...", + "terminal_help_button": "I'm having trouble, help?", + "terminal_back_to_modes": "Back to mode picker", + "terminal_mode_configure": "Configure Device", + "terminal_mode_configure_desc": "Configure WiFi, authentication, and more. Includes an interactive serial console.", + "terminal_mode_flash": "Flash Firmware", + "terminal_mode_flash_desc": "Install or update firmware on a connected device.", + "terminal_mode_raw": "Serial Monitor", + "terminal_mode_raw_desc": "Just the console. Read device logs and send commands.", + "terminal_step_channel": "Select Channel", + "terminal_step_board": "Select Board", + "terminal_go_to_step": "Go to step {{number}}: {{title}}", + "terminal_erase": "Erase before flashing", + "terminal_erase_desc": "Clears all data on the device including existing configs", + "terminal_unsupported": "Your browser does not support this feature.", + "terminal_update_browser": "Please update your browser to the latest version.", + "terminal_use_browsers": "Please use one of the following browsers:", + "terminal_connect_failed_bootloader": "Could not enter bootloader mode", + "terminal_connect_failed": "Device connection failed", + "terminal_connect_failed_desc": "We couldn't establish a serial connection with the device.", + "terminal_quick_tries": "Quick things to try:", + "terminal_try_replug": "Unplug and replug the device.", + "terminal_try_cable": "Try a different USB cable or port.", + "terminal_try_driver": "Make sure the serial driver is installed.", + "terminal_open_troubleshooter": "Open troubleshooter", + "terminal_log_reset_no_device": "Host-side error during reset: no device!", + "terminal_log_reset_error": "Host-side error during reset: {{error}}", + "terminal_log_send_no_device": "Couldn't send: no device!", + "terminal_log_send_error": "Couldn't send: {{error}}", + "terminal_log_firmware_disconnected": "Firmware disconnected: {{error}}", + "terminal_log_erase_failed": "Failed to erase flash: {{error}}", + "terminal_log_hard_reset_failed": "Failed to hard reset: {{error}}", + "terminal_log_flash_complete": "Flash complete", + "terminal_log_flash_failed": "Failed to flash: {{error}}", + "terminal_log_command_failed": "Failed to write application command: {{error}}", + "terminal_help_title": "Troubleshooter", + "terminal_help_desc": "Work through these steps in order. Each one rules out a common cause.", + "terminal_help_step_cable": "USB cable", + "terminal_help_step_port": "USB port", + "terminal_help_step_driver": "Install driver", + "terminal_help_step_manual": "Manual driver update", + "terminal_help_step_discord": "Ask on Discord", + "terminal_help_cable_body": "Many USB-C and micro-USB cables are charge-only and don't carry data. Swap to a known-good data cable (one you've used to transfer files or connect other devices) and reconnect the hub.", + "terminal_help_port_body": "Plug the device directly into a USB port on your computer. Avoid USB hubs, docking stations, and front-panel ports if possible; these are common sources of power and signal issues. If you're on a desktop, try a port on the back of the machine.", + "terminal_help_driver_download": "Download the CP210x driver:", + "terminal_help_driver_extract": "Extract the contents of the zip file to a folder on your computer.", + "terminal_help_driver_run": "Open the folder and run {{installer}}. Follow the prompts to install.", + "terminal_help_driver_reconnect": "Reconnect the device.", + "terminal_help_manual_intro": "If the driver installer ran but the device still doesn't show up:", + "terminal_help_manual_open": "Open Device Manager (press Win + X and select Device Manager).", + "terminal_help_manual_ports": "Under Ports (COM & LPT), look for an entry like:", + "terminal_help_manual_missing": "If it's missing, the device isn't being detected by Windows at all; revisit the cable and port steps.", + "terminal_help_manual_update": "Right-click the device and pick Update Driver.", + "terminal_help_manual_browse": "Choose Browse my computer for drivers and select the folder you extracted the driver zip into. Make sure Include subfolders is checked.", + "terminal_help_manual_success": "On success, the entry should now read {{deviceName}}.", + "terminal_help_discord_intro": "Still stuck after all of the above? Hop into our Discord server and ask in the {{channel}} channel. Please include:", + "terminal_help_discord_os": "your operating system and browser", + "terminal_help_discord_device": "the device you're using (board model, where you got it)", + "terminal_help_discord_tried": "what you've already tried from the previous steps", + "terminal_help_discord_errors": "any error messages or relevant terminal output", + "terminal_help_discord_join": "Join our Discord server", + "terminal_risk_title": "⚠️ UNSTABLE FIRMWARE", + "terminal_risk_intro": "You are about to flash experimental firmware that is known to be unstable.", + "terminal_risk_brick": "This may permanently brick your device, require manual recovery, or render it unusable.", + "terminal_risk_no_support": "We will NOT provide support for issues caused by this firmware.", + "terminal_risk_acknowledge": "I understand this is entirely my responsibility", + "terminal_risk_abort": "Abort", + "terminal_risk_accept": "I ACCEPT FULL RESPONSIBILITY", + "firmware_channel_recommended": "This is the recommended channel.", + "firmware_channel_danger": "DO NOT USE THIS UNLESS YOU KNOW WHAT YOU ARE DOING", + "firmware_channel_stable": "Stable", + "firmware_channel_beta": "Beta", + "firmware_channel_develop": "Develop", + "terminal_board_select": "Select a board...", + "terminal_board_search": "Search boards...", + "terminal_board_none": "No board found.", + "terminal_flash_button": "Flash", + "terminal_flash_progress": "Flash Progress: {{status}}", + "terminal_flash_idle": "Idle", + "terminal_flash_no_device": "No device selected.", + "terminal_flash_resetting": "Resetting...", + "terminal_flash_downloading": "Downloading firmware...", + "terminal_flash_download_failed": "Failed to download firmware.", + "terminal_flash_flashing": "Flashing firmware...", + "terminal_flash_rebooting": "Rebooting device... (Reconnect to power manually if stuck)", + "terminal_flash_done": "Rebooted device! Flashing complete.", + "terminal_port_select": "Select Device", + "terminal_port_disconnect": "Disconnect Device", + "terminal_port_connected": "Device connected: {{id}}", + "terminal_console": "Console", + "terminal_connected_device": "Connected device", + "terminal_resize": "Resize terminal panel", + "terminal_reboot": "Reboot", + "terminal_disconnect": "Disconnect", + "terminal_fullscreen_exit_esc": "Exit fullscreen (Esc)", + "terminal_fullscreen_exit": "Exit fullscreen", + "terminal_fullscreen_fill": "Fill the window", + "terminal_command_label": "Serial command", + "terminal_command_placeholder": "Type a command...", + "terminal_command_send": "Send command", + "terminal_colors": "Colors", + "terminal_colors_menu": "Colors...", + "terminal_colors_label": "Console colors", + "terminal_colors_close": "Close colors", + "terminal_color_input": "{{name}} color", + "terminal_colors_reset": "Reset to defaults", + "terminal_color_bg": "Background", + "terminal_color_fg": "Text", + "terminal_color_ts": "Timestamp", + "terminal_color_error": "Error", + "terminal_color_warning": "Warning", + "terminal_color_info": "Info", + "terminal_color_debug": "Debug", + "terminal_color_verbose": "Verbose", + "terminal_options": "Options", + "terminal_options_label": "Console options", + "terminal_hide_system": "Hide system messages", + "terminal_stick_bottom": "Stick to bottom", + "terminal_raw_output": "Raw output", + "terminal_timestamps": "Timestamps", + "terminal_timestamp_uptime": "Uptime", + "terminal_timestamp_local": "Local", + "terminal_timestamp_ms": "Ms", + "terminal_timestamp_off": "Off", + "terminal_copy_settings": "Copy settings", + "terminal_import_settings": "Import settings", + "terminal_copy_selection": "Copy selection", + "terminal_copy_all": "Copy all output", + "terminal_toast_selection_copied": "Selection copied", + "terminal_toast_output_copied": "Console output copied", + "terminal_toast_settings_copied": "Console settings copied", + "terminal_toast_clipboard_unreadable": "Could not read the clipboard", + "terminal_toast_settings_imported": "Console settings imported", + "terminal_toast_settings_invalid": "Clipboard does not contain console settings", + "common_try_again": "Try again", + "terminal_cfg_intro": "Values are sent to the device via UART. Read the device's response in the console below. Commands without an argument act as getters; use the button next to each field to read the current value.", + "terminal_cfg_rf_title": "RF Transmitter", + "terminal_cfg_rf_desc": "Controls the shocker RF output.", + "terminal_cfg_tx_pin": "TX GPIO pin", + "terminal_cfg_example": "e.g. {{value}}", + "terminal_cfg_read_value": "Read current value", + "terminal_cfg_set": "Set", + "terminal_cfg_read": "Read", + "terminal_cfg_reading": "Reading…", + "terminal_cfg_apply": "Apply", + "terminal_cfg_keepalive": "Keepalive enabled", + "terminal_cfg_keepalive_desc": "Periodically pings paired shockers to keep them awake.", + "terminal_cfg_estop_title": "Emergency Stop", + "terminal_cfg_estop_desc": "Hardware button that halts all output.", + "terminal_cfg_estop_enabled": "EStop enabled", + "terminal_cfg_estop_pin": "EStop GPIO pin", + "terminal_cfg_estop_note": "Note: {{latching}} and {{active}} have no dedicated commands; set them via the JSON config below.", + "terminal_cfg_wifi_title": "WiFi", + "terminal_cfg_wifi_desc": "Station credentials and device hostname.", + "terminal_cfg_hostname": "Hostname", + "terminal_cfg_networks": "Networks (JSON array)", + "terminal_cfg_invalid_json_array": "Must be a valid JSON array", + "terminal_cfg_ap_note": "AP settings ({{ssid}}, {{password}}, {{disabled}}, {{staDisabled}}, {{offlineMode}}) have no dedicated commands; use the JSON config.", + "terminal_cfg_backend_title": "Backend", + "terminal_cfg_backend_desc": "OpenShock server and authentication.", + "terminal_cfg_domain": "Domain", + "terminal_cfg_domain_restart": "Setting the domain will restart the device.", + "terminal_cfg_auth_token": "Auth token", + "terminal_cfg_auth_token_placeholder": "Paste device token", + "terminal_cfg_hide": "Hide", + "terminal_cfg_show": "Show", + "terminal_cfg_serial_title": "Serial Input", + "terminal_cfg_echo": "Echo enabled", + "terminal_cfg_echo_desc": "Print typed characters back to the console.", + "terminal_cfg_advanced_title": "Advanced: full config", + "terminal_cfg_advanced_desc": "For fields without dedicated commands (captive portal, OTA, LAN, etc.), replace the entire config.", + "terminal_cfg_json_config": "JSON config", + "terminal_cfg_invalid_json": "Must be valid JSON", + "terminal_cfg_read_json": "Read current config as JSON", + "terminal_cfg_json_restart": "Applying a JSON config will restart the device.", + "terminal_cfg_raw_config": "Raw FlatBuffer config (base64)", + "terminal_cfg_invalid_base64": "Must be a valid base64 string", + "terminal_cfg_read_raw": "Read current config as base64", + "terminal_cfg_factory_reset": "Factory reset", + "terminal_cfg_factory_reset_desc": "Wipes the entire device configuration.", + "terminal_cfg_factory_reset_title": "Factory reset device?", + "terminal_cfg_factory_reset_action": "Wipe config", + "terminal_cfg_factory_reset_confirm": "This will erase all configuration on the device; WiFi networks, backend credentials, pins, and all other settings. The device will be reset to defaults.", + "terminal_cfg_read_failed_json_title": "Couldn't read the JSON config", + "terminal_cfg_read_failed_raw_title": "Couldn't read the raw config", + "terminal_cfg_read_failed_desc": "The device didn't respond after {{attempts}} attempts.", + "terminal_cfg_common_causes": "Common causes:", + "terminal_cfg_cause_busy": "The device is busy handling another command.", + "terminal_cfg_cause_disconnected": "The device disconnected or rebooted.", + "terminal_cfg_cause_unsupported": "The firmware version doesn't support this command.", + "common_status": "Status", + "common_version": "Version", + "common_created": "Created", + "common_create": "Create", + "common_done": "Done", + "common_enable": "Enable", + "common_disable": "Disable", + "common_are_you_sure": "Are you sure?", + "common_generating": "Generating...", + "hubs_title": "Hubs", + "hubs_subtitle": "Every hub registered to your account.", + "hubs_add": "Add Hub", + "hubs_load_failed": "Failed to load hubs.", + "hubs_empty_title": "No hubs yet", + "hubs_empty_desc": "A hub is the device that relays commands to your shockers. Add one to get started.", + "hubs_create_title": "Create hub", + "hubs_name_label": "Hub Name", + "hubs_name_placeholder": "My Hub", + "hub_toast_not_connected": "Not connected to the server", + "hub_toast_try_later": "Try again in a moment.", + "hub_reboot_title": "Reboot {{name}}?", + "hub_reboot_desc": "The hub will disconnect and restart. Any shockers paired to it stop responding until it comes back online.", + "hub_reboot": "Reboot", + "hub_hotspot_enable_title": "Enable Wi-Fi hotspot on {{name}}?", + "hub_hotspot_disable_title": "Disable Wi-Fi hotspot on {{name}}?", + "hub_hotspot_enable_desc": "The hub broadcasts its own setup network. It stays reachable on your Wi-Fi, but the hotspot is open to anyone in range until you turn it off.", + "hub_hotspot_disable_desc": "The setup hotspot shuts down. If the hub is not already on your Wi-Fi you will need physical access to set it up again.", + "hub_delete_desc": "You are about to delete hub {{name}}.", + "hub_delete_shockers": "This will also delete the following shockers:", + "hub_edit_title": "Edit hub", + "hub_edit_apply": "Apply", + "hub_pair_title_generate": "Generate pair code?", + "hub_pair_title_generated": "Pair code generated", + "hub_pair_title_paired": "Hub paired", + "hub_pair_consumed": "{{name}} consumed this pair code and is now paired.", + "hub_pair_used": "The code has been used and is no longer valid.", + "hub_pair_generated_for": "Pair code generated for {{name}}.", + "hub_copy_now": "The code below will not be accessible later, please copy it now and update clients with it.", + "hub_pair_generate_for": "You are about to generate a pair code for {{name}}.", + "hub_pair_valid_for": "It will be valid for 15 minutes after its creation.", + "hub_pair_one_active": "There is only one active pair code per hub, newly generated ones will override the older active ones.", + "hub_pair_complete": "Pairing complete", + "hub_pair_code_label": "Pair code:", + "hub_pair_copied_close": "Code has been copied, close", + "hub_pair_get": "Get Pair Code", + "hub_token_generated": "Token generated", + "hub_token_generated_for": "New token generated for {{name}}.", + "hub_token_regenerate_for": "You are about to regenerate the token for {{name}}.", + "hub_token_invalidate": "This action will invalidate the current token and disconnect clients using it.", + "hub_token_confirm": "Are you sure you want to do this?", + "hub_token_label": "New token:", + "hub_token_copied_close": "Token has been copied, close", + "hub_token_regenerate": "Regenerate Token", + "hub_menu_update": "Update", + "hub_menu_label": "Hub", + "hub_menu_hotspot_enable": "Enable Wi-Fi hotspot", + "hub_menu_hotspot_disable": "Disable Wi-Fi hotspot", + "hub_menu_pair": "Pair", + "hub_menu_estop": "Emergency Stop", + "hub_update_breadcrumb": "Update", + "hub_update_unknown_hub": "Unknown Hub", + "hub_update_unknown_task": "Unknown Task", + "hub_update_task_metadata": "Fetching Metadata", + "hub_update_task_preparing": "Preparing for Update", + "hub_update_task_flash_fs": "Flashing Filesystem", + "hub_update_task_verify_fs": "Verifying Filesystem", + "hub_update_task_flash_app": "Flashing Application", + "hub_update_task_bootable": "Marking Application Bootable", + "hub_update_task_rebooting": "Rebooting", + "hub_update_status_started": "Started", + "hub_update_status_running": "Running", + "hub_update_status_finished": "Finished", + "hub_update_status_error": "Error", + "hub_update_status_timeout": "Timeout", + "hub_update_confirm_title": "Confirm firmware update", + "hub_update_confirm_desc": "Update {{name}} to version {{version}}?", + "hub_update_unstable_warning": "This version may not be from the stable channel and could contain bugs.", + "hub_update_title": "Update {{name}}", + "hub_update_subtitle": "Manage firmware updates for this hub.", + "hub_update_status_title": "Hub Status", + "hub_update_firmware": "Firmware: {{version}}", + "hub_update_confirm": "Update", + "hub_update_success": "Update completed successfully", + "hub_update_rolled_back": "Device rolled back to previous version", + "hub_update_back": "Back to Hubs", + "hub_update_flash_again": "Flash Again", + "hub_update_card_title": "Firmware Update", + "hub_update_card_desc": "Select a firmware channel and version to install.", + "hub_update_to": "Update to {{version}}", + "hub_update_must_be_online": "Hub must be online to start an update.", + "hub_update_updating_to": "Updating to {{version}}...", + "hub_update_total": "Total", + "hub_update_task": "Task", + "hub_update_history": "Update History", + "hub_update_no_history": "No update history found for this hub.", + "hub_update_col_id": "ID", + "hub_update_col_started": "Started", + "hub_update_col_message": "Message", + "hub_update_loading": "Loading hub information...", + "hub_update_not_found": "Hub not found.", + "home_breadcrumb": "Home", + "home_welcome": "Welcome back", + "home_welcome_name": "Welcome back, {{name}}", + "home_subtitle": "Here's an overview of your OpenShock setup.", + "home_hubs_online": "{{count}} online", + "home_hub_status": "Hub Status", + "home_no_hubs": "No hubs", + "home_all_online": "All online", + "home_all_offline": "All offline", + "home_some_online": "{{online}}/{{total}} online", + "home_quick_links": "Quick Links", + "home_my_shockers": "My Shockers", + "home_my_shockers_desc": "Control your shockers", + "home_hubs_desc": "Manage your hubs", + "home_shared_desc": "Shockers shared with you", + "home_public_desc": "Manage share links", + "home_get_started": "Get Started", + "home_get_started_desc": "You don't have any hubs yet. Create a hub to connect your first device, then add shockers to it.", + "home_set_up_hub": "Set Up a Hub", + "home_first_shocker": "Add Your First Shocker", + "home_first_shocker_desc_one": "You have {{count}} hub set up. Add a shocker to start controlling it.", + "home_first_shocker_desc_other": "You have {{count}} hubs set up. Add a shocker to start controlling it.", + "home_go_to_shockers": "Go to Shockers", + "profile_title": "Profile", + "profile_coming_soon": "Profile is coming soon", + "profile_coming_soon_desc": "Your public profile is not available yet. Account details live under Settings.", + "common_retry": "Retry", + "common_never_used": "Never used", + "common_expires": "Expires {{time}}", + "common_search_placeholder": "Search...", + "common_unknown": "Unknown", + "settings_breadcrumb_account": "Account", + "account_subtitle": "Your sign-in details and account actions.", + "account_change_username": "Change Username", + "account_change_email": "Change Email", + "account_change_password": "Change Password", + "account_username_label": "Username", + "account_email_label": "Email", + "account_password_label": "Password", + "account_new_password_label": "New Password", + "account_confirm_password_label": "Confirm New Password", + "account_oauth_only": "Not available for OAuth-only accounts", + "account_oauth_no_password": "This account signs in via OAuth and has no password.", + "account_diagnostics": "Diagnostics", + "account_diagnostics_desc": "Help us fix crashes and slow API calls. Reports include the error message, stack trace and your IP. Off by default.", + "account_diagnostics_level": "Diagnostics level", + "account_telemetry_off": "Off", + "account_telemetry_off_desc": "Send nothing.", + "account_telemetry_errors": "Errors", + "account_telemetry_errors_desc": "Send browser error reports only.", + "account_telemetry_full": "Full", + "account_telemetry_full_desc": "Error reports plus traces of API calls (no page navigations).", + "account_toast_deactivated": "Account deactivated successfully", + "account_deactivate_title": "Deactivate account", + "account_deactivate_desc": "Are you sure you want to deactivate your account?", + "account_deactivate": "Deactivate Account", + "account_email_title": "Change email", + "account_email_desc": "Enter your new email address and confirm with your current password.", + "account_email_toast_sent": "Verification email sent to {{email}}. Click the link in that email to apply the change.", + "account_new_email": "New Email", + "account_current_password": "Current Password", + "account_password_title": "Change password", + "account_password_desc": "Enter your current password and choose a new one.", + "account_password_toast": "Password has been changed", + "account_username_title": "Change username", + "account_username_desc": "Enter a new username.", + "account_new_username": "New Username", + "account_username_toast": "Username changed successfully", + "tokens_subtitle": "API Tokens are used to authenticate with the OpenShock API.", + "tokens_generate": "Generate Token", + "tokens_toast_refreshed": "Tokens refreshed successfully", + "tokens_empty_title": "No API tokens", + "tokens_empty_desc": "Generate a token to authenticate with the OpenShock API.", + "tokens_created_on": "Created {{date}}", + "tokens_last_used": "Last used {{time}}", + "tokens_never_expires": "Never expires", + "tokens_load_failed": "Failed to load API tokens.", + "token_toast_edited": "Token edited successfully", + "token_name_required": "Name is required", + "token_name_too_long": "Name is too long", + "token_edit_title": "Edit API token", + "token_name_label": "Token Name", + "token_name_placeholder": "Token name...", + "token_permissions": "Permissions", + "token_perm_category_shockers": "Shockers", + "token_perm_category_devices": "Hubs", + "token_perm_category_usershares": "User Shares", + "token_perm_category_publicshares": "Public Shares", + "token_perm_use": "Use", + "token_perm_edit": "Edit", + "token_perm_pause": "Pause", + "token_perm_auth": "Authenticate", + "token_shocker_control": "Shocker Control", + "token_toast_paused": "Token paused", + "token_toast_resumed": "Token resumed", + "token_delete_title": "Delete API token", + "token_delete_desc": "Are you sure you want to delete {{name}}?", + "token_delete_permanent": "This action cannot be undone. This will permanently delete the token.", + "token_toast_deleted": "Token deleted successfully", + "token_resume": "Resume token", + "token_pause": "Pause token", + "token_mode_clamp_desc": "Clamp: requests outside the allowed range are capped to the nearest limit (the min or the max).", + "token_mode_lerp_desc": "Lerp: the full input range is linearly rescaled so it fits within your allowed min–max range.", + "token_paused_desc": "A paused token may not send shocker control messages.", + "token_intensity_range": "Intensity range", + "token_duration_range": "Duration range", + "token_new_breadcrumb": "New", + "token_redirect_not_allowed": "The provided redirect_uri is not allowed. Only loopback addresses or custom application schemes are permitted.", + "token_params_missing": "Required get parameters are missing. Make sure name, redirect_uri, and permissions are provided.", + "token_invalid_permissions": "Invalid permissions provided: {{list}}", + "token_toast_created": "Token created successfully", + "token_request_title": "API Token Request", + "token_access_granted": "Access granted", + "token_shared_redirecting": "The token has been created and shared with the application. Redirecting you back to {{uri}}.", + "token_not_redirected": "If you are not redirected automatically, use the button below.", + "token_finish": "Finish", + "token_generated_title": "API Token Generated", + "token_copy_now": "Please copy your API Token now, you will not be able to view it again later!", + "token_new_title": "New API Token", + "token_external_desc": "An external application is requesting access to your account. Review and adjust the permissions below before allowing access.", + "token_new_desc": "Configure and generate a new API token for your account.", + "token_external_requesting": "{{name}} is requesting an API Token. Your token will be shared with the application at {{uri}}.", + "token_allow": "Allow", + "token_generate": "Generate", + "token_deny": "Deny", + "sessions_subtitle": "Every active session on your account. Revoke any you do not recognize.", + "sessions_unknown_device": "Unknown device", + "sessions_toast_refreshed": "Sessions refreshed successfully", + "sessions_load_failed": "Failed to load sessions.", + "sessions_empty_title": "No active sessions", + "sessions_empty_desc": "Sessions appear here once you sign in from a browser or app.", + "sessions_last_seen": "Last seen {{time}}", + "sessions_signed_in": "Signed in {{time}}", + "session_toast_revoked": "Session revoked successfully", + "session_revoke_title": "Revoke session", + "session_revoke": "Revoke", + "session_revoke_desc": "Are you sure you want to revoke this session?", + "session_revoke_from": "Session logged in from {{ip}} using {{agent}}", + "connections_title": "OAuth Connections", + "connections_subtitle": "Link or unlink third-party accounts to sign in faster and keep your profile in sync.", + "connections_toast_linked": "Account linked.", + "connections_toast_cancelled": "Link flow cancelled.", + "connections_toast_failed": "Linking failed.", + "connections_toast_removed": "Connection removed", + "connections_refreshing": "Refreshing…", + "connections_link_new": "Link new provider", + "connections_empty_title": "No connections yet", + "connections_empty_desc": "Choose “Link new provider” above to connect available providers.", + "connections_unlink": "Unlink", + "connections_load_failed": "Failed to load OAuth connections.", + "connections_unlink_title": "Unlink {{name}}?", + "connections_unlink_title_generic": "Unlink this account?", + "connections_unlink_desc": "You'll no longer be able to sign in with this provider unless you link it again.", + "provider_starting": "Starting {{name}}...", + "provider_link": "Link {{name}}", + "audit_subtitle": "Security-relevant activity on your account. Review anything you do not recognize.", + "audit_col_time": "Time", + "audit_col_action": "Action", + "audit_col_details": "Details", + "audit_col_reason": "Reason", + "audit_col_ip": "IP address", + "audit_col_device": "Device", + "audit_action_login": "Signed in", + "audit_action_logout": "Signed out", + "audit_action_password_changed": "Password changed", + "audit_action_email_change_requested": "Email change requested", + "audit_action_email_changed": "Email changed", + "audit_action_username_changed": "Username changed", + "audit_action_api_token_created": "API token created", + "audit_action_api_token_deleted": "API token deleted", + "audit_action_oauth_connected": "Connection added", + "audit_action_oauth_disconnected": "Connection removed", + "audit_action_account_deactivated": "Account deactivated", + "audit_action_account_reactivated": "Account reactivated", + "audit_action_account_deleted": "Account deleted", + "audit_action_automation_token_created": "Automation token created", + "audit_action_automation_token_updated": "Automation token updated", + "audit_action_automation_token_rotated": "Automation token rotated", + "audit_action_automation_token_deleted": "Automation token deleted", + "audit_action_automation_token_used": "Automation token used", + "audit_meta_session": "Session {{id}}", + "audit_meta_changed": "{{old}} to {{new}}", + "audit_meta_email_requested": "Requested change to {{email}}", + "audit_meta_accounts_removed_one": "{{name}} ({{count}} account removed)", + "audit_meta_accounts_removed_other": "{{name}} ({{count}} accounts removed)", + "audit_meta_scheduled_deletion": "Scheduled for deletion", + "audit_meta_kept": "Kept for reactivation", + "common_view": "View", + "common_save": "Save", + "common_saving": "Saving...", + "common_back": "Back", + "common_shared_by": "Shared by", + "common_user_avatar": "User Avatar", + "common_toast_saved": "Changes saved successfully", + "pause_reason_shocker": "Paused at shocker level", + "pause_reason_shocker_user_share": "Paused at shocker and user share level", + "pause_reason_shocker_public_share": "Paused at shocker and public share level", + "pause_reason_user_share": "Paused at user share level", + "pause_reason_public_share": "Paused at public share level", + "public_shares_subtitle": "A link anyone can use, no account required.", + "public_shares_new": "New Share", + "public_share_never_expires": "Never expires", + "public_shares_empty_title": "No public shares yet", + "public_shares_empty_desc": "Create a link that anyone can use to control your shockers.", + "public_share_expired": "Expired", + "public_share_no_expiry": "No expiry", + "public_share_label": "Public Share", + "public_share_toast_created": "Created new public share", + "public_share_create_title": "Create public share", + "public_share_toast_deleted": "Deleted public share", + "public_share_delete_title": "Delete public share", + "public_share_delete_desc": "Are you sure you want to delete public share {{name}}?", + "public_share_edit_title": "Public Share: {{name}}", + "public_share_edit_subtitle": "Editing: changes apply when you save.", + "public_share_add_shocker": "Add Shocker", + "public_share_toast_added_one": "Added {{count}} shocker to share", + "public_share_toast_added_other": "Added {{count}} shockers to share", + "public_share_empty_shockers_title": "No shockers in this share", + "public_share_empty_shockers_desc": "Add a shocker and anyone with the link will be able to control it.", + "public_share_load_failed": "Error fetching public share details", + "public_share_paused_here": "Paused for this share", + "public_share_resume_shocker": "Resume shocker", + "public_share_pause_shocker": "Pause shocker", + "public_share_remove": "Remove from share", + "public_share_toast_removed": "Shocker removed from share", + "public_share_add_title": "Add shockers", + "public_share_add_desc": "Add shockers to this public share. You can set their limits once they are added.", + "public_share_add_placeholder": "Select shockers to share...", + "public_share_add_no_match": "No matching shockers", + "public_share_add_submit": "Add Shockers", + "public_share_view_loading": "Loading share details...", + "public_share_view_title": "Public Share Link", + "public_share_view_desc": "Enter as a guest or login with your OpenShock account", + "public_share_view_guest_name": "Guest Name", + "public_share_view_enter": "Enter", + "public_share_view_enter_guest": "Enter as Guest", + "public_share_login": "Login", + "perm_shock_on": "Shock enabled", + "perm_shock_off": "Shock disabled", + "perm_vibrate_on": "Vibrate enabled", + "perm_vibrate_off": "Vibrate disabled", + "perm_sound_on": "Sound enabled", + "perm_sound_off": "Sound disabled", + "perm_live_on": "Live enabled", + "perm_live_off": "Live disabled", + "perm_live_control": "Live Control", + "user_selector_avatar_of": "{{name}}'s avatar", + "user_selector_placeholder": "Enter user name", + "user_selector_aria": "Username to search", + "user_selector_search": "Search user", + "user_selector_found": "User found", + "common_remove": "Remove", + "user_shares_subtitle": "Direct permanent shares with other users.", + "user_shares_toast_invited": "Sent a shocker invite to {{name}}", + "user_shares_redeem": "Redeem Code", + "user_shares_new": "New Share", + "user_shares_tab_shares": "Shares", + "user_shares_tab_incoming": "Shared with Me", + "user_shares_tab_invites": "Invites", + "share_code_create_title": "New share code", + "share_code_create_desc": "Create a Share Code or Invite", + "share_code_shocker_placeholder": "Select shockers to share...", + "share_code_no_match": "No matching shockers", + "share_code_send_invite": "Send Share Invite", + "share_code_create": "Create Share Code", + "share_code_created_title": "Share code generated", + "share_code_created_desc": "Please copy share code or code link!", + "share_code_redeem_title": "Redeem share code", + "share_code_redeem_desc": "Enter the share code to redeem", + "share_code_redeem_placeholder": "Enter share code", + "share_code_redeemed": "Redeemed successfully!", + "share_code_shared_shockers": "Shared shockers", + "share_code_redeeming": "Redeeming...", + "share_code_redeem": "Redeem", + "incoming_shares_empty_title": "Nothing shared with you", + "incoming_shares_empty_desc": "No one has shared a shocker with you yet.", + "incoming_share_toast_removed": "Removed share for {{name}}", + "incoming_share_remove_title": "Remove Share", + "incoming_share_remove_desc": "Are you sure you want to remove the share for {{name}}?", + "incoming_share_toast_removed_shocker": "Removed {{shocker}} shared by {{name}}", + "incoming_share_remove_shocker_title": "Remove this shared shocker?", + "incoming_share_remove_shocker_desc": "Are you sure you want to remove the shocker share {{shocker}} by {{name}}?", + "incoming_share_manage_from": "Manage shares from", + "share_remove": "Remove share", + "invites_empty_title": "No invites yet", + "invites_empty_desc": "You have no incoming or outgoing share invites.", + "invites_outgoing": "Outgoing", + "invites_outgoing_empty_title": "No outgoing invites", + "invites_outgoing_empty_desc": "You have no outgoing share invites.", + "invites_incoming": "Incoming", + "invites_incoming_empty_title": "No incoming invites", + "invites_incoming_empty_desc": "You have no incoming share invites.", + "invite_toast_accepted": "Accepted share invite from {{name}}", + "invite_toast_declined": "Declined share invite from {{name}}", + "invite_deny_title": "Deny Invite", + "invite_deny_label": "Deny Invite", + "invite_deny": "Deny", + "invite_deny_desc": "Are you sure you want to deny the invite from {{name}}?", + "invite_accept": "Accept Invite", + "invite_toast_cancelled_for": "Cancelled invite for {{name}} ({{id}})", + "invite_toast_cancelled": "Cancelled invite {{id}}", + "invite_cancel_title": "Cancel Invite", + "invite_cancel": "Cancel", + "invite_cancel_for_desc": "Are you sure you want to cancel the invite for {{name}}?", + "invite_cancel_code_desc": "Are you sure you want to cancel the invite with code {{code}}?", + "invite_cancel_outstanding": "Cancel Outstanding Invite", + "outgoing_shares_empty_title": "No shared shockers", + "outgoing_shares_empty_desc": "You haven't shared any shockers with other users yet.", + "outgoing_share_toast_removed": "Removed shocker share {{name}}", + "outgoing_share_remove_title": "Stop sharing this shocker?", + "outgoing_share_editing_for": "Editing shares for", + "outgoing_share_limits": "Limits & Permissions", + "outgoing_share_same": "Same restrictions on every shocker", + "outgoing_share_per_desc": "Tune restrictions per shocker", + "outgoing_share_all": "All", + "outgoing_share_per": "Per shocker", + "outgoing_share_remove_desc": "Are you sure you want to stop sharing {{shocker}} with {{name}}?", + "report_breadcrumb": "Report API Tokens", + "report_toast_clipboard_failed": "Failed to read clipboard: {{error}}", + "report_title": "Report Leaked API Tokens", + "report_paste": "Paste from clipboard", + "report_warning": "This form is only for reporting accidentally leaked API tokens.", + "report_abuse_warning": "Intentional abuse will result in bans or severe endpoint restrictions.", + "report_detected": "Detected Tokens", + "report_invalid": "One or more tokens appear to be invalid. Please check for formatting issues.", + "report_acknowledge": "I confirm I understand what this feature is for and accept responsibility.", + "report_submit": "Submit Report", + "turnstile_disabled": "Turnstile disabled", + "common_internal_error": "Internal error", + "resend_toast_sent": "Activation email sent. Check your inbox and spam folder.", + "resend_toast_throttled": "Too many activation emails have been requested. Please try again later.", + "resend_toast_unavailable": "No activation email can be resent from this browser. If your account isn't activated yet, logging in sends a new link.", + "resend_button": "Didn't get the email? Resend", + "expiration_label": "Expiration", + "expiration_never": "Never", + "expiration_custom": "Custom", + "expiration_days_one": "{{count}} Day", + "expiration_days_other": "{{count}} Days", + "expiration_required": "Expire date is required", + "expiration_never_desc": "This will never expire", + "expiration_expires_at": "Expires {{time}} ({{date}})", + "date_picker_placeholder": "Pick a date", + "telemetry_toast_title": "Help improve OpenShock?", + "telemetry_toast_desc": "Send diagnostics to help us fix crashes and slow API calls. Reports include the error message, stack trace and your IP. You can change this any time in Account settings.", + "telemetry_toast_no": "No thanks", + "telemetry_toast_errors": "Errors only", + "telemetry_toast_full": "Full", + "table_show_details": "Show details", + "table_hide_details": "Hide details", + "table_no_results": "No results.", + "table_sort_asc": "Sort by {{name}}, ascending", + "table_sort_desc": "Sort by {{name}}, descending", + "table_sort_none": "Sort by {{name}}, unsorted", + "cell_na": "N/A", + "cell_not_applicable": "Not applicable", + "cell_invalid": "Invalid", + "cell_unavailable": "Unavailable", + "cell_none": "None", + "oauth_login_with": "Login with {{provider}}", + "oauth_signup_with": "Signup with {{provider}}", + "signalr_connect_failed": "Failed to connect to server!", + "signalr_disconnect_failed": "Encountered error while disconnecting from server!", + "signalr_invalid_update": "Received invalid update from server!", + "signalr_invalid_log": "Received invalid log data from server!", + "signalr_invalid_ota": "Received invalid firmware update data from server!", + "ota_toast_failed": "Hub firmware update failed: {{message}}", + "ota_toast_succeeded": "Hub firmware update completed successfully!", + "ota_toast_rolled_back": "Hub firmware rolled back to previous version", + "lcg_connect_failed": "Failed to connect to live control gateway", + "terminal_toast_bootloader_failed": "Failed to enter bootloader: {{error}}", + "terminal_toast_app_mode_failed": "Failed to enter application mode: {{error}}", + "problem_account_account_not_activated_title": "Account not activated", + "problem_account_account_not_activated_desc": "Check your inbox for the activation email.", + "problem_account_activation_not_found_title": "Activation link is invalid", + "problem_account_activation_not_found_desc": "The link may have expired or already been used.", + "problem_account_activation_resend_too_many_title": "Too many activation emails requested", + "problem_account_activation_resend_too_many_desc": "Please wait a while before trying again.", + "problem_account_activation_resend_unavailable_title": "Cannot resend activation email", + "problem_account_activation_resend_unavailable_desc": "Log in again to request a new activation link.", + "problem_account_deactivate_already_deactivated_title": "Account is already deactivated", + "problem_account_deactivate_denied_privileged_title": "Privileged accounts cannot be deactivated", + "problem_account_deactivate_unauthorized_title": "You are not allowed to do this", + "problem_account_deactivated_title": "This account has been deactivated", + "problem_account_email_already_in_use_title": "That email address is already in use", + "problem_account_email_invalid_title": "That email address is not valid", + "problem_account_email_taken_title": "That email address is already in use", + "problem_account_email_too_many_requests_title": "Too many email change requests", + "problem_account_email_too_many_requests_desc": "Please wait a while before trying again.", + "problem_account_email_unchanged_title": "That is already your email address", + "problem_account_email_verify_not_found_title": "Verification link is invalid", + "problem_account_email_verify_not_found_desc": "The link may have expired or already been used.", + "problem_account_o_auth_only_title": "This account has no password", + "problem_account_o_auth_only_desc": "Sign in with the provider you signed up with.", + "problem_account_password_not_set_title": "No password set", + "problem_account_password_not_set_desc": "This account signs in through an external provider.", + "problem_account_password_old_password_invalid_title": "Current password is incorrect", + "problem_account_username_invalid_title": "That username is not allowed", + "problem_account_username_recently_changed_title": "Username changed too recently", + "problem_account_username_recently_changed_desc": "You can change your username once every 7 days.", + "problem_account_username_taken_title": "That username is already taken", + "problem_admin_user_deactivated_title": "This user is deactivated", + "problem_admin_user_not_activated_title": "This user has not been activated yet", + "problem_api_token_can_only_delete_self_title": "An API token can only delete itself", + "problem_api_token_not_found_title": "API token not found", + "problem_api_token_paused_title": "This API token is paused", + "problem_assign_lcg_bad_schema_version_title": "Unsupported hub protocol version", + "problem_assign_lcg_bad_schema_version_desc": "Update the hub firmware to connect.", + "problem_assign_lcg_no_lcg_available_title": "No gateway available", + "problem_assign_lcg_no_lcg_available_desc": "No live control gateway is available right now. Please try again later.", + "problem_authentication_account_deactivated_title": "This account has been deactivated", + "problem_authentication_account_not_activated_title": "This account has not been activated", + "problem_authentication_cookie_missing_or_invalid_title": "You are not logged in", + "problem_authentication_cookie_missing_or_invalid_desc": "Your session may have expired. Please log in again.", + "problem_authentication_header_missing_or_invalid_title": "Invalid API token", + "problem_authentication_session_invalid_title": "Session expired", + "problem_authentication_session_invalid_desc": "Please log in again.", + "problem_authentication_token_invalid_title": "Invalid API token", + "problem_authentication_unknown_error_title": "Authentication failed", + "problem_authorization_policy_not_met_title": "You do not have permission to do this", + "problem_authorization_token_only_title": "This action requires an API token", + "problem_authorization_token_permission_missing_title": "This API token is missing a required permission", + "problem_authorization_unknown_error_title": "Authorization failed", + "problem_authorization_user_session_only_title": "This action requires a logged-in session", + "problem_automation_token_not_allowed_for_account_title": "Automation tokens cannot be used with privileged accounts", + "problem_configuration_already_exists_title": "A configuration entry with that name already exists", + "problem_configuration_invalid_name_format_title": "Invalid configuration name", + "problem_configuration_invalid_name_format_desc": "Only A to Z and underscores are allowed.", + "problem_configuration_invalid_value_format_title": "Value does not match the configuration type", + "problem_configuration_not_found_title": "Configuration entry not found", + "problem_control_stats_invalid_range_title": "The from date must not be after the to date", + "problem_control_stats_invalid_time_zone_title": "Unknown time zone", + "problem_control_stats_missing_capability_title": "Control statistics are not available on this server", + "problem_device_not_found_title": "Hub not found", + "problem_device_not_online_title": "Hub is offline", + "problem_device_too_many_hubs_title": "You have reached the maximum number of hubs", + "problem_device_too_many_shockers_title": "This hub has reached its maximum number of shockers", + "problem_endpoint_retired_title": "This feature is no longer available", + "problem_expression_error_title": "Invalid filter expression", + "problem_internal_server_error_title": "Something went wrong on our end", + "problem_login_invalid_credentials_title": "Invalid username or password", + "problem_login_invalid_domain_title": "Logging in from this address is not allowed", + "problem_o_auth_connection_already_exists_title": "Your account is already connected to this provider", + "problem_o_auth_connection_already_linked_title": "This external account is already linked to another user", + "problem_o_auth_flow_anonymous_only_title": "You are already signed in", + "problem_o_auth_flow_mismatch_title": "Sign-in attempt does not match", + "problem_o_auth_flow_mismatch_desc": "Please start over.", + "problem_o_auth_flow_missing_data_title": "The provider did not return your account details", + "problem_o_auth_flow_missing_data_desc": "Please try again.", + "problem_o_auth_flow_not_found_title": "Sign-in attempt expired", + "problem_o_auth_flow_not_found_desc": "Please start over.", + "problem_o_auth_flow_unsupported_title": "Unsupported sign-in flow", + "problem_o_auth_internal_error_title": "Something went wrong during sign-in", + "problem_o_auth_internal_error_desc": "Please try again in a moment.", + "problem_o_auth_link_authenticated_user_only_title": "You must be signed in to link an external account", + "problem_o_auth_provider_mismatch_title": "Sign-in attempt does not match the provider", + "problem_o_auth_provider_mismatch_desc": "Please start over.", + "problem_o_auth_provider_unsupported_title": "This sign-in provider is not supported", + "problem_pair_code_not_found_title": "Pair code not found", + "problem_password_reset_not_found_title": "Password reset link is invalid", + "problem_password_reset_not_found_desc": "The link may have expired or already been used.", + "problem_session_not_found_title": "Session not found", + "problem_share_get_no_shares_title": "You have no shares with this user", + "problem_share_request_create_cannot_share_with_self_title": "You cannot share with yourself", + "problem_share_request_create_shocker_not_found_title": "One or more shockers were not found", + "problem_share_request_create_shocker_not_found_desc": "They may have been removed or do not belong to you.", + "problem_share_request_not_found_title": "Share invite not found", + "problem_share_user_not_found_title": "Share not found", + "problem_share_code_already_linked_title": "Shocker is already linked to your account", + "problem_share_code_cant_link_own_share_code_title": "You cannot redeem your own share code", + "problem_share_code_not_found_title": "Share code not found", + "problem_share_link_expiry_date_in_past_title": "Expiry date cannot be in the past", + "problem_share_link_not_found_title": "Public share not found", + "problem_share_link_shocker_already_in_share_link_title": "Shocker is already in this public share", + "problem_share_link_shocker_not_in_share_link_title": "Shocker is not in this public share", + "problem_shocker_control_no_permission_title": "You do not have permission to control this shocker", + "problem_shocker_control_not_found_title": "Shocker not found", + "problem_shocker_control_paused_title": "Shocker is paused", + "problem_shocker_not_found_title": "Shocker not found", + "problem_signup_registration_disabled_title": "Registration is currently disabled", + "problem_signup_username_or_email_exists_title": "That username or email is already in use", + "problem_turnstile_invalid_title": "Verification failed", + "problem_turnstile_invalid_desc": "Please complete the challenge again and retry.", + "problem_user_not_found_title": "User not found", + "problem_user_privileged_delete_denied_title": "Privileged users cannot be deleted", + "problem_validation_error_title": "Some fields are invalid", + "problem_webhook_not_found_title": "Webhook not found", + "problem_webhook_unsupported_title": "Only Discord webhooks are supported", + "problem_webhook_unsupported_desc": "Use a discord.com URL, not canary or ptb.", + "error_too_many_requests": "Too many requests", + "error_retry_after_one": "Try again in {{count}} second.", + "error_retry_after_other": "Try again in {{count}} seconds.", + "error_unexpected_response": "Unexpected server response", + "error_internal": "Internal error occurred", + "error_network": "Network error occurred", + "dev_banner": "This is the OpenShock DEVELOPMENT environment. No data is saved, and it is regularly overwritten by production data.", + "firmware_channel_bugs_warning": "This channel might contain bugs." +} From 2b0f8c42602ab32b8a78828a7ec5e778a5b54e6b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Luc=20=E2=99=A5?= Date: Thu, 12 Nov 2026 17:43:36 +0100 Subject: [PATCH 25/27] New translations en.json (Ukrainian) [ci skip] --- messages/uk.json | 320 +++++++++++++++++------------------------------ 1 file changed, 117 insertions(+), 203 deletions(-) diff --git a/messages/uk.json b/messages/uk.json index e9c62e1b..c4f83c74 100644 --- a/messages/uk.json +++ b/messages/uk.json @@ -1,15 +1,13 @@ { - "$schema": "https://inlang.com/schema/inlang-message-format", - "landing_tagline": "Платформа для безпечного й надійного дистанційного керування шокерами з мінімальною затримкою.", "landing_section_label": "Головна", "landing_hubs_online": "Хабів онлайн зараз: ", "landing_learn_more": "Дізнатися більше", "landing_wiki": "Вікі", "landing_meta_description": "Вітаємо в OpenShock, безкоштовній екосистемі з відкритим кодом для керування різними шокерами через інтернет.", - "instance_meta_description": "Вітаємо в {siteName}, незалежному екземплярі OpenShock, безкоштовної екосистеми з відкритим кодом для керування різними шокерами через інтернет.", + "instance_meta_description": "Вітаємо в {{siteName}}, незалежному екземплярі OpenShock, безкоштовної екосистеми з відкритим кодом для керування різними шокерами через інтернет.", "header_sidebar_toggle": "Перемкнути бічну панель", - "header_avatar_alt": "Аватар {name}", + "header_avatar_alt": "Аватар {{name}}", "header_menu_profile": "Профіль", "header_menu_settings": "Налаштування", "header_menu_logout": "Вийти", @@ -17,16 +15,14 @@ "header_signup": "Реєстрація", "header_github_title": "OpenShock на GitHub", "header_discord_title": "Спільнота в Discord", - - "footer_made_with": "Зроблено з {#heart/} {#team}командою OpenShock{/team}", + "footer_made_with": "Зроблено з командою OpenShock", "footer_connection_status_label": "Стан з'єднання із сервером", "footer_signalr_state": "Стан SignalR", "footer_frontend_version": "Версія фронтенду", - "footer_frontend_commit_title": "Коміт {commit}", + "footer_frontend_commit_title": "Коміт {{commit}}", "footer_backend_version": "Версія бекенду", - "footer_backend_commit_title": "Коміт {commit}", + "footer_backend_commit_title": "Коміт {{commit}}", "footer_language_label": "Мова", - "sidebar_home_link_label": "Головна OpenShock", "sidebar_group_general": "Загальне", "sidebar_home": "Головна", @@ -53,7 +49,6 @@ "sidebar_settings_audit_log": "Журнал аудиту", "sidebar_settings_connections": "Підключення", "sidebar_settings_account": "Обліковий запис", - "error_meta_title": "Сервіс недоступний", "error_meta_description": "OpenShock зараз недоступний", "error_meta_logo_alt": "Логотип OpenShock", @@ -62,10 +57,8 @@ "error_not_found_description": "Сторінки, яку ти шукаєш, не існує.", "error_unexpected_description": "Сталася неочікувана помилка.", "error_go_back": "Назад", - "auth_layout_logo_alt": "Логотип OpenShock", "auth_layout_invalid_redirect_removed": "Задля твоєї безпеки недійсну адресу переспрямування видалено.", - "auth_activate_breadcrumb": "Активація облікового запису", "auth_activate_title": "Активація облікового запису", "auth_activate_activating": "Активуємо твій обліковий запис...", @@ -74,17 +67,15 @@ "auth_activate_missing_token": "Відсутній токен активації", "auth_activate_continue": "Перейти до входу", "auth_activate_toast_success": "Обліковий запис активовано", - "auth_forgot_breadcrumb": "Забув пароль", "auth_forgot_title": "Забув пароль", "auth_forgot_description": "Введи свою пошту, щоб скинути пароль", "auth_forgot_email_label": "Пошта", "auth_forgot_email_placeholder": "Пошта", "auth_forgot_submit": "Скинути пароль", - "auth_forgot_signin_prompt": "Пам'ятаєш пароль? {#signin}Увійти{/signin}", + "auth_forgot_signin_prompt": "Пам'ятаєш пароль? Увійти", "auth_forgot_mail_disabled": "Скидання пароля недоступне на цьому сервері, бо поштовий провайдер не налаштований. Звернися до адміністратора, щоб відновити обліковий запис.", "auth_forgot_toast_sent": "Запит на скидання пароля надіслано на вказану пошту", - "auth_login_breadcrumb": "Вхід", "auth_login_title": "З поверненням", "auth_login_loading_methods": "Завантажуємо доступні способи входу", @@ -98,23 +89,20 @@ "auth_login_username_label": "Ім'я користувача або пошта", "auth_login_password_label": "Пароль", "auth_login_submit": "Увійти", - "auth_login_signup_prompt": "Немає облікового запису? {#signup}Зареєструватися{/signup}", - "auth_login_legal": "Натискаючи «Увійти», ти погоджуєшся з нашими {#tos}Умовами використання{/tos} та {#privacy}Політикою конфіденційності{/privacy}.", - - "auth_oauth_create_breadcrumb": "Реєстрація через {provider}", - "auth_oauth_create_title": "Реєстрація через {#provider}{provider}{/provider}", + "auth_login_signup_prompt": "Немає облікового запису? Зареєструватися", + "auth_login_legal": "Натискаючи «Увійти», ти погоджуєшся з нашими Умовами використання та Політикою конфіденційності.", + "auth_oauth_create_breadcrumb": "Реєстрація через {{provider}}", + "auth_oauth_create_title": "Реєстрація через {{provider}}", "auth_oauth_create_description": "Заповни дані облікового запису", "auth_oauth_create_username_label": "Ім'я користувача", "auth_oauth_create_username_placeholder": "Ім'я користувача", "auth_oauth_create_email_label": "Пошта", "auth_oauth_create_email_placeholder": "Пошта", "auth_oauth_create_submit": "Зареєструватися", - "auth_oauth_create_legal": "Натискаючи «Зареєструватися», ти погоджуєшся з нашими {#tos}Умовами використання{/tos} та {#privacy}Політикою конфіденційності{/privacy}.", - + "auth_oauth_create_legal": "Натискаючи «Зареєструватися», ти погоджуєшся з нашими Умовами використання та Політикою конфіденційності.", "auth_oauth_error_breadcrumb": "Помилка автентифікації", "auth_oauth_error_title": "Помилка автентифікації", "auth_oauth_error_back": "Назад до входу", - "auth_reset_breadcrumb": "Скидання пароля", "auth_reset_title": "Скидання пароля", "auth_reset_checking": "Перевіряємо посилання...", @@ -127,7 +115,6 @@ "auth_reset_submit": "Скинути пароль", "auth_reset_request_new": "Запитати нове посилання", "auth_reset_toast_success": "Пароль скинуто", - "auth_signup_breadcrumb": "Реєстрація", "auth_signup_toast_created_mail": "Обліковий запис створено. Перевір пошту, щоб підтвердити його.", "auth_signup_toast_created_no_mail": "Обліковий запис створено. Тепер можна увійти.", @@ -150,11 +137,10 @@ "auth_signup_confirm_label": "Підтверди пароль", "auth_signup_confirm_placeholder": "Підтверди пароль", "auth_signup_submit": "Створити обліковий запис", - "auth_signup_signin_prompt": "Уже маєш обліковий запис? {#signin}Увійти{/signin}", + "auth_signup_signin_prompt": "Уже маєш обліковий запис? Увійти", "auth_signup_or": "Або", "auth_signup_with_email": "Реєстрація через пошту", - "auth_signup_legal": "Натискаючи «Створити обліковий запис», ти погоджуєшся з нашими {#tos}Умовами використання{/tos} та {#privacy}Політикою конфіденційності{/privacy}.", - + "auth_signup_legal": "Натискаючи «Створити обліковий запис», ти погоджуєшся з нашими Умовами використання та Політикою конфіденційності.", "auth_verify_breadcrumb": "Підтвердження пошти", "auth_verify_title": "Підтвердження пошти", "auth_verify_verifying": "Підтверджуємо твою адресу пошти...", @@ -163,7 +149,6 @@ "auth_verify_missing_token": "Відсутній токен підтвердження", "auth_verify_continue": "Перейти до входу", "auth_verify_toast_success": "Пошту підтверджено", - "common_cancel": "Скасувати", "common_delete": "Видалити", "common_edit": "Редагувати", @@ -194,7 +179,7 @@ "control_type_shock": "Удар", "control_type_vibrate": "Вібрація", "control_type_sound": "Звук", - "live_tooltip_active": "Наживо через {gateway} ({country}), {latency} мс", + "live_tooltip_active": "Наживо через {{gateway}} ({{country}}), {{latency}} мс", "live_tooltip_connecting": "Підключення...", "live_tooltip_connect": "Підключити Live Control", "live_tooltip_hub_start": "Ctrl+клік, щоб запустити весь хаб", @@ -207,14 +192,14 @@ "shocker_hub": "Хаб", "shocker_select_hub": "Обери хаб", "shocker_rf_id": "RF ID", - "shocker_rf_id_invalid": "RF ID має бути цілим числом від {min} до {max}.", + "shocker_rf_id_invalid": "RF ID має бути цілим числом від {{min}} до {{max}}.", "shocker_model": "Модель", "shocker_select_model": "Обери модель", "shocker_name_placeholder": "Назва шокера", "shocker_menu_view_logs": "Журнал", "shocker_delete_title": "Видалити шокер", - "shocker_delete_desc": "Точно видалити «{name}»? Цю дію не можна скасувати.", - "shocker_toast_deleted": "Шокер «{name}» видалено", + "shocker_delete_desc": "Точно видалити «{{name}}»? Цю дію не можна скасувати.", + "shocker_toast_deleted": "Шокер «{{name}}» видалено", "shocker_toast_paused": "Шокер призупинено", "shocker_toast_resumed": "Шокер відновлено", "shocker_add_desc": "Зареєструй новий шокер на одному зі своїх хабів.", @@ -239,18 +224,8 @@ "shockers_empty_no_hubs": "Спершу створи хаб, а потім додай до нього шокери.", "shockers_empty_has_hubs": "Додай шокер до одного зі своїх хабів, щоб почати.", "shockers_create_hub": "Створити хаб", - "shockers_count": [ - { - "declarations": ["input count", "local countPlural = count: plural"], - "selectors": ["countPlural"], - "match": { - "countPlural=one": "{count} шокер", - "countPlural=few": "{count} шокери", - "countPlural=many": "{count} шокерів", - "countPlural=other": "{count} шокера" - } - } - ], + "shockers_count_one": "{{count}} шокер", + "shockers_count_other": "{{count}} шокера", "shared_shockers_title": "Спільні шокери", "shared_shockers_subtitle": "Шокери, якими з тобою поділилися інші користувачі.", "shared_shockers_empty_title": "З тобою ще не поділилися жодним шокером.", @@ -279,18 +254,17 @@ "shocker_edit_is_active": "Шокер активний", "shocker_edit_toast_updated": "Шокер оновлено", "shocker_edit_delete_desc": "Остаточно видалити цей шокер. Цю дію не можна скасувати.", - "common_close": "Закрити", "common_continue": "Продовжити", "common_loading": "Завантаження...", "common_previous": "Назад", "common_next": "Далі", "common_steps": "Кроки", - "common_step_label": "Крок {number}: {title}", + "common_step_label": "Крок {{number}}: {{title}}", "common_copy": "Копіювати", "common_copied": "Скопійовано", "common_never": "Ніколи", - "common_error": "Помилка: {message}", + "common_error": "Помилка: {{message}}", "terminal_title": "Серійний термінал", "terminal_connecting": "Підключення...", "terminal_help_button": "Щось не виходить, допоможіть?", @@ -303,7 +277,7 @@ "terminal_mode_raw_desc": "Лише консоль. Читай журнали пристрою та надсилай команди.", "terminal_step_channel": "Обери канал", "terminal_step_board": "Обери плату", - "terminal_go_to_step": "Перейти до кроку {number}: {title}", + "terminal_go_to_step": "Перейти до кроку {{number}}: {{title}}", "terminal_erase": "Стерти перед прошивкою", "terminal_erase_desc": "Видаляє всі дані на пристрої, включно з наявними налаштуваннями", "terminal_unsupported": "Твій браузер не підтримує цю функцію.", @@ -318,15 +292,15 @@ "terminal_try_driver": "Переконайся, що серійний драйвер встановлено.", "terminal_open_troubleshooter": "Відкрити довідник з усунення проблем", "terminal_log_reset_no_device": "Помилка хоста під час скидання: немає пристрою!", - "terminal_log_reset_error": "Помилка хоста під час скидання: {error}", + "terminal_log_reset_error": "Помилка хоста під час скидання: {{error}}", "terminal_log_send_no_device": "Не вдалося надіслати: немає пристрою!", - "terminal_log_send_error": "Не вдалося надіслати: {error}", - "terminal_log_firmware_disconnected": "Прошивка від'єдналася: {error}", - "terminal_log_erase_failed": "Не вдалося стерти флеш-пам'ять: {error}", - "terminal_log_hard_reset_failed": "Не вдалося виконати апаратне скидання: {error}", + "terminal_log_send_error": "Не вдалося надіслати: {{error}}", + "terminal_log_firmware_disconnected": "Прошивка від'єдналася: {{error}}", + "terminal_log_erase_failed": "Не вдалося стерти флеш-пам'ять: {{error}}", + "terminal_log_hard_reset_failed": "Не вдалося виконати апаратне скидання: {{error}}", "terminal_log_flash_complete": "Прошивку завершено", - "terminal_log_flash_failed": "Не вдалося прошити: {error}", - "terminal_log_command_failed": "Не вдалося записати команду застосунку: {error}", + "terminal_log_flash_failed": "Не вдалося прошити: {{error}}", + "terminal_log_command_failed": "Не вдалося записати команду застосунку: {{error}}", "terminal_help_title": "Усунення проблем", "terminal_help_desc": "Пройди ці кроки по черзі. Кожен виключає одну поширену причину.", "terminal_help_step_cable": "USB-кабель", @@ -338,23 +312,23 @@ "terminal_help_port_body": "Під'єднай пристрій напряму до USB-порту комп'ютера. За можливості уникай USB-хабів, док-станцій і портів на передній панелі: вони часто спричиняють проблеми з живленням і сигналом. Якщо в тебе настільний ПК, спробуй порт на задній панелі.", "terminal_help_driver_download": "Завантаж драйвер CP210x:", "terminal_help_driver_extract": "Розпакуй вміст zip-архіву в папку на комп'ютері.", - "terminal_help_driver_run": "Відкрий папку й запусти {#code}{installer}{/code}. Виконуй підказки, щоб встановити.", + "terminal_help_driver_run": "Відкрий папку й запусти {{installer}}. Виконуй підказки, щоб встановити.", "terminal_help_driver_reconnect": "Знову під'єднай пристрій.", "terminal_help_manual_intro": "Якщо інсталятор драйвера відпрацював, але пристрій досі не з'являється:", - "terminal_help_manual_open": "Відкрий Диспетчер пристроїв (натисни {#key}Win{/key} + {#key}X{/key} і вибери {#code}Device Manager{/code}).", - "terminal_help_manual_ports": "У розділі {#code}Ports (COM & LPT){/code} знайди запис на кшталт:", + "terminal_help_manual_open": "Відкрий Диспетчер пристроїв (натисни Win + X і вибери Device Manager).", + "terminal_help_manual_ports": "У розділі Ports (COM & LPT) знайди запис на кшталт:", "terminal_help_manual_missing": "Якщо його немає, Windows взагалі не бачить пристрій. Повернися до кроків про кабель і порт.", - "terminal_help_manual_update": "Клацни правою кнопкою на пристрої та вибери {#code}Update Driver{/code}.", - "terminal_help_manual_browse": "Вибери {#code}Browse my computer for drivers{/code} і вкажи папку, куди розпакував zip із драйвером. Переконайся, що позначено {#code}Include subfolders{/code}.", - "terminal_help_manual_success": "Якщо все вдалося, запис тепер має називатися {#code}{deviceName}{/code}.", - "terminal_help_discord_intro": "Досі не виходить після всього цього? Заходь на наш Discord-сервер і питай у каналі {#code}{channel}{/code}. Вкажи:", + "terminal_help_manual_update": "Клацни правою кнопкою на пристрої та вибери Update Driver.", + "terminal_help_manual_browse": "Вибери Browse my computer for drivers і вкажи папку, куди розпакував zip із драйвером. Переконайся, що позначено Include subfolders.", + "terminal_help_manual_success": "Якщо все вдалося, запис тепер має називатися {{deviceName}}.", + "terminal_help_discord_intro": "Досі не виходить після всього цього? Заходь на наш Discord-сервер і питай у каналі {{channel}}. Вкажи:", "terminal_help_discord_os": "свою операційну систему й браузер", "terminal_help_discord_device": "пристрій, який використовуєш (модель плати, де ти її взяв)", "terminal_help_discord_tried": "що ти вже пробував із попередніх кроків", "terminal_help_discord_errors": "будь-які повідомлення про помилки або відповідний вивід термінала", "terminal_help_discord_join": "Приєднатися до нашого Discord-сервера", "terminal_risk_title": "⚠️ НЕСТАБІЛЬНА ПРОШИВКА", - "terminal_risk_intro": "Ти збираєшся встановити {#strong}експериментальну прошивку{/strong}, яка {#strong}завідомо нестабільна{/strong}.", + "terminal_risk_intro": "Ти збираєшся встановити експериментальну прошивку, яка завідомо нестабільна.", "terminal_risk_brick": "Це може назавжди вивести пристрій з ладу, вимагати ручного відновлення або зробити його непридатним.", "terminal_risk_no_support": "Ми НЕ надаємо підтримку щодо проблем, спричинених цією прошивкою.", "terminal_risk_acknowledge": "Я розумію, що вся відповідальність лежить на мені", @@ -369,7 +343,7 @@ "terminal_board_search": "Пошук плат...", "terminal_board_none": "Плату не знайдено.", "terminal_flash_button": "Прошити", - "terminal_flash_progress": "Прогрес прошивки: {status}", + "terminal_flash_progress": "Прогрес прошивки: {{status}}", "terminal_flash_idle": "Очікування", "terminal_flash_no_device": "Пристрій не вибрано.", "terminal_flash_resetting": "Скидання...", @@ -380,7 +354,7 @@ "terminal_flash_done": "Пристрій перезавантажено! Прошивку завершено.", "terminal_port_select": "Обрати пристрій", "terminal_port_disconnect": "Від'єднати пристрій", - "terminal_port_connected": "Пристрій підключено: {#strong}{id}{/strong}", + "terminal_port_connected": "Пристрій підключено: {{id}}", "terminal_console": "Консоль", "terminal_connected_device": "Підключений пристрій", "terminal_resize": "Змінити розмір панелі термінала", @@ -396,7 +370,7 @@ "terminal_colors_menu": "Кольори...", "terminal_colors_label": "Кольори консолі", "terminal_colors_close": "Закрити кольори", - "terminal_color_input": "Колір: {name}", + "terminal_color_input": "Колір: {{name}}", "terminal_colors_reset": "Скинути до типових", "terminal_color_bg": "Фон", "terminal_color_fg": "Текст", @@ -426,13 +400,12 @@ "terminal_toast_clipboard_unreadable": "Не вдалося прочитати буфер обміну", "terminal_toast_settings_imported": "Налаштування консолі імпортовано", "terminal_toast_settings_invalid": "У буфері обміну немає налаштувань консолі", - "common_try_again": "Спробувати ще", - "terminal_cfg_intro": "Значення надсилаються на пристрій через UART. Відповідь пристрою дивись у консолі нижче. Команди без аргументу працюють як геттери: натисни кнопку {#eye/} біля поля, щоб прочитати поточне значення.", + "terminal_cfg_intro": "Значення надсилаються на пристрій через UART. Відповідь пристрою дивись у консолі нижче. Команди без аргументу працюють як геттери: натисни кнопку біля поля, щоб прочитати поточне значення.", "terminal_cfg_rf_title": "RF-передавач", "terminal_cfg_rf_desc": "Керує RF-виходом для шокерів.", "terminal_cfg_tx_pin": "GPIO-пін TX", - "terminal_cfg_example": "напр. {value}", + "terminal_cfg_example": "напр. {{value}}", "terminal_cfg_read_value": "Прочитати поточне значення", "terminal_cfg_set": "Задати", "terminal_cfg_read": "Прочитати", @@ -444,13 +417,13 @@ "terminal_cfg_estop_desc": "Апаратна кнопка, яка зупиняє весь вихід.", "terminal_cfg_estop_enabled": "EStop увімкнено", "terminal_cfg_estop_pin": "GPIO-пін EStop", - "terminal_cfg_estop_note": "Примітка: для {#code}{latching}{/code} і {#code}{active}{/code} немає окремих команд, задай їх через JSON-конфіг нижче.", + "terminal_cfg_estop_note": "Примітка: для {{latching}} і {{active}} немає окремих команд, задай їх через JSON-конфіг нижче.", "terminal_cfg_wifi_title": "WiFi", "terminal_cfg_wifi_desc": "Облікові дані мережі та ім'я хоста пристрою.", "terminal_cfg_hostname": "Ім'я хоста", "terminal_cfg_networks": "Мережі (JSON-масив)", "terminal_cfg_invalid_json_array": "Має бути коректним JSON-масивом", - "terminal_cfg_ap_note": "Для налаштувань AP ({#code}{ssid}{/code}, {#code}{password}{/code}, {#code}{disabled}{/code}, {#code}{staDisabled}{/code}, {#code}{offlineMode}{/code}) немає окремих команд, використовуй JSON-конфіг.", + "terminal_cfg_ap_note": "Для налаштувань AP ({{ssid}}, {{password}}, {{disabled}}, {{staDisabled}}, {{offlineMode}}) немає окремих команд, використовуй JSON-конфіг.", "terminal_cfg_backend_title": "Бекенд", "terminal_cfg_backend_desc": "Сервер OpenShock і автентифікація.", "terminal_cfg_domain": "Домен", @@ -478,12 +451,11 @@ "terminal_cfg_factory_reset_confirm": "Це зітре всю конфігурацію на пристрої: мережі WiFi, облікові дані бекенду, піни та всі інші налаштування. Пристрій повернеться до типових налаштувань.", "terminal_cfg_read_failed_json_title": "Не вдалося прочитати JSON-конфігурацію", "terminal_cfg_read_failed_raw_title": "Не вдалося прочитати сиру конфігурацію", - "terminal_cfg_read_failed_desc": "Пристрій не відповів після {attempts} спроб.", + "terminal_cfg_read_failed_desc": "Пристрій не відповів після {{attempts}} спроб.", "terminal_cfg_common_causes": "Поширені причини:", "terminal_cfg_cause_busy": "Пристрій зайнятий іншою командою.", "terminal_cfg_cause_disconnected": "Пристрій від'єднався або перезавантажився.", "terminal_cfg_cause_unsupported": "Ця версія прошивки не підтримує цю команду.", - "common_status": "Стан", "common_version": "Версія", "common_created": "Створено", @@ -504,25 +476,25 @@ "hubs_name_placeholder": "Мій хаб", "hub_toast_not_connected": "Немає з'єднання із сервером", "hub_toast_try_later": "Спробуй ще раз за мить.", - "hub_reboot_title": "Перезавантажити {name}?", + "hub_reboot_title": "Перезавантажити {{name}}?", "hub_reboot_desc": "Хаб від'єднається та перезапуститься. Під'єднані до нього шокери не реагуватимуть, доки він знову не вийде в мережу.", "hub_reboot": "Перезавантажити", - "hub_hotspot_enable_title": "Увімкнути точку доступу Wi-Fi на {name}?", - "hub_hotspot_disable_title": "Вимкнути точку доступу Wi-Fi на {name}?", + "hub_hotspot_enable_title": "Увімкнути точку доступу Wi-Fi на {{name}}?", + "hub_hotspot_disable_title": "Вимкнути точку доступу Wi-Fi на {{name}}?", "hub_hotspot_enable_desc": "Хаб транслює власну мережу для налаштування. Він залишається доступним у твоїй Wi-Fi, але точка доступу відкрита для всіх поблизу, доки ти її не вимкнеш.", "hub_hotspot_disable_desc": "Точка доступу для налаштування вимкнеться. Якщо хаб ще не підключений до твоєї Wi-Fi, для повторного налаштування знадобиться фізичний доступ.", - "hub_delete_desc": "Ти збираєшся видалити хаб {#strong}{name}{/strong}.", + "hub_delete_desc": "Ти збираєшся видалити хаб {{name}}.", "hub_delete_shockers": "Також буде видалено ці шокери:", "hub_edit_title": "Редагувати хаб", "hub_edit_apply": "Застосувати", "hub_pair_title_generate": "Згенерувати код сполучення?", "hub_pair_title_generated": "Код сполучення згенеровано", "hub_pair_title_paired": "Хаб сполучено", - "hub_pair_consumed": "{#strong}{name}{/strong} використав цей код і тепер сполучений.", + "hub_pair_consumed": "{{name}} використав цей код і тепер сполучений.", "hub_pair_used": "Код використано, він більше не дійсний.", - "hub_pair_generated_for": "Код сполучення для {#strong}{name}{/strong} згенеровано.", + "hub_pair_generated_for": "Код сполучення для {{name}} згенеровано.", "hub_copy_now": "Код нижче потім буде недоступний, тож скопіюй його зараз і онови ним клієнти.", - "hub_pair_generate_for": "Ти збираєшся згенерувати код сполучення для {#strong}{name}{/strong}.", + "hub_pair_generate_for": "Ти збираєшся згенерувати код сполучення для {{name}}.", "hub_pair_valid_for": "Він буде дійсний 15 хвилин після створення.", "hub_pair_one_active": "Для кожного хаба діє лише один код сполучення, новий замінює попередній активний.", "hub_pair_complete": "Сполучення завершено", @@ -530,8 +502,8 @@ "hub_pair_copied_close": "Код скопійовано, закрити", "hub_pair_get": "Отримати код", "hub_token_generated": "Токен згенеровано", - "hub_token_generated_for": "Новий токен для {#strong}{name}{/strong} згенеровано.", - "hub_token_regenerate_for": "Ти збираєшся перегенерувати токен для {#strong}{name}{/strong}.", + "hub_token_generated_for": "Новий токен для {{name}} згенеровано.", + "hub_token_regenerate_for": "Ти збираєшся перегенерувати токен для {{name}}.", "hub_token_invalidate": "Це анулює поточний токен і від'єднає клієнти, які ним користуються.", "hub_token_confirm": "Точно хочеш це зробити?", "hub_token_label": "Новий токен:", @@ -559,12 +531,12 @@ "hub_update_status_error": "Помилка", "hub_update_status_timeout": "Час вичерпано", "hub_update_confirm_title": "Підтвердь оновлення прошивки", - "hub_update_confirm_desc": "Оновити {#strong}{name}{/strong} до версії {#strong}{version}{/strong}?", + "hub_update_confirm_desc": "Оновити {{name}} до версії {{version}}?", "hub_update_unstable_warning": "Ця версія може бути не зі стабільного каналу й містити помилки.", - "hub_update_title": "Оновлення {name}", + "hub_update_title": "Оновлення {{name}}", "hub_update_subtitle": "Керуй оновленнями прошивки цього хаба.", "hub_update_status_title": "Стан хаба", - "hub_update_firmware": "Прошивка: {#mono}{version}{/mono}", + "hub_update_firmware": "Прошивка: {{version}}", "hub_update_confirm": "Оновити", "hub_update_success": "Оновлення успішно завершено", "hub_update_rolled_back": "Пристрій повернувся до попередньої версії", @@ -572,9 +544,9 @@ "hub_update_flash_again": "Прошити ще раз", "hub_update_card_title": "Оновлення прошивки", "hub_update_card_desc": "Обери канал і версію прошивки для встановлення.", - "hub_update_to": "Оновити до {version}", + "hub_update_to": "Оновити до {{version}}", "hub_update_must_be_online": "Щоб почати оновлення, хаб має бути онлайн.", - "hub_update_updating_to": "Оновлюємо до {version}...", + "hub_update_updating_to": "Оновлюємо до {{version}}...", "hub_update_total": "Загалом", "hub_update_task": "Завдання", "hub_update_history": "Історія оновлень", @@ -586,14 +558,14 @@ "hub_update_not_found": "Хаб не знайдено.", "home_breadcrumb": "Головна", "home_welcome": "З поверненням", - "home_welcome_name": "З поверненням, {name}", + "home_welcome_name": "З поверненням, {{name}}", "home_subtitle": "Ось огляд твого OpenShock.", - "home_hubs_online": "{count} онлайн", + "home_hubs_online": "{{count}} онлайн", "home_hub_status": "Стан хабів", "home_no_hubs": "Немає хабів", "home_all_online": "Усі онлайн", "home_all_offline": "Усі офлайн", - "home_some_online": "{online}/{total} онлайн", + "home_some_online": "{{online}}/{{total}} онлайн", "home_quick_links": "Швидкі посилання", "home_my_shockers": "Мої шокери", "home_my_shockers_desc": "Керуй своїми шокерами", @@ -604,26 +576,15 @@ "home_get_started_desc": "У тебе ще немає хабів. Створи хаб, щоб підключити перший пристрій, а потім додай до нього шокери.", "home_set_up_hub": "Налаштувати хаб", "home_first_shocker": "Додай перший шокер", - "home_first_shocker_desc": [ - { - "declarations": ["input count", "local countPlural = count: plural"], - "selectors": ["countPlural"], - "match": { - "countPlural=one": "У тебе налаштовано {count} хаб. Додай шокер, щоб почати керування.", - "countPlural=few": "У тебе налаштовано {count} хаби. Додай шокер, щоб почати керування.", - "countPlural=many": "У тебе налаштовано {count} хабів. Додай шокер, щоб почати керування.", - "countPlural=other": "У тебе налаштовано {count} хаба. Додай шокер, щоб почати керування." - } - } - ], + "home_first_shocker_desc_one": "У тебе налаштовано {{count}} хаб. Додай шокер, щоб почати керування.", + "home_first_shocker_desc_other": "У тебе налаштовано {{count}} хаба. Додай шокер, щоб почати керування.", "home_go_to_shockers": "До шокерів", "profile_title": "Профіль", "profile_coming_soon": "Профіль скоро буде", "profile_coming_soon_desc": "Твій публічний профіль поки недоступний. Дані облікового запису є в Налаштуваннях.", - "common_retry": "Повторити", "common_never_used": "Не використовувався", - "common_expires": "Діє до {time}", + "common_expires": "Діє до {{time}}", "common_search_placeholder": "Пошук...", "common_unknown": "Невідомо", "settings_breadcrumb_account": "Обліковий запис", @@ -653,7 +614,7 @@ "account_deactivate": "Деактивувати", "account_email_title": "Зміна пошти", "account_email_desc": "Введи нову адресу пошти й підтвердь поточним паролем.", - "account_email_toast_sent": "Лист для підтвердження надіслано на {email}. Перейди за посиланням у листі, щоб застосувати зміну.", + "account_email_toast_sent": "Лист для підтвердження надіслано на {{email}}. Перейди за посиланням у листі, щоб застосувати зміну.", "account_new_email": "Нова пошта", "account_current_password": "Поточний пароль", "account_password_title": "Зміна пароля", @@ -668,8 +629,8 @@ "tokens_toast_refreshed": "Токени оновлено", "tokens_empty_title": "Немає API-токенів", "tokens_empty_desc": "Створи токен для автентифікації в OpenShock API.", - "tokens_created_on": "Створено {date}", - "tokens_last_used": "Востаннє використано {time}", + "tokens_created_on": "Створено {{date}}", + "tokens_last_used": "Востаннє використано {{time}}", "tokens_never_expires": "Безстроковий", "tokens_load_failed": "Не вдалося завантажити API-токени.", "token_toast_edited": "Токен змінено", @@ -691,7 +652,7 @@ "token_toast_paused": "Токен призупинено", "token_toast_resumed": "Токен відновлено", "token_delete_title": "Видалити API-токен", - "token_delete_desc": "Точно видалити {#strong}{name}{/strong}?", + "token_delete_desc": "Точно видалити {{name}}?", "token_delete_permanent": "Цю дію не можна скасувати. Токен буде видалено назавжди.", "token_toast_deleted": "Токен видалено", "token_resume": "Відновити токен", @@ -704,11 +665,11 @@ "token_new_breadcrumb": "Новий", "token_redirect_not_allowed": "Вказаний redirect_uri не дозволено. Дозволені лише loopback-адреси або власні схеми застосунків.", "token_params_missing": "Бракує обов'язкових GET-параметрів. Переконайся, що вказано name, redirect_uri і permissions.", - "token_invalid_permissions": "Указано недійсні дозволи: {list}", + "token_invalid_permissions": "Указано недійсні дозволи: {{list}}", "token_toast_created": "Токен створено", "token_request_title": "Запит API-токена", "token_access_granted": "Доступ надано", - "token_shared_redirecting": "Токен створено й передано застосунку. Повертаємо тебе на {#b}{uri}{/b}.", + "token_shared_redirecting": "Токен створено й передано застосунку. Повертаємо тебе на {{uri}}.", "token_not_redirected": "Якщо переспрямування не відбулося автоматично, скористайся кнопкою нижче.", "token_finish": "Завершити", "token_generated_title": "API-токен створено", @@ -716,7 +677,7 @@ "token_new_title": "Новий API-токен", "token_external_desc": "Зовнішній застосунок запитує доступ до твого облікового запису. Переглянь і за потреби зміни дозволи нижче, перш ніж надати доступ.", "token_new_desc": "Налаштуй і створи новий API-токен для свого облікового запису.", - "token_external_requesting": "{#b}{name}{/b} запитує API-токен. Твій токен буде передано застосунку за адресою {#b}{uri}{/b}.", + "token_external_requesting": "{{name}} запитує API-токен. Твій токен буде передано застосунку за адресою {{uri}}.", "token_allow": "Дозволити", "token_generate": "Створити", "token_deny": "Відхилити", @@ -726,13 +687,13 @@ "sessions_load_failed": "Не вдалося завантажити сеанси.", "sessions_empty_title": "Немає активних сеансів", "sessions_empty_desc": "Сеанси з'являться тут, щойно ти увійдеш із браузера чи застосунку.", - "sessions_last_seen": "Остання активність {time}", - "sessions_signed_in": "Вхід {time}", + "sessions_last_seen": "Остання активність {{time}}", + "sessions_signed_in": "Вхід {{time}}", "session_toast_revoked": "Сеанс відкликано", "session_revoke_title": "Відкликати сеанс", "session_revoke": "Відкликати", "session_revoke_desc": "Точно відкликати цей сеанс?", - "session_revoke_from": "Вхід із {#strong}{ip}{/strong} через {#strong}{agent}{/strong}", + "session_revoke_from": "Вхід із {{ip}} через {{agent}}", "connections_title": "OAuth-підключення", "connections_subtitle": "Прив'язуй або відв'язуй сторонні облікові записи, щоб швидше входити й тримати профіль синхронізованим.", "connections_toast_linked": "Обліковий запис прив'язано.", @@ -745,11 +706,11 @@ "connections_empty_desc": "Натисни «Прив'язати провайдера» вище, щоб підключити доступних провайдерів.", "connections_unlink": "Відв'язати", "connections_load_failed": "Не вдалося завантажити OAuth-підключення.", - "connections_unlink_title": "Відв'язати {name}?", + "connections_unlink_title": "Відв'язати {{name}}?", "connections_unlink_title_generic": "Відв'язати цей обліковий запис?", "connections_unlink_desc": "Ти більше не зможеш входити через цього провайдера, доки знову його не прив'яжеш.", - "provider_starting": "Запускаємо {name}...", - "provider_link": "Прив'язати {name}", + "provider_starting": "Запускаємо {{name}}...", + "provider_link": "Прив'язати {{name}}", "audit_subtitle": "Важливі для безпеки дії у твоєму обліковому записі. Перевір усе, чого не впізнаєш.", "audit_col_time": "Час", "audit_col_action": "Дія", @@ -775,24 +736,13 @@ "audit_action_automation_token_rotated": "Токен автоматизації замінено", "audit_action_automation_token_deleted": "Токен автоматизації видалено", "audit_action_automation_token_used": "Токен автоматизації використано", - "audit_meta_session": "Сеанс {id}", - "audit_meta_changed": "{old} на {new}", - "audit_meta_email_requested": "Запит на зміну на {email}", - "audit_meta_accounts_removed": [ - { - "declarations": ["input count", "local countPlural = count: plural"], - "selectors": ["countPlural"], - "match": { - "countPlural=one": "{name} (видалено {count} обліковий запис)", - "countPlural=few": "{name} (видалено {count} облікові записи)", - "countPlural=many": "{name} (видалено {count} облікових записів)", - "countPlural=other": "{name} (видалено {count} облікового запису)" - } - } - ], + "audit_meta_session": "Сеанс {{id}}", + "audit_meta_changed": "{{old}} на {{new}}", + "audit_meta_email_requested": "Запит на зміну на {{email}}", + "audit_meta_accounts_removed_one": "{{name}} (видалено {{count}} обліковий запис)", + "audit_meta_accounts_removed_other": "{{name}} (видалено {{count}} облікового запису)", "audit_meta_scheduled_deletion": "Заплановано видалення", "audit_meta_kept": "Збережено для відновлення", - "common_view": "Переглянути", "common_save": "Зберегти", "common_saving": "Зберігаємо...", @@ -817,22 +767,12 @@ "public_share_create_title": "Створити публічне посилання", "public_share_toast_deleted": "Публічне посилання видалено", "public_share_delete_title": "Видалити публічне посилання", - "public_share_delete_desc": "Точно видалити публічне посилання {#strong}{name}{/strong}?", - "public_share_edit_title": "Публічне посилання: {name}", + "public_share_delete_desc": "Точно видалити публічне посилання {{name}}?", + "public_share_edit_title": "Публічне посилання: {{name}}", "public_share_edit_subtitle": "Редагування: зміни застосуються після збереження.", "public_share_add_shocker": "Додати шокер", - "public_share_toast_added": [ - { - "declarations": ["input count", "local countPlural = count: plural"], - "selectors": ["countPlural"], - "match": { - "countPlural=one": "До посилання додано {count} шокер", - "countPlural=few": "До посилання додано {count} шокери", - "countPlural=many": "До посилання додано {count} шокерів", - "countPlural=other": "До посилання додано {count} шокера" - } - } - ], + "public_share_toast_added_one": "До посилання додано {{count}} шокер", + "public_share_toast_added_other": "До посилання додано {{count}} шокера", "public_share_empty_shockers_title": "У цьому посиланні немає шокерів", "public_share_empty_shockers_desc": "Додай шокер, і будь-хто з посиланням зможе ним керувати.", "public_share_load_failed": "Помилка під час отримання даних публічного посилання", @@ -862,15 +802,14 @@ "perm_live_on": "Live увімкнено", "perm_live_off": "Live вимкнено", "perm_live_control": "Live Control", - "user_selector_avatar_of": "Аватар {name}", + "user_selector_avatar_of": "Аватар {{name}}", "user_selector_placeholder": "Введи ім'я користувача", "user_selector_aria": "Ім'я користувача для пошуку", "user_selector_search": "Знайти користувача", "user_selector_found": "Користувача знайдено", - "common_remove": "Прибрати", "user_shares_subtitle": "Прямий постійний доступ для інших користувачів.", - "user_shares_toast_invited": "Запрошення до шокера надіслано {name}", + "user_shares_toast_invited": "Запрошення до шокера надіслано {{name}}", "user_shares_redeem": "Ввести код", "user_shares_new": "Нове посилання", "user_shares_tab_shares": "Доступи", @@ -893,12 +832,12 @@ "share_code_redeem": "Активувати", "incoming_shares_empty_title": "З тобою нічим не поділилися", "incoming_shares_empty_desc": "Поки ніхто не поділився з тобою шокером.", - "incoming_share_toast_removed": "Доступ від {name} прибрано", + "incoming_share_toast_removed": "Доступ від {{name}} прибрано", "incoming_share_remove_title": "Прибрати доступ", - "incoming_share_remove_desc": "Точно прибрати доступ від {#strong}{name}{/strong}?", - "incoming_share_toast_removed_shocker": "Прибрано {shocker}, яким поділився {name}", + "incoming_share_remove_desc": "Точно прибрати доступ від {{name}}?", + "incoming_share_toast_removed_shocker": "Прибрано {{shocker}}, яким поділився {{name}}", "incoming_share_remove_shocker_title": "Прибрати цей спільний шокер?", - "incoming_share_remove_shocker_desc": "Точно прибрати доступ до шокера {#strong}{shocker}{/strong} від {#strong}{name}{/strong}?", + "incoming_share_remove_shocker_desc": "Точно прибрати доступ до шокера {{shocker}} від {{name}}?", "incoming_share_manage_from": "Керування доступом від", "share_remove": "Прибрати доступ", "invites_empty_title": "Запрошень поки немає", @@ -909,23 +848,23 @@ "invites_incoming": "Вхідні", "invites_incoming_empty_title": "Немає вхідних запрошень", "invites_incoming_empty_desc": "У тебе немає вхідних запрошень.", - "invite_toast_accepted": "Запрошення від {name} прийнято", - "invite_toast_declined": "Запрошення від {name} відхилено", + "invite_toast_accepted": "Запрошення від {{name}} прийнято", + "invite_toast_declined": "Запрошення від {{name}} відхилено", "invite_deny_title": "Відхилити запрошення", "invite_deny_label": "Відхилити запрошення", "invite_deny": "Відхилити", - "invite_deny_desc": "Точно відхилити запрошення від {#strong}{name}{/strong}?", + "invite_deny_desc": "Точно відхилити запрошення від {{name}}?", "invite_accept": "Прийняти", - "invite_toast_cancelled_for": "Запрошення для {name} ({id}) скасовано", - "invite_toast_cancelled": "Запрошення {id} скасовано", + "invite_toast_cancelled_for": "Запрошення для {{name}} ({{id}}) скасовано", + "invite_toast_cancelled": "Запрошення {{id}} скасовано", "invite_cancel_title": "Скасувати запрошення", "invite_cancel": "Скасувати", - "invite_cancel_for_desc": "Точно скасувати запрошення для {#strong}{name}{/strong}?", - "invite_cancel_code_desc": "Точно скасувати запрошення з кодом {#strong}{code}{/strong}?", + "invite_cancel_for_desc": "Точно скасувати запрошення для {{name}}?", + "invite_cancel_code_desc": "Точно скасувати запрошення з кодом {{code}}?", "invite_cancel_outstanding": "Скасувати активне запрошення", "outgoing_shares_empty_title": "Немає спільних шокерів", "outgoing_shares_empty_desc": "Ти ще не поділився жодним шокером з іншими користувачами.", - "outgoing_share_toast_removed": "Доступ до шокера {name} прибрано", + "outgoing_share_toast_removed": "Доступ до шокера {{name}} прибрано", "outgoing_share_remove_title": "Припинити доступ до цього шокера?", "outgoing_share_editing_for": "Редагування доступу для", "outgoing_share_limits": "Ліміти й дозволи", @@ -933,11 +872,9 @@ "outgoing_share_per_desc": "Окремі обмеження для кожного шокера", "outgoing_share_all": "Усі", "outgoing_share_per": "Окремо", - - "outgoing_share_remove_desc": "Точно припинити доступ {#strong}{name}{/strong} до {#strong}{shocker}{/strong}?", - + "outgoing_share_remove_desc": "Точно припинити доступ {{name}} до {{shocker}}?", "report_breadcrumb": "Повідомити про токени", - "report_toast_clipboard_failed": "Не вдалося прочитати буфер обміну: {error}", + "report_toast_clipboard_failed": "Не вдалося прочитати буфер обміну: {{error}}", "report_title": "Повідомити про витік API-токенів", "report_paste": "Вставити з буфера", "report_warning": "Ця форма лише для повідомлень про випадковий витік API-токенів.", @@ -955,21 +892,11 @@ "expiration_label": "Термін дії", "expiration_never": "Ніколи", "expiration_custom": "Свій", - "expiration_days": [ - { - "declarations": ["input count", "local countPlural = count: plural"], - "selectors": ["countPlural"], - "match": { - "countPlural=one": "{count} день", - "countPlural=few": "{count} дні", - "countPlural=many": "{count} днів", - "countPlural=other": "{count} дня" - } - } - ], + "expiration_days_one": "{{count}} день", + "expiration_days_other": "{{count}} дня", "expiration_required": "Дата закінчення обов'язкова", "expiration_never_desc": "Без терміну дії", - "expiration_expires_at": "Діє до {time} ({date})", + "expiration_expires_at": "Діє до {{time}} ({{date}})", "date_picker_placeholder": "Обери дату", "telemetry_toast_title": "Допоможеш покращити OpenShock?", "telemetry_toast_desc": "Надсилай діагностику, щоб допомогти нам виправляти збої та повільні запити до API. Звіти містять повідомлення про помилку, стек викликів і твою IP-адресу. Це можна змінити будь-коли в налаштуваннях облікового запису.", @@ -979,28 +906,27 @@ "table_show_details": "Показати деталі", "table_hide_details": "Сховати деталі", "table_no_results": "Немає результатів.", - "table_sort_asc": "Сортувати за {name}, за зростанням", - "table_sort_desc": "Сортувати за {name}, за спаданням", - "table_sort_none": "Сортувати за {name}, без сортування", + "table_sort_asc": "Сортувати за {{name}}, за зростанням", + "table_sort_desc": "Сортувати за {{name}}, за спаданням", + "table_sort_none": "Сортувати за {{name}}, без сортування", "cell_na": "Н/Д", "cell_not_applicable": "Не застосовується", "cell_invalid": "Недійсне", "cell_unavailable": "Недоступно", "cell_none": "Немає", - "oauth_login_with": "Увійти через {provider}", - "oauth_signup_with": "Реєстрація через {provider}", + "oauth_login_with": "Увійти через {{provider}}", + "oauth_signup_with": "Реєстрація через {{provider}}", "signalr_connect_failed": "Не вдалося підключитися до сервера!", "signalr_disconnect_failed": "Помилка під час від'єднання від сервера!", "signalr_invalid_update": "Від сервера отримано недійсне оновлення!", "signalr_invalid_log": "Від сервера отримано недійсні дані журналу!", "signalr_invalid_ota": "Від сервера отримано недійсні дані оновлення прошивки!", - "ota_toast_failed": "Не вдалося оновити прошивку хаба: {message}", + "ota_toast_failed": "Не вдалося оновити прошивку хаба: {{message}}", "ota_toast_succeeded": "Прошивку хаба успішно оновлено!", "ota_toast_rolled_back": "Прошивку хаба повернуто до попередньої версії", "lcg_connect_failed": "Не вдалося підключитися до шлюзу Live Control", - "terminal_toast_bootloader_failed": "Не вдалося увійти в завантажувач: {error}", - "terminal_toast_app_mode_failed": "Не вдалося увійти в режим застосунку: {error}", - + "terminal_toast_bootloader_failed": "Не вдалося увійти в завантажувач: {{error}}", + "terminal_toast_app_mode_failed": "Не вдалося увійти в режим застосунку: {{error}}", "problem_account_account_not_activated_title": "Обліковий запис не активовано", "problem_account_account_not_activated_desc": "Пошукай лист для активації у вхідних.", "problem_account_activation_not_found_title": "Посилання для активації недійсне", @@ -1118,24 +1044,12 @@ "problem_webhook_not_found_title": "Вебхук не знайдено", "problem_webhook_unsupported_title": "Підтримуються лише вебхуки Discord", "problem_webhook_unsupported_desc": "Використовуй URL discord.com, а не canary чи ptb.", - "error_too_many_requests": "Забагато запитів", - "error_retry_after": [ - { - "declarations": ["input seconds", "local secondsPlural = seconds: plural"], - "selectors": ["secondsPlural"], - "match": { - "secondsPlural=one": "Спробуй ще раз через {seconds} секунду.", - "secondsPlural=few": "Спробуй ще раз через {seconds} секунди.", - "secondsPlural=many": "Спробуй ще раз через {seconds} секунд.", - "secondsPlural=other": "Спробуй ще раз через {seconds} секунди." - } - } - ], + "error_retry_after_one": "Спробуй ще раз через {{count}} секунду.", + "error_retry_after_other": "Спробуй ще раз через {{count}} секунди.", "error_unexpected_response": "Неочікувана відповідь сервера", "error_internal": "Сталася внутрішня помилка", "error_network": "Сталася помилка мережі", - - "dev_banner": "Це {#b}ТЕСТОВЕ{/b} середовище OpenShock. {#u}Дані не зберігаються{/u} і регулярно перезаписуються даними з продакшену.", + "dev_banner": "Це ТЕСТОВЕ середовище OpenShock. Дані не зберігаються і регулярно перезаписуються даними з продакшену.", "firmware_channel_bugs_warning": "Цей канал може містити помилки." } From 8b3946e3878014e3d554c7dbe059d3784eadc80a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Luc=20=E2=99=A5?= Date: Thu, 12 Nov 2026 17:43:38 +0100 Subject: [PATCH 26/27] New translations en.json (Chinese Simplified) [ci skip] --- messages/zh.json | 1055 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 1055 insertions(+) create mode 100644 messages/zh.json diff --git a/messages/zh.json b/messages/zh.json new file mode 100644 index 00000000..ef4df56c --- /dev/null +++ b/messages/zh.json @@ -0,0 +1,1055 @@ +{ + "landing_tagline": "The go-to platform for safe, reliable, real low-latency remote shocking.", + "landing_section_label": "Home", + "landing_hubs_online": "Hubs online right now: ", + "landing_learn_more": "Learn More", + "landing_wiki": "Wiki", + "landing_meta_description": "Welcome to OpenShock, a free and open-source ecosystem to control various shock collars over the internet.", + "instance_meta_description": "Welcome to {{siteName}}, an independent instance of OpenShock, a free and open-source ecosystem to control various shock collars over the internet.", + "header_sidebar_toggle": "Toggle Sidebar", + "header_avatar_alt": "{{name}}'s avatar", + "header_menu_profile": "Profile", + "header_menu_settings": "Settings", + "header_menu_logout": "Logout", + "header_login": "Login", + "header_signup": "Sign Up", + "header_github_title": "OpenShock on GitHub", + "header_discord_title": "Community Discord", + "footer_made_with": "Made with by the OpenShock Team", + "footer_connection_status_label": "Server connection status", + "footer_signalr_state": "SignalR State", + "footer_frontend_version": "Frontend Version", + "footer_frontend_commit_title": "Commit {{commit}}", + "footer_backend_version": "Backend Version", + "footer_backend_commit_title": "Commit {{commit}}", + "footer_language_label": "Language", + "sidebar_home_link_label": "OpenShock home", + "sidebar_group_general": "General", + "sidebar_home": "Home", + "sidebar_shockers": "Shockers", + "sidebar_shared_shockers": "Shared Shockers", + "sidebar_hubs": "Hubs", + "sidebar_user_shares": "User Shares", + "sidebar_public_shares": "Public Shares", + "sidebar_serial_terminal": "Serial Terminal", + "sidebar_group_admin": "Admin", + "sidebar_admin_monitoring": "Monitoring", + "sidebar_admin_online_hubs": "Online Hubs", + "sidebar_admin_online_gateways": "Online Gateways", + "sidebar_admin_management": "Management", + "sidebar_admin_users": "Users", + "sidebar_admin_blacklists": "Blacklists", + "sidebar_admin_webhooks": "Webhooks", + "sidebar_admin_mail": "Mail", + "sidebar_admin_automation_tokens": "Automation Tokens", + "sidebar_admin_configuration": "Configuration", + "sidebar_group_settings": "Settings", + "sidebar_settings_api_tokens": "API Tokens", + "sidebar_settings_sessions": "Sessions", + "sidebar_settings_audit_log": "Audit Log", + "sidebar_settings_connections": "Connections", + "sidebar_settings_account": "Account Settings", + "error_meta_title": "Service Unavailable", + "error_meta_description": "OpenShock is currently unavailable", + "error_meta_logo_alt": "OpenShock Logo", + "error_fallback_message": "Something went wrong.", + "error_not_found_message": "Page not found", + "error_not_found_description": "The page you're looking for doesn't exist.", + "error_unexpected_description": "An unexpected error occurred.", + "error_go_back": "Go back", + "auth_layout_logo_alt": "OpenShock Logo", + "auth_layout_invalid_redirect_removed": "An invalid redirect URL was removed for your safety.", + "auth_activate_breadcrumb": "Activate Account", + "auth_activate_title": "Activate Account", + "auth_activate_activating": "Activating your account...", + "auth_activate_success": "Your account has been activated", + "auth_activate_failed": "This activation link is invalid or has expired", + "auth_activate_missing_token": "Missing activation token", + "auth_activate_continue": "Continue to login", + "auth_activate_toast_success": "Account activated", + "auth_forgot_breadcrumb": "Forgot Password", + "auth_forgot_title": "Forgot Password", + "auth_forgot_description": "Enter your email to reset your password", + "auth_forgot_email_label": "Email", + "auth_forgot_email_placeholder": "Email", + "auth_forgot_submit": "Reset Password", + "auth_forgot_signin_prompt": "Remember your password? Sign in", + "auth_forgot_mail_disabled": "Password resets are unavailable on this instance because it has no mail provider configured. Please contact your administrator for help recovering your account.", + "auth_forgot_toast_sent": "Reset password request has been sent to the given email", + "auth_login_breadcrumb": "Login", + "auth_login_title": "Welcome back", + "auth_login_loading_methods": "Loading available login methods", + "auth_login_choose_method": "Login with one of these methods", + "auth_login_with_account": "Login with your OpenShock Account", + "auth_login_activation_after_signup": "Your account has been created. We've sent an activation link to your email address. Check your inbox and spam folder.", + "auth_login_activation_pending": "Your account isn't activated yet. We've sent an activation link to your email address. Check your inbox and spam folder. If nothing arrives, try logging in again later to get a new link.", + "auth_login_oauth_only": "This account has no password. Sign in with the provider you signed up with.", + "auth_login_oauth_only_with_buttons": "This account has no password. Sign in with the provider you signed up with using the buttons above.", + "auth_login_or_continue_with": "Or continue with", + "auth_login_username_label": "Username or Email", + "auth_login_password_label": "Password", + "auth_login_submit": "Login", + "auth_login_signup_prompt": "Don't have an account? Sign up", + "auth_login_legal": "By clicking Login, you agree to our Terms of Service and Privacy Policy.", + "auth_oauth_create_breadcrumb": "Sign Up With {{provider}}", + "auth_oauth_create_title": "Sign Up With {{provider}}", + "auth_oauth_create_description": "Complete your account details", + "auth_oauth_create_username_label": "Username", + "auth_oauth_create_username_placeholder": "Username", + "auth_oauth_create_email_label": "Email", + "auth_oauth_create_email_placeholder": "Email", + "auth_oauth_create_submit": "Sign Up", + "auth_oauth_create_legal": "By clicking Sign Up, you agree to our Terms of Service and Privacy Policy.", + "auth_oauth_error_breadcrumb": "Authentication Error", + "auth_oauth_error_title": "Authentication Error", + "auth_oauth_error_back": "Back to login", + "auth_reset_breadcrumb": "Reset Password", + "auth_reset_title": "Reset Password", + "auth_reset_checking": "Verifying reset link...", + "auth_reset_choose_password": "Choose a new password for your account", + "auth_reset_invalid": "This reset link is invalid or has expired", + "auth_reset_password_label": "New Password", + "auth_reset_password_placeholder": "New Password", + "auth_reset_confirm_label": "Confirm New Password", + "auth_reset_confirm_placeholder": "Confirm New Password", + "auth_reset_submit": "Reset Password", + "auth_reset_request_new": "Request a new reset link", + "auth_reset_toast_success": "Password has been reset", + "auth_signup_breadcrumb": "Sign Up", + "auth_signup_toast_created_mail": "Account created successfully. Please check your email to verify your account.", + "auth_signup_toast_created_no_mail": "Account created successfully. You can log in now.", + "auth_signup_dialog_title": "Welcome! Thank you for signing up! ❤️", + "auth_signup_dialog_created_mail": "Your account has been created. 🎉 Please check your email to verify your account.", + "auth_signup_dialog_verify_then_login": "After verifying your email, you can log in to your account.", + "auth_signup_dialog_created_no_mail": "Your account has been created and is ready to use. 🎉", + "auth_signup_dialog_login_now": "You can log in to your account now.", + "auth_signup_title": "Create your account", + "auth_signup_loading_methods": "Loading available sign-up methods", + "auth_signup_using_email": "Signing up using email", + "auth_signup_choose_method": "Choose your preferred sign-up method", + "auth_signup_back": "Back", + "auth_signup_username_label": "Username", + "auth_signup_username_placeholder": "John OpenShock", + "auth_signup_email_label": "Email", + "auth_signup_email_placeholder": "john@example.com", + "auth_signup_password_label": "Password", + "auth_signup_password_placeholder": "Password", + "auth_signup_confirm_label": "Confirm Password", + "auth_signup_confirm_placeholder": "Confirm Password", + "auth_signup_submit": "Create Account", + "auth_signup_signin_prompt": "Already have an account? Sign in", + "auth_signup_or": "Or", + "auth_signup_with_email": "Signup with Email", + "auth_signup_legal": "By clicking Create Account, you agree to our Terms of Service and Privacy Policy.", + "auth_verify_breadcrumb": "Verify Email", + "auth_verify_title": "Verify Email", + "auth_verify_verifying": "Verifying your email address...", + "auth_verify_success": "Your email has been verified", + "auth_verify_failed": "This verification link is invalid or has expired", + "auth_verify_missing_token": "Missing verification token", + "auth_verify_continue": "Continue to login", + "auth_verify_toast_success": "Email verified", + "common_cancel": "Cancel", + "common_delete": "Delete", + "common_edit": "Edit", + "common_share": "Share", + "common_copy_id": "Copy ID", + "common_id_copied": "ID copied to clipboard", + "common_open_menu": "Open menu", + "common_refresh": "Refresh", + "common_settings": "Settings", + "common_clear": "Clear", + "common_online": "Online", + "common_offline": "Offline", + "common_paused": "Paused", + "common_resume": "Resume", + "common_resuming": "Resuming...", + "common_coming_soon": "(Coming soon)", + "common_save_changes": "Save Changes", + "common_danger_zone": "Danger Zone", + "common_name": "Name", + "control_intensity": "Intensity", + "control_duration": "Duration", + "control_max_intensity": "Max Intensity", + "control_max_duration": "Max Duration", + "control_vibration": "Vibration", + "control_value": "Value", + "control_live_intensity": "Live intensity", + "control_type_stop": "Stop", + "control_type_shock": "Shock", + "control_type_vibrate": "Vibrate", + "control_type_sound": "Sound", + "live_tooltip_active": "Live via {{gateway}} ({{country}}), {{latency}}ms", + "live_tooltip_connecting": "Connecting...", + "live_tooltip_connect": "Connect to Live Control", + "live_tooltip_hub_start": "Ctrl+click to start the whole hub", + "live_tooltip_hub_stop": "Ctrl+click to stop the whole hub", + "pause_resume_shocker": "Resume shocker", + "pause_pause_shocker": "Pause shocker", + "pause_resume_all": "Resume all shockers", + "pause_pause_all": "Pause all shockers", + "shocker_label": "Shocker", + "shocker_hub": "Hub", + "shocker_select_hub": "Select hub", + "shocker_rf_id": "RF ID", + "shocker_rf_id_invalid": "RF ID must be a whole number between {{min}} and {{max}}.", + "shocker_model": "Model", + "shocker_select_model": "Select model", + "shocker_name_placeholder": "Shocker name", + "shocker_menu_view_logs": "View Logs", + "shocker_delete_title": "Delete Shocker", + "shocker_delete_desc": "Are you sure you want to delete \"{{name}}\"? This action cannot be undone.", + "shocker_toast_deleted": "Shocker \"{{name}}\" deleted", + "shocker_toast_paused": "Shocker paused", + "shocker_toast_resumed": "Shocker resumed", + "shocker_add_desc": "Register a new shocker to one of your hubs.", + "shocker_add_name_placeholder": "My Shocker", + "shockers_title": "Shockers", + "shockers_subtitle": "Every shocker paired to your hubs.", + "shockers_loading": "Loading shockers...", + "shockers_toast_refreshed": "Shockers refreshed", + "shockers_toast_need_hub": "You need to create a hub before adding shockers.", + "shockers_toast_added": "Shocker added", + "shockers_unknown_module": "Unknown module type", + "shockers_add": "Add Shocker", + "shockers_view_mode": "View mode", + "shockers_mode_classic": "Classic", + "shockers_mode_rich": "Rich", + "shockers_mode_simple": "Simple", + "shockers_mode_map": "Map", + "shockers_group_by_hub": "Group by Hub", + "shockers_global_limits": "Global Limits", + "shockers_logs_label": "Logs", + "shockers_empty_title": "No shockers yet", + "shockers_empty_no_hubs": "Create a hub first, then add shockers to it.", + "shockers_empty_has_hubs": "Add a shocker to one of your hubs to get started.", + "shockers_create_hub": "Create a Hub", + "shockers_count_one": "{{count}} shocker", + "shockers_count_other": "{{count}} shockers", + "shared_shockers_title": "Shared Shockers", + "shared_shockers_subtitle": "Shockers other users have shared with you.", + "shared_shockers_empty_title": "No shockers have been shared with you yet.", + "shared_shockers_empty_desc": "When someone shares their shockers with you, they'll appear here.", + "shocker_logs_title": "Shocker Logs", + "shocker_logs_subtitle": "Every control command sent to your shockers.", + "shocker_logs_live_title": "New logs appear in real time", + "shocker_logs_paused_title": "Live updates pause when sorting or viewing a page other than the first", + "shocker_logs_live": "Live", + "shocker_logs_col_time": "Time", + "shocker_logs_col_type": "Type", + "shocker_logs_col_by": "By", + "shocker_logs_filter_label": "Filter by shocker", + "shocker_logs_filter_placeholder": "Search shockers...", + "shocker_logs_filter_all": "All shockers", + "shocker_logs_filter_none": "No matching shockers", + "shocker_edit_title": "Edit Shocker", + "shocker_edit_subtitle": "Change this shocker's details or remove it.", + "shocker_edit_back": "Back to Shockers", + "shocker_edit_load_failed": "Failed to load shocker.", + "shocker_edit_loading": "Loading shocker...", + "shocker_edit_details_title": "Shocker Details", + "shocker_edit_details_desc": "Update the name, RF ID, and model for this shocker.", + "shocker_edit_pause_state": "Pause State", + "shocker_edit_is_paused": "Shocker is paused", + "shocker_edit_is_active": "Shocker is active", + "shocker_edit_toast_updated": "Shocker updated", + "shocker_edit_delete_desc": "Permanently delete this shocker. This action cannot be undone.", + "common_close": "Close", + "common_continue": "Continue", + "common_loading": "Loading...", + "common_previous": "Previous", + "common_next": "Next", + "common_steps": "Steps", + "common_step_label": "Step {{number}}: {{title}}", + "common_copy": "Copy", + "common_copied": "Copied", + "common_never": "Never", + "common_error": "Error: {{message}}", + "terminal_title": "Serial Terminal", + "terminal_connecting": "Connecting...", + "terminal_help_button": "I'm having trouble, help?", + "terminal_back_to_modes": "Back to mode picker", + "terminal_mode_configure": "Configure Device", + "terminal_mode_configure_desc": "Configure WiFi, authentication, and more. Includes an interactive serial console.", + "terminal_mode_flash": "Flash Firmware", + "terminal_mode_flash_desc": "Install or update firmware on a connected device.", + "terminal_mode_raw": "Serial Monitor", + "terminal_mode_raw_desc": "Just the console. Read device logs and send commands.", + "terminal_step_channel": "Select Channel", + "terminal_step_board": "Select Board", + "terminal_go_to_step": "Go to step {{number}}: {{title}}", + "terminal_erase": "Erase before flashing", + "terminal_erase_desc": "Clears all data on the device including existing configs", + "terminal_unsupported": "Your browser does not support this feature.", + "terminal_update_browser": "Please update your browser to the latest version.", + "terminal_use_browsers": "Please use one of the following browsers:", + "terminal_connect_failed_bootloader": "Could not enter bootloader mode", + "terminal_connect_failed": "Device connection failed", + "terminal_connect_failed_desc": "We couldn't establish a serial connection with the device.", + "terminal_quick_tries": "Quick things to try:", + "terminal_try_replug": "Unplug and replug the device.", + "terminal_try_cable": "Try a different USB cable or port.", + "terminal_try_driver": "Make sure the serial driver is installed.", + "terminal_open_troubleshooter": "Open troubleshooter", + "terminal_log_reset_no_device": "Host-side error during reset: no device!", + "terminal_log_reset_error": "Host-side error during reset: {{error}}", + "terminal_log_send_no_device": "Couldn't send: no device!", + "terminal_log_send_error": "Couldn't send: {{error}}", + "terminal_log_firmware_disconnected": "Firmware disconnected: {{error}}", + "terminal_log_erase_failed": "Failed to erase flash: {{error}}", + "terminal_log_hard_reset_failed": "Failed to hard reset: {{error}}", + "terminal_log_flash_complete": "Flash complete", + "terminal_log_flash_failed": "Failed to flash: {{error}}", + "terminal_log_command_failed": "Failed to write application command: {{error}}", + "terminal_help_title": "Troubleshooter", + "terminal_help_desc": "Work through these steps in order. Each one rules out a common cause.", + "terminal_help_step_cable": "USB cable", + "terminal_help_step_port": "USB port", + "terminal_help_step_driver": "Install driver", + "terminal_help_step_manual": "Manual driver update", + "terminal_help_step_discord": "Ask on Discord", + "terminal_help_cable_body": "Many USB-C and micro-USB cables are charge-only and don't carry data. Swap to a known-good data cable (one you've used to transfer files or connect other devices) and reconnect the hub.", + "terminal_help_port_body": "Plug the device directly into a USB port on your computer. Avoid USB hubs, docking stations, and front-panel ports if possible; these are common sources of power and signal issues. If you're on a desktop, try a port on the back of the machine.", + "terminal_help_driver_download": "Download the CP210x driver:", + "terminal_help_driver_extract": "Extract the contents of the zip file to a folder on your computer.", + "terminal_help_driver_run": "Open the folder and run {{installer}}. Follow the prompts to install.", + "terminal_help_driver_reconnect": "Reconnect the device.", + "terminal_help_manual_intro": "If the driver installer ran but the device still doesn't show up:", + "terminal_help_manual_open": "Open Device Manager (press Win + X and select Device Manager).", + "terminal_help_manual_ports": "Under Ports (COM & LPT), look for an entry like:", + "terminal_help_manual_missing": "If it's missing, the device isn't being detected by Windows at all; revisit the cable and port steps.", + "terminal_help_manual_update": "Right-click the device and pick Update Driver.", + "terminal_help_manual_browse": "Choose Browse my computer for drivers and select the folder you extracted the driver zip into. Make sure Include subfolders is checked.", + "terminal_help_manual_success": "On success, the entry should now read {{deviceName}}.", + "terminal_help_discord_intro": "Still stuck after all of the above? Hop into our Discord server and ask in the {{channel}} channel. Please include:", + "terminal_help_discord_os": "your operating system and browser", + "terminal_help_discord_device": "the device you're using (board model, where you got it)", + "terminal_help_discord_tried": "what you've already tried from the previous steps", + "terminal_help_discord_errors": "any error messages or relevant terminal output", + "terminal_help_discord_join": "Join our Discord server", + "terminal_risk_title": "⚠️ UNSTABLE FIRMWARE", + "terminal_risk_intro": "You are about to flash experimental firmware that is known to be unstable.", + "terminal_risk_brick": "This may permanently brick your device, require manual recovery, or render it unusable.", + "terminal_risk_no_support": "We will NOT provide support for issues caused by this firmware.", + "terminal_risk_acknowledge": "I understand this is entirely my responsibility", + "terminal_risk_abort": "Abort", + "terminal_risk_accept": "I ACCEPT FULL RESPONSIBILITY", + "firmware_channel_recommended": "This is the recommended channel.", + "firmware_channel_danger": "DO NOT USE THIS UNLESS YOU KNOW WHAT YOU ARE DOING", + "firmware_channel_stable": "Stable", + "firmware_channel_beta": "Beta", + "firmware_channel_develop": "Develop", + "terminal_board_select": "Select a board...", + "terminal_board_search": "Search boards...", + "terminal_board_none": "No board found.", + "terminal_flash_button": "Flash", + "terminal_flash_progress": "Flash Progress: {{status}}", + "terminal_flash_idle": "Idle", + "terminal_flash_no_device": "No device selected.", + "terminal_flash_resetting": "Resetting...", + "terminal_flash_downloading": "Downloading firmware...", + "terminal_flash_download_failed": "Failed to download firmware.", + "terminal_flash_flashing": "Flashing firmware...", + "terminal_flash_rebooting": "Rebooting device... (Reconnect to power manually if stuck)", + "terminal_flash_done": "Rebooted device! Flashing complete.", + "terminal_port_select": "Select Device", + "terminal_port_disconnect": "Disconnect Device", + "terminal_port_connected": "Device connected: {{id}}", + "terminal_console": "Console", + "terminal_connected_device": "Connected device", + "terminal_resize": "Resize terminal panel", + "terminal_reboot": "Reboot", + "terminal_disconnect": "Disconnect", + "terminal_fullscreen_exit_esc": "Exit fullscreen (Esc)", + "terminal_fullscreen_exit": "Exit fullscreen", + "terminal_fullscreen_fill": "Fill the window", + "terminal_command_label": "Serial command", + "terminal_command_placeholder": "Type a command...", + "terminal_command_send": "Send command", + "terminal_colors": "Colors", + "terminal_colors_menu": "Colors...", + "terminal_colors_label": "Console colors", + "terminal_colors_close": "Close colors", + "terminal_color_input": "{{name}} color", + "terminal_colors_reset": "Reset to defaults", + "terminal_color_bg": "Background", + "terminal_color_fg": "Text", + "terminal_color_ts": "Timestamp", + "terminal_color_error": "Error", + "terminal_color_warning": "Warning", + "terminal_color_info": "Info", + "terminal_color_debug": "Debug", + "terminal_color_verbose": "Verbose", + "terminal_options": "Options", + "terminal_options_label": "Console options", + "terminal_hide_system": "Hide system messages", + "terminal_stick_bottom": "Stick to bottom", + "terminal_raw_output": "Raw output", + "terminal_timestamps": "Timestamps", + "terminal_timestamp_uptime": "Uptime", + "terminal_timestamp_local": "Local", + "terminal_timestamp_ms": "Ms", + "terminal_timestamp_off": "Off", + "terminal_copy_settings": "Copy settings", + "terminal_import_settings": "Import settings", + "terminal_copy_selection": "Copy selection", + "terminal_copy_all": "Copy all output", + "terminal_toast_selection_copied": "Selection copied", + "terminal_toast_output_copied": "Console output copied", + "terminal_toast_settings_copied": "Console settings copied", + "terminal_toast_clipboard_unreadable": "Could not read the clipboard", + "terminal_toast_settings_imported": "Console settings imported", + "terminal_toast_settings_invalid": "Clipboard does not contain console settings", + "common_try_again": "Try again", + "terminal_cfg_intro": "Values are sent to the device via UART. Read the device's response in the console below. Commands without an argument act as getters; use the button next to each field to read the current value.", + "terminal_cfg_rf_title": "RF Transmitter", + "terminal_cfg_rf_desc": "Controls the shocker RF output.", + "terminal_cfg_tx_pin": "TX GPIO pin", + "terminal_cfg_example": "e.g. {{value}}", + "terminal_cfg_read_value": "Read current value", + "terminal_cfg_set": "Set", + "terminal_cfg_read": "Read", + "terminal_cfg_reading": "Reading…", + "terminal_cfg_apply": "Apply", + "terminal_cfg_keepalive": "Keepalive enabled", + "terminal_cfg_keepalive_desc": "Periodically pings paired shockers to keep them awake.", + "terminal_cfg_estop_title": "Emergency Stop", + "terminal_cfg_estop_desc": "Hardware button that halts all output.", + "terminal_cfg_estop_enabled": "EStop enabled", + "terminal_cfg_estop_pin": "EStop GPIO pin", + "terminal_cfg_estop_note": "Note: {{latching}} and {{active}} have no dedicated commands; set them via the JSON config below.", + "terminal_cfg_wifi_title": "WiFi", + "terminal_cfg_wifi_desc": "Station credentials and device hostname.", + "terminal_cfg_hostname": "Hostname", + "terminal_cfg_networks": "Networks (JSON array)", + "terminal_cfg_invalid_json_array": "Must be a valid JSON array", + "terminal_cfg_ap_note": "AP settings ({{ssid}}, {{password}}, {{disabled}}, {{staDisabled}}, {{offlineMode}}) have no dedicated commands; use the JSON config.", + "terminal_cfg_backend_title": "Backend", + "terminal_cfg_backend_desc": "OpenShock server and authentication.", + "terminal_cfg_domain": "Domain", + "terminal_cfg_domain_restart": "Setting the domain will restart the device.", + "terminal_cfg_auth_token": "Auth token", + "terminal_cfg_auth_token_placeholder": "Paste device token", + "terminal_cfg_hide": "Hide", + "terminal_cfg_show": "Show", + "terminal_cfg_serial_title": "Serial Input", + "terminal_cfg_echo": "Echo enabled", + "terminal_cfg_echo_desc": "Print typed characters back to the console.", + "terminal_cfg_advanced_title": "Advanced: full config", + "terminal_cfg_advanced_desc": "For fields without dedicated commands (captive portal, OTA, LAN, etc.), replace the entire config.", + "terminal_cfg_json_config": "JSON config", + "terminal_cfg_invalid_json": "Must be valid JSON", + "terminal_cfg_read_json": "Read current config as JSON", + "terminal_cfg_json_restart": "Applying a JSON config will restart the device.", + "terminal_cfg_raw_config": "Raw FlatBuffer config (base64)", + "terminal_cfg_invalid_base64": "Must be a valid base64 string", + "terminal_cfg_read_raw": "Read current config as base64", + "terminal_cfg_factory_reset": "Factory reset", + "terminal_cfg_factory_reset_desc": "Wipes the entire device configuration.", + "terminal_cfg_factory_reset_title": "Factory reset device?", + "terminal_cfg_factory_reset_action": "Wipe config", + "terminal_cfg_factory_reset_confirm": "This will erase all configuration on the device; WiFi networks, backend credentials, pins, and all other settings. The device will be reset to defaults.", + "terminal_cfg_read_failed_json_title": "Couldn't read the JSON config", + "terminal_cfg_read_failed_raw_title": "Couldn't read the raw config", + "terminal_cfg_read_failed_desc": "The device didn't respond after {{attempts}} attempts.", + "terminal_cfg_common_causes": "Common causes:", + "terminal_cfg_cause_busy": "The device is busy handling another command.", + "terminal_cfg_cause_disconnected": "The device disconnected or rebooted.", + "terminal_cfg_cause_unsupported": "The firmware version doesn't support this command.", + "common_status": "Status", + "common_version": "Version", + "common_created": "Created", + "common_create": "Create", + "common_done": "Done", + "common_enable": "Enable", + "common_disable": "Disable", + "common_are_you_sure": "Are you sure?", + "common_generating": "Generating...", + "hubs_title": "Hubs", + "hubs_subtitle": "Every hub registered to your account.", + "hubs_add": "Add Hub", + "hubs_load_failed": "Failed to load hubs.", + "hubs_empty_title": "No hubs yet", + "hubs_empty_desc": "A hub is the device that relays commands to your shockers. Add one to get started.", + "hubs_create_title": "Create hub", + "hubs_name_label": "Hub Name", + "hubs_name_placeholder": "My Hub", + "hub_toast_not_connected": "Not connected to the server", + "hub_toast_try_later": "Try again in a moment.", + "hub_reboot_title": "Reboot {{name}}?", + "hub_reboot_desc": "The hub will disconnect and restart. Any shockers paired to it stop responding until it comes back online.", + "hub_reboot": "Reboot", + "hub_hotspot_enable_title": "Enable Wi-Fi hotspot on {{name}}?", + "hub_hotspot_disable_title": "Disable Wi-Fi hotspot on {{name}}?", + "hub_hotspot_enable_desc": "The hub broadcasts its own setup network. It stays reachable on your Wi-Fi, but the hotspot is open to anyone in range until you turn it off.", + "hub_hotspot_disable_desc": "The setup hotspot shuts down. If the hub is not already on your Wi-Fi you will need physical access to set it up again.", + "hub_delete_desc": "You are about to delete hub {{name}}.", + "hub_delete_shockers": "This will also delete the following shockers:", + "hub_edit_title": "Edit hub", + "hub_edit_apply": "Apply", + "hub_pair_title_generate": "Generate pair code?", + "hub_pair_title_generated": "Pair code generated", + "hub_pair_title_paired": "Hub paired", + "hub_pair_consumed": "{{name}} consumed this pair code and is now paired.", + "hub_pair_used": "The code has been used and is no longer valid.", + "hub_pair_generated_for": "Pair code generated for {{name}}.", + "hub_copy_now": "The code below will not be accessible later, please copy it now and update clients with it.", + "hub_pair_generate_for": "You are about to generate a pair code for {{name}}.", + "hub_pair_valid_for": "It will be valid for 15 minutes after its creation.", + "hub_pair_one_active": "There is only one active pair code per hub, newly generated ones will override the older active ones.", + "hub_pair_complete": "Pairing complete", + "hub_pair_code_label": "Pair code:", + "hub_pair_copied_close": "Code has been copied, close", + "hub_pair_get": "Get Pair Code", + "hub_token_generated": "Token generated", + "hub_token_generated_for": "New token generated for {{name}}.", + "hub_token_regenerate_for": "You are about to regenerate the token for {{name}}.", + "hub_token_invalidate": "This action will invalidate the current token and disconnect clients using it.", + "hub_token_confirm": "Are you sure you want to do this?", + "hub_token_label": "New token:", + "hub_token_copied_close": "Token has been copied, close", + "hub_token_regenerate": "Regenerate Token", + "hub_menu_update": "Update", + "hub_menu_label": "Hub", + "hub_menu_hotspot_enable": "Enable Wi-Fi hotspot", + "hub_menu_hotspot_disable": "Disable Wi-Fi hotspot", + "hub_menu_pair": "Pair", + "hub_menu_estop": "Emergency Stop", + "hub_update_breadcrumb": "Update", + "hub_update_unknown_hub": "Unknown Hub", + "hub_update_unknown_task": "Unknown Task", + "hub_update_task_metadata": "Fetching Metadata", + "hub_update_task_preparing": "Preparing for Update", + "hub_update_task_flash_fs": "Flashing Filesystem", + "hub_update_task_verify_fs": "Verifying Filesystem", + "hub_update_task_flash_app": "Flashing Application", + "hub_update_task_bootable": "Marking Application Bootable", + "hub_update_task_rebooting": "Rebooting", + "hub_update_status_started": "Started", + "hub_update_status_running": "Running", + "hub_update_status_finished": "Finished", + "hub_update_status_error": "Error", + "hub_update_status_timeout": "Timeout", + "hub_update_confirm_title": "Confirm firmware update", + "hub_update_confirm_desc": "Update {{name}} to version {{version}}?", + "hub_update_unstable_warning": "This version may not be from the stable channel and could contain bugs.", + "hub_update_title": "Update {{name}}", + "hub_update_subtitle": "Manage firmware updates for this hub.", + "hub_update_status_title": "Hub Status", + "hub_update_firmware": "Firmware: {{version}}", + "hub_update_confirm": "Update", + "hub_update_success": "Update completed successfully", + "hub_update_rolled_back": "Device rolled back to previous version", + "hub_update_back": "Back to Hubs", + "hub_update_flash_again": "Flash Again", + "hub_update_card_title": "Firmware Update", + "hub_update_card_desc": "Select a firmware channel and version to install.", + "hub_update_to": "Update to {{version}}", + "hub_update_must_be_online": "Hub must be online to start an update.", + "hub_update_updating_to": "Updating to {{version}}...", + "hub_update_total": "Total", + "hub_update_task": "Task", + "hub_update_history": "Update History", + "hub_update_no_history": "No update history found for this hub.", + "hub_update_col_id": "ID", + "hub_update_col_started": "Started", + "hub_update_col_message": "Message", + "hub_update_loading": "Loading hub information...", + "hub_update_not_found": "Hub not found.", + "home_breadcrumb": "Home", + "home_welcome": "Welcome back", + "home_welcome_name": "Welcome back, {{name}}", + "home_subtitle": "Here's an overview of your OpenShock setup.", + "home_hubs_online": "{{count}} online", + "home_hub_status": "Hub Status", + "home_no_hubs": "No hubs", + "home_all_online": "All online", + "home_all_offline": "All offline", + "home_some_online": "{{online}}/{{total}} online", + "home_quick_links": "Quick Links", + "home_my_shockers": "My Shockers", + "home_my_shockers_desc": "Control your shockers", + "home_hubs_desc": "Manage your hubs", + "home_shared_desc": "Shockers shared with you", + "home_public_desc": "Manage share links", + "home_get_started": "Get Started", + "home_get_started_desc": "You don't have any hubs yet. Create a hub to connect your first device, then add shockers to it.", + "home_set_up_hub": "Set Up a Hub", + "home_first_shocker": "Add Your First Shocker", + "home_first_shocker_desc_one": "You have {{count}} hub set up. Add a shocker to start controlling it.", + "home_first_shocker_desc_other": "You have {{count}} hubs set up. Add a shocker to start controlling it.", + "home_go_to_shockers": "Go to Shockers", + "profile_title": "Profile", + "profile_coming_soon": "Profile is coming soon", + "profile_coming_soon_desc": "Your public profile is not available yet. Account details live under Settings.", + "common_retry": "Retry", + "common_never_used": "Never used", + "common_expires": "Expires {{time}}", + "common_search_placeholder": "Search...", + "common_unknown": "Unknown", + "settings_breadcrumb_account": "Account", + "account_subtitle": "Your sign-in details and account actions.", + "account_change_username": "Change Username", + "account_change_email": "Change Email", + "account_change_password": "Change Password", + "account_username_label": "Username", + "account_email_label": "Email", + "account_password_label": "Password", + "account_new_password_label": "New Password", + "account_confirm_password_label": "Confirm New Password", + "account_oauth_only": "Not available for OAuth-only accounts", + "account_oauth_no_password": "This account signs in via OAuth and has no password.", + "account_diagnostics": "Diagnostics", + "account_diagnostics_desc": "Help us fix crashes and slow API calls. Reports include the error message, stack trace and your IP. Off by default.", + "account_diagnostics_level": "Diagnostics level", + "account_telemetry_off": "Off", + "account_telemetry_off_desc": "Send nothing.", + "account_telemetry_errors": "Errors", + "account_telemetry_errors_desc": "Send browser error reports only.", + "account_telemetry_full": "Full", + "account_telemetry_full_desc": "Error reports plus traces of API calls (no page navigations).", + "account_toast_deactivated": "Account deactivated successfully", + "account_deactivate_title": "Deactivate account", + "account_deactivate_desc": "Are you sure you want to deactivate your account?", + "account_deactivate": "Deactivate Account", + "account_email_title": "Change email", + "account_email_desc": "Enter your new email address and confirm with your current password.", + "account_email_toast_sent": "Verification email sent to {{email}}. Click the link in that email to apply the change.", + "account_new_email": "New Email", + "account_current_password": "Current Password", + "account_password_title": "Change password", + "account_password_desc": "Enter your current password and choose a new one.", + "account_password_toast": "Password has been changed", + "account_username_title": "Change username", + "account_username_desc": "Enter a new username.", + "account_new_username": "New Username", + "account_username_toast": "Username changed successfully", + "tokens_subtitle": "API Tokens are used to authenticate with the OpenShock API.", + "tokens_generate": "Generate Token", + "tokens_toast_refreshed": "Tokens refreshed successfully", + "tokens_empty_title": "No API tokens", + "tokens_empty_desc": "Generate a token to authenticate with the OpenShock API.", + "tokens_created_on": "Created {{date}}", + "tokens_last_used": "Last used {{time}}", + "tokens_never_expires": "Never expires", + "tokens_load_failed": "Failed to load API tokens.", + "token_toast_edited": "Token edited successfully", + "token_name_required": "Name is required", + "token_name_too_long": "Name is too long", + "token_edit_title": "Edit API token", + "token_name_label": "Token Name", + "token_name_placeholder": "Token name...", + "token_permissions": "Permissions", + "token_perm_category_shockers": "Shockers", + "token_perm_category_devices": "Hubs", + "token_perm_category_usershares": "User Shares", + "token_perm_category_publicshares": "Public Shares", + "token_perm_use": "Use", + "token_perm_edit": "Edit", + "token_perm_pause": "Pause", + "token_perm_auth": "Authenticate", + "token_shocker_control": "Shocker Control", + "token_toast_paused": "Token paused", + "token_toast_resumed": "Token resumed", + "token_delete_title": "Delete API token", + "token_delete_desc": "Are you sure you want to delete {{name}}?", + "token_delete_permanent": "This action cannot be undone. This will permanently delete the token.", + "token_toast_deleted": "Token deleted successfully", + "token_resume": "Resume token", + "token_pause": "Pause token", + "token_mode_clamp_desc": "Clamp: requests outside the allowed range are capped to the nearest limit (the min or the max).", + "token_mode_lerp_desc": "Lerp: the full input range is linearly rescaled so it fits within your allowed min–max range.", + "token_paused_desc": "A paused token may not send shocker control messages.", + "token_intensity_range": "Intensity range", + "token_duration_range": "Duration range", + "token_new_breadcrumb": "New", + "token_redirect_not_allowed": "The provided redirect_uri is not allowed. Only loopback addresses or custom application schemes are permitted.", + "token_params_missing": "Required get parameters are missing. Make sure name, redirect_uri, and permissions are provided.", + "token_invalid_permissions": "Invalid permissions provided: {{list}}", + "token_toast_created": "Token created successfully", + "token_request_title": "API Token Request", + "token_access_granted": "Access granted", + "token_shared_redirecting": "The token has been created and shared with the application. Redirecting you back to {{uri}}.", + "token_not_redirected": "If you are not redirected automatically, use the button below.", + "token_finish": "Finish", + "token_generated_title": "API Token Generated", + "token_copy_now": "Please copy your API Token now, you will not be able to view it again later!", + "token_new_title": "New API Token", + "token_external_desc": "An external application is requesting access to your account. Review and adjust the permissions below before allowing access.", + "token_new_desc": "Configure and generate a new API token for your account.", + "token_external_requesting": "{{name}} is requesting an API Token. Your token will be shared with the application at {{uri}}.", + "token_allow": "Allow", + "token_generate": "Generate", + "token_deny": "Deny", + "sessions_subtitle": "Every active session on your account. Revoke any you do not recognize.", + "sessions_unknown_device": "Unknown device", + "sessions_toast_refreshed": "Sessions refreshed successfully", + "sessions_load_failed": "Failed to load sessions.", + "sessions_empty_title": "No active sessions", + "sessions_empty_desc": "Sessions appear here once you sign in from a browser or app.", + "sessions_last_seen": "Last seen {{time}}", + "sessions_signed_in": "Signed in {{time}}", + "session_toast_revoked": "Session revoked successfully", + "session_revoke_title": "Revoke session", + "session_revoke": "Revoke", + "session_revoke_desc": "Are you sure you want to revoke this session?", + "session_revoke_from": "Session logged in from {{ip}} using {{agent}}", + "connections_title": "OAuth Connections", + "connections_subtitle": "Link or unlink third-party accounts to sign in faster and keep your profile in sync.", + "connections_toast_linked": "Account linked.", + "connections_toast_cancelled": "Link flow cancelled.", + "connections_toast_failed": "Linking failed.", + "connections_toast_removed": "Connection removed", + "connections_refreshing": "Refreshing…", + "connections_link_new": "Link new provider", + "connections_empty_title": "No connections yet", + "connections_empty_desc": "Choose “Link new provider” above to connect available providers.", + "connections_unlink": "Unlink", + "connections_load_failed": "Failed to load OAuth connections.", + "connections_unlink_title": "Unlink {{name}}?", + "connections_unlink_title_generic": "Unlink this account?", + "connections_unlink_desc": "You'll no longer be able to sign in with this provider unless you link it again.", + "provider_starting": "Starting {{name}}...", + "provider_link": "Link {{name}}", + "audit_subtitle": "Security-relevant activity on your account. Review anything you do not recognize.", + "audit_col_time": "Time", + "audit_col_action": "Action", + "audit_col_details": "Details", + "audit_col_reason": "Reason", + "audit_col_ip": "IP address", + "audit_col_device": "Device", + "audit_action_login": "Signed in", + "audit_action_logout": "Signed out", + "audit_action_password_changed": "Password changed", + "audit_action_email_change_requested": "Email change requested", + "audit_action_email_changed": "Email changed", + "audit_action_username_changed": "Username changed", + "audit_action_api_token_created": "API token created", + "audit_action_api_token_deleted": "API token deleted", + "audit_action_oauth_connected": "Connection added", + "audit_action_oauth_disconnected": "Connection removed", + "audit_action_account_deactivated": "Account deactivated", + "audit_action_account_reactivated": "Account reactivated", + "audit_action_account_deleted": "Account deleted", + "audit_action_automation_token_created": "Automation token created", + "audit_action_automation_token_updated": "Automation token updated", + "audit_action_automation_token_rotated": "Automation token rotated", + "audit_action_automation_token_deleted": "Automation token deleted", + "audit_action_automation_token_used": "Automation token used", + "audit_meta_session": "Session {{id}}", + "audit_meta_changed": "{{old}} to {{new}}", + "audit_meta_email_requested": "Requested change to {{email}}", + "audit_meta_accounts_removed_one": "{{name}} ({{count}} account removed)", + "audit_meta_accounts_removed_other": "{{name}} ({{count}} accounts removed)", + "audit_meta_scheduled_deletion": "Scheduled for deletion", + "audit_meta_kept": "Kept for reactivation", + "common_view": "View", + "common_save": "Save", + "common_saving": "Saving...", + "common_back": "Back", + "common_shared_by": "Shared by", + "common_user_avatar": "User Avatar", + "common_toast_saved": "Changes saved successfully", + "pause_reason_shocker": "Paused at shocker level", + "pause_reason_shocker_user_share": "Paused at shocker and user share level", + "pause_reason_shocker_public_share": "Paused at shocker and public share level", + "pause_reason_user_share": "Paused at user share level", + "pause_reason_public_share": "Paused at public share level", + "public_shares_subtitle": "A link anyone can use, no account required.", + "public_shares_new": "New Share", + "public_share_never_expires": "Never expires", + "public_shares_empty_title": "No public shares yet", + "public_shares_empty_desc": "Create a link that anyone can use to control your shockers.", + "public_share_expired": "Expired", + "public_share_no_expiry": "No expiry", + "public_share_label": "Public Share", + "public_share_toast_created": "Created new public share", + "public_share_create_title": "Create public share", + "public_share_toast_deleted": "Deleted public share", + "public_share_delete_title": "Delete public share", + "public_share_delete_desc": "Are you sure you want to delete public share {{name}}?", + "public_share_edit_title": "Public Share: {{name}}", + "public_share_edit_subtitle": "Editing: changes apply when you save.", + "public_share_add_shocker": "Add Shocker", + "public_share_toast_added_one": "Added {{count}} shocker to share", + "public_share_toast_added_other": "Added {{count}} shockers to share", + "public_share_empty_shockers_title": "No shockers in this share", + "public_share_empty_shockers_desc": "Add a shocker and anyone with the link will be able to control it.", + "public_share_load_failed": "Error fetching public share details", + "public_share_paused_here": "Paused for this share", + "public_share_resume_shocker": "Resume shocker", + "public_share_pause_shocker": "Pause shocker", + "public_share_remove": "Remove from share", + "public_share_toast_removed": "Shocker removed from share", + "public_share_add_title": "Add shockers", + "public_share_add_desc": "Add shockers to this public share. You can set their limits once they are added.", + "public_share_add_placeholder": "Select shockers to share...", + "public_share_add_no_match": "No matching shockers", + "public_share_add_submit": "Add Shockers", + "public_share_view_loading": "Loading share details...", + "public_share_view_title": "Public Share Link", + "public_share_view_desc": "Enter as a guest or login with your OpenShock account", + "public_share_view_guest_name": "Guest Name", + "public_share_view_enter": "Enter", + "public_share_view_enter_guest": "Enter as Guest", + "public_share_login": "Login", + "perm_shock_on": "Shock enabled", + "perm_shock_off": "Shock disabled", + "perm_vibrate_on": "Vibrate enabled", + "perm_vibrate_off": "Vibrate disabled", + "perm_sound_on": "Sound enabled", + "perm_sound_off": "Sound disabled", + "perm_live_on": "Live enabled", + "perm_live_off": "Live disabled", + "perm_live_control": "Live Control", + "user_selector_avatar_of": "{{name}}'s avatar", + "user_selector_placeholder": "Enter user name", + "user_selector_aria": "Username to search", + "user_selector_search": "Search user", + "user_selector_found": "User found", + "common_remove": "Remove", + "user_shares_subtitle": "Direct permanent shares with other users.", + "user_shares_toast_invited": "Sent a shocker invite to {{name}}", + "user_shares_redeem": "Redeem Code", + "user_shares_new": "New Share", + "user_shares_tab_shares": "Shares", + "user_shares_tab_incoming": "Shared with Me", + "user_shares_tab_invites": "Invites", + "share_code_create_title": "New share code", + "share_code_create_desc": "Create a Share Code or Invite", + "share_code_shocker_placeholder": "Select shockers to share...", + "share_code_no_match": "No matching shockers", + "share_code_send_invite": "Send Share Invite", + "share_code_create": "Create Share Code", + "share_code_created_title": "Share code generated", + "share_code_created_desc": "Please copy share code or code link!", + "share_code_redeem_title": "Redeem share code", + "share_code_redeem_desc": "Enter the share code to redeem", + "share_code_redeem_placeholder": "Enter share code", + "share_code_redeemed": "Redeemed successfully!", + "share_code_shared_shockers": "Shared shockers", + "share_code_redeeming": "Redeeming...", + "share_code_redeem": "Redeem", + "incoming_shares_empty_title": "Nothing shared with you", + "incoming_shares_empty_desc": "No one has shared a shocker with you yet.", + "incoming_share_toast_removed": "Removed share for {{name}}", + "incoming_share_remove_title": "Remove Share", + "incoming_share_remove_desc": "Are you sure you want to remove the share for {{name}}?", + "incoming_share_toast_removed_shocker": "Removed {{shocker}} shared by {{name}}", + "incoming_share_remove_shocker_title": "Remove this shared shocker?", + "incoming_share_remove_shocker_desc": "Are you sure you want to remove the shocker share {{shocker}} by {{name}}?", + "incoming_share_manage_from": "Manage shares from", + "share_remove": "Remove share", + "invites_empty_title": "No invites yet", + "invites_empty_desc": "You have no incoming or outgoing share invites.", + "invites_outgoing": "Outgoing", + "invites_outgoing_empty_title": "No outgoing invites", + "invites_outgoing_empty_desc": "You have no outgoing share invites.", + "invites_incoming": "Incoming", + "invites_incoming_empty_title": "No incoming invites", + "invites_incoming_empty_desc": "You have no incoming share invites.", + "invite_toast_accepted": "Accepted share invite from {{name}}", + "invite_toast_declined": "Declined share invite from {{name}}", + "invite_deny_title": "Deny Invite", + "invite_deny_label": "Deny Invite", + "invite_deny": "Deny", + "invite_deny_desc": "Are you sure you want to deny the invite from {{name}}?", + "invite_accept": "Accept Invite", + "invite_toast_cancelled_for": "Cancelled invite for {{name}} ({{id}})", + "invite_toast_cancelled": "Cancelled invite {{id}}", + "invite_cancel_title": "Cancel Invite", + "invite_cancel": "Cancel", + "invite_cancel_for_desc": "Are you sure you want to cancel the invite for {{name}}?", + "invite_cancel_code_desc": "Are you sure you want to cancel the invite with code {{code}}?", + "invite_cancel_outstanding": "Cancel Outstanding Invite", + "outgoing_shares_empty_title": "No shared shockers", + "outgoing_shares_empty_desc": "You haven't shared any shockers with other users yet.", + "outgoing_share_toast_removed": "Removed shocker share {{name}}", + "outgoing_share_remove_title": "Stop sharing this shocker?", + "outgoing_share_editing_for": "Editing shares for", + "outgoing_share_limits": "Limits & Permissions", + "outgoing_share_same": "Same restrictions on every shocker", + "outgoing_share_per_desc": "Tune restrictions per shocker", + "outgoing_share_all": "All", + "outgoing_share_per": "Per shocker", + "outgoing_share_remove_desc": "Are you sure you want to stop sharing {{shocker}} with {{name}}?", + "report_breadcrumb": "Report API Tokens", + "report_toast_clipboard_failed": "Failed to read clipboard: {{error}}", + "report_title": "Report Leaked API Tokens", + "report_paste": "Paste from clipboard", + "report_warning": "This form is only for reporting accidentally leaked API tokens.", + "report_abuse_warning": "Intentional abuse will result in bans or severe endpoint restrictions.", + "report_detected": "Detected Tokens", + "report_invalid": "One or more tokens appear to be invalid. Please check for formatting issues.", + "report_acknowledge": "I confirm I understand what this feature is for and accept responsibility.", + "report_submit": "Submit Report", + "turnstile_disabled": "Turnstile disabled", + "common_internal_error": "Internal error", + "resend_toast_sent": "Activation email sent. Check your inbox and spam folder.", + "resend_toast_throttled": "Too many activation emails have been requested. Please try again later.", + "resend_toast_unavailable": "No activation email can be resent from this browser. If your account isn't activated yet, logging in sends a new link.", + "resend_button": "Didn't get the email? Resend", + "expiration_label": "Expiration", + "expiration_never": "Never", + "expiration_custom": "Custom", + "expiration_days_one": "{{count}} Day", + "expiration_days_other": "{{count}} Days", + "expiration_required": "Expire date is required", + "expiration_never_desc": "This will never expire", + "expiration_expires_at": "Expires {{time}} ({{date}})", + "date_picker_placeholder": "Pick a date", + "telemetry_toast_title": "Help improve OpenShock?", + "telemetry_toast_desc": "Send diagnostics to help us fix crashes and slow API calls. Reports include the error message, stack trace and your IP. You can change this any time in Account settings.", + "telemetry_toast_no": "No thanks", + "telemetry_toast_errors": "Errors only", + "telemetry_toast_full": "Full", + "table_show_details": "Show details", + "table_hide_details": "Hide details", + "table_no_results": "No results.", + "table_sort_asc": "Sort by {{name}}, ascending", + "table_sort_desc": "Sort by {{name}}, descending", + "table_sort_none": "Sort by {{name}}, unsorted", + "cell_na": "N/A", + "cell_not_applicable": "Not applicable", + "cell_invalid": "Invalid", + "cell_unavailable": "Unavailable", + "cell_none": "None", + "oauth_login_with": "Login with {{provider}}", + "oauth_signup_with": "Signup with {{provider}}", + "signalr_connect_failed": "Failed to connect to server!", + "signalr_disconnect_failed": "Encountered error while disconnecting from server!", + "signalr_invalid_update": "Received invalid update from server!", + "signalr_invalid_log": "Received invalid log data from server!", + "signalr_invalid_ota": "Received invalid firmware update data from server!", + "ota_toast_failed": "Hub firmware update failed: {{message}}", + "ota_toast_succeeded": "Hub firmware update completed successfully!", + "ota_toast_rolled_back": "Hub firmware rolled back to previous version", + "lcg_connect_failed": "Failed to connect to live control gateway", + "terminal_toast_bootloader_failed": "Failed to enter bootloader: {{error}}", + "terminal_toast_app_mode_failed": "Failed to enter application mode: {{error}}", + "problem_account_account_not_activated_title": "Account not activated", + "problem_account_account_not_activated_desc": "Check your inbox for the activation email.", + "problem_account_activation_not_found_title": "Activation link is invalid", + "problem_account_activation_not_found_desc": "The link may have expired or already been used.", + "problem_account_activation_resend_too_many_title": "Too many activation emails requested", + "problem_account_activation_resend_too_many_desc": "Please wait a while before trying again.", + "problem_account_activation_resend_unavailable_title": "Cannot resend activation email", + "problem_account_activation_resend_unavailable_desc": "Log in again to request a new activation link.", + "problem_account_deactivate_already_deactivated_title": "Account is already deactivated", + "problem_account_deactivate_denied_privileged_title": "Privileged accounts cannot be deactivated", + "problem_account_deactivate_unauthorized_title": "You are not allowed to do this", + "problem_account_deactivated_title": "This account has been deactivated", + "problem_account_email_already_in_use_title": "That email address is already in use", + "problem_account_email_invalid_title": "That email address is not valid", + "problem_account_email_taken_title": "That email address is already in use", + "problem_account_email_too_many_requests_title": "Too many email change requests", + "problem_account_email_too_many_requests_desc": "Please wait a while before trying again.", + "problem_account_email_unchanged_title": "That is already your email address", + "problem_account_email_verify_not_found_title": "Verification link is invalid", + "problem_account_email_verify_not_found_desc": "The link may have expired or already been used.", + "problem_account_o_auth_only_title": "This account has no password", + "problem_account_o_auth_only_desc": "Sign in with the provider you signed up with.", + "problem_account_password_not_set_title": "No password set", + "problem_account_password_not_set_desc": "This account signs in through an external provider.", + "problem_account_password_old_password_invalid_title": "Current password is incorrect", + "problem_account_username_invalid_title": "That username is not allowed", + "problem_account_username_recently_changed_title": "Username changed too recently", + "problem_account_username_recently_changed_desc": "You can change your username once every 7 days.", + "problem_account_username_taken_title": "That username is already taken", + "problem_admin_user_deactivated_title": "This user is deactivated", + "problem_admin_user_not_activated_title": "This user has not been activated yet", + "problem_api_token_can_only_delete_self_title": "An API token can only delete itself", + "problem_api_token_not_found_title": "API token not found", + "problem_api_token_paused_title": "This API token is paused", + "problem_assign_lcg_bad_schema_version_title": "Unsupported hub protocol version", + "problem_assign_lcg_bad_schema_version_desc": "Update the hub firmware to connect.", + "problem_assign_lcg_no_lcg_available_title": "No gateway available", + "problem_assign_lcg_no_lcg_available_desc": "No live control gateway is available right now. Please try again later.", + "problem_authentication_account_deactivated_title": "This account has been deactivated", + "problem_authentication_account_not_activated_title": "This account has not been activated", + "problem_authentication_cookie_missing_or_invalid_title": "You are not logged in", + "problem_authentication_cookie_missing_or_invalid_desc": "Your session may have expired. Please log in again.", + "problem_authentication_header_missing_or_invalid_title": "Invalid API token", + "problem_authentication_session_invalid_title": "Session expired", + "problem_authentication_session_invalid_desc": "Please log in again.", + "problem_authentication_token_invalid_title": "Invalid API token", + "problem_authentication_unknown_error_title": "Authentication failed", + "problem_authorization_policy_not_met_title": "You do not have permission to do this", + "problem_authorization_token_only_title": "This action requires an API token", + "problem_authorization_token_permission_missing_title": "This API token is missing a required permission", + "problem_authorization_unknown_error_title": "Authorization failed", + "problem_authorization_user_session_only_title": "This action requires a logged-in session", + "problem_automation_token_not_allowed_for_account_title": "Automation tokens cannot be used with privileged accounts", + "problem_configuration_already_exists_title": "A configuration entry with that name already exists", + "problem_configuration_invalid_name_format_title": "Invalid configuration name", + "problem_configuration_invalid_name_format_desc": "Only A to Z and underscores are allowed.", + "problem_configuration_invalid_value_format_title": "Value does not match the configuration type", + "problem_configuration_not_found_title": "Configuration entry not found", + "problem_control_stats_invalid_range_title": "The from date must not be after the to date", + "problem_control_stats_invalid_time_zone_title": "Unknown time zone", + "problem_control_stats_missing_capability_title": "Control statistics are not available on this server", + "problem_device_not_found_title": "Hub not found", + "problem_device_not_online_title": "Hub is offline", + "problem_device_too_many_hubs_title": "You have reached the maximum number of hubs", + "problem_device_too_many_shockers_title": "This hub has reached its maximum number of shockers", + "problem_endpoint_retired_title": "This feature is no longer available", + "problem_expression_error_title": "Invalid filter expression", + "problem_internal_server_error_title": "Something went wrong on our end", + "problem_login_invalid_credentials_title": "Invalid username or password", + "problem_login_invalid_domain_title": "Logging in from this address is not allowed", + "problem_o_auth_connection_already_exists_title": "Your account is already connected to this provider", + "problem_o_auth_connection_already_linked_title": "This external account is already linked to another user", + "problem_o_auth_flow_anonymous_only_title": "You are already signed in", + "problem_o_auth_flow_mismatch_title": "Sign-in attempt does not match", + "problem_o_auth_flow_mismatch_desc": "Please start over.", + "problem_o_auth_flow_missing_data_title": "The provider did not return your account details", + "problem_o_auth_flow_missing_data_desc": "Please try again.", + "problem_o_auth_flow_not_found_title": "Sign-in attempt expired", + "problem_o_auth_flow_not_found_desc": "Please start over.", + "problem_o_auth_flow_unsupported_title": "Unsupported sign-in flow", + "problem_o_auth_internal_error_title": "Something went wrong during sign-in", + "problem_o_auth_internal_error_desc": "Please try again in a moment.", + "problem_o_auth_link_authenticated_user_only_title": "You must be signed in to link an external account", + "problem_o_auth_provider_mismatch_title": "Sign-in attempt does not match the provider", + "problem_o_auth_provider_mismatch_desc": "Please start over.", + "problem_o_auth_provider_unsupported_title": "This sign-in provider is not supported", + "problem_pair_code_not_found_title": "Pair code not found", + "problem_password_reset_not_found_title": "Password reset link is invalid", + "problem_password_reset_not_found_desc": "The link may have expired or already been used.", + "problem_session_not_found_title": "Session not found", + "problem_share_get_no_shares_title": "You have no shares with this user", + "problem_share_request_create_cannot_share_with_self_title": "You cannot share with yourself", + "problem_share_request_create_shocker_not_found_title": "One or more shockers were not found", + "problem_share_request_create_shocker_not_found_desc": "They may have been removed or do not belong to you.", + "problem_share_request_not_found_title": "Share invite not found", + "problem_share_user_not_found_title": "Share not found", + "problem_share_code_already_linked_title": "Shocker is already linked to your account", + "problem_share_code_cant_link_own_share_code_title": "You cannot redeem your own share code", + "problem_share_code_not_found_title": "Share code not found", + "problem_share_link_expiry_date_in_past_title": "Expiry date cannot be in the past", + "problem_share_link_not_found_title": "Public share not found", + "problem_share_link_shocker_already_in_share_link_title": "Shocker is already in this public share", + "problem_share_link_shocker_not_in_share_link_title": "Shocker is not in this public share", + "problem_shocker_control_no_permission_title": "You do not have permission to control this shocker", + "problem_shocker_control_not_found_title": "Shocker not found", + "problem_shocker_control_paused_title": "Shocker is paused", + "problem_shocker_not_found_title": "Shocker not found", + "problem_signup_registration_disabled_title": "Registration is currently disabled", + "problem_signup_username_or_email_exists_title": "That username or email is already in use", + "problem_turnstile_invalid_title": "Verification failed", + "problem_turnstile_invalid_desc": "Please complete the challenge again and retry.", + "problem_user_not_found_title": "User not found", + "problem_user_privileged_delete_denied_title": "Privileged users cannot be deleted", + "problem_validation_error_title": "Some fields are invalid", + "problem_webhook_not_found_title": "Webhook not found", + "problem_webhook_unsupported_title": "Only Discord webhooks are supported", + "problem_webhook_unsupported_desc": "Use a discord.com URL, not canary or ptb.", + "error_too_many_requests": "Too many requests", + "error_retry_after_one": "Try again in {{count}} second.", + "error_retry_after_other": "Try again in {{count}} seconds.", + "error_unexpected_response": "Unexpected server response", + "error_internal": "Internal error occurred", + "error_network": "Network error occurred", + "dev_banner": "This is the OpenShock DEVELOPMENT environment. No data is saved, and it is regularly overwritten by production data.", + "firmware_channel_bugs_warning": "This channel might contain bugs." +} From f017f1113bbe0ba506fcc3cbc71ca2ee9efefa9a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Luc=20=E2=99=A5?= Date: Thu, 12 Nov 2026 17:43:40 +0100 Subject: [PATCH 27/27] New translations en.json (Vietnamese) [ci skip] --- messages/vi.json | 1055 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 1055 insertions(+) create mode 100644 messages/vi.json diff --git a/messages/vi.json b/messages/vi.json new file mode 100644 index 00000000..ef4df56c --- /dev/null +++ b/messages/vi.json @@ -0,0 +1,1055 @@ +{ + "landing_tagline": "The go-to platform for safe, reliable, real low-latency remote shocking.", + "landing_section_label": "Home", + "landing_hubs_online": "Hubs online right now: ", + "landing_learn_more": "Learn More", + "landing_wiki": "Wiki", + "landing_meta_description": "Welcome to OpenShock, a free and open-source ecosystem to control various shock collars over the internet.", + "instance_meta_description": "Welcome to {{siteName}}, an independent instance of OpenShock, a free and open-source ecosystem to control various shock collars over the internet.", + "header_sidebar_toggle": "Toggle Sidebar", + "header_avatar_alt": "{{name}}'s avatar", + "header_menu_profile": "Profile", + "header_menu_settings": "Settings", + "header_menu_logout": "Logout", + "header_login": "Login", + "header_signup": "Sign Up", + "header_github_title": "OpenShock on GitHub", + "header_discord_title": "Community Discord", + "footer_made_with": "Made with by the OpenShock Team", + "footer_connection_status_label": "Server connection status", + "footer_signalr_state": "SignalR State", + "footer_frontend_version": "Frontend Version", + "footer_frontend_commit_title": "Commit {{commit}}", + "footer_backend_version": "Backend Version", + "footer_backend_commit_title": "Commit {{commit}}", + "footer_language_label": "Language", + "sidebar_home_link_label": "OpenShock home", + "sidebar_group_general": "General", + "sidebar_home": "Home", + "sidebar_shockers": "Shockers", + "sidebar_shared_shockers": "Shared Shockers", + "sidebar_hubs": "Hubs", + "sidebar_user_shares": "User Shares", + "sidebar_public_shares": "Public Shares", + "sidebar_serial_terminal": "Serial Terminal", + "sidebar_group_admin": "Admin", + "sidebar_admin_monitoring": "Monitoring", + "sidebar_admin_online_hubs": "Online Hubs", + "sidebar_admin_online_gateways": "Online Gateways", + "sidebar_admin_management": "Management", + "sidebar_admin_users": "Users", + "sidebar_admin_blacklists": "Blacklists", + "sidebar_admin_webhooks": "Webhooks", + "sidebar_admin_mail": "Mail", + "sidebar_admin_automation_tokens": "Automation Tokens", + "sidebar_admin_configuration": "Configuration", + "sidebar_group_settings": "Settings", + "sidebar_settings_api_tokens": "API Tokens", + "sidebar_settings_sessions": "Sessions", + "sidebar_settings_audit_log": "Audit Log", + "sidebar_settings_connections": "Connections", + "sidebar_settings_account": "Account Settings", + "error_meta_title": "Service Unavailable", + "error_meta_description": "OpenShock is currently unavailable", + "error_meta_logo_alt": "OpenShock Logo", + "error_fallback_message": "Something went wrong.", + "error_not_found_message": "Page not found", + "error_not_found_description": "The page you're looking for doesn't exist.", + "error_unexpected_description": "An unexpected error occurred.", + "error_go_back": "Go back", + "auth_layout_logo_alt": "OpenShock Logo", + "auth_layout_invalid_redirect_removed": "An invalid redirect URL was removed for your safety.", + "auth_activate_breadcrumb": "Activate Account", + "auth_activate_title": "Activate Account", + "auth_activate_activating": "Activating your account...", + "auth_activate_success": "Your account has been activated", + "auth_activate_failed": "This activation link is invalid or has expired", + "auth_activate_missing_token": "Missing activation token", + "auth_activate_continue": "Continue to login", + "auth_activate_toast_success": "Account activated", + "auth_forgot_breadcrumb": "Forgot Password", + "auth_forgot_title": "Forgot Password", + "auth_forgot_description": "Enter your email to reset your password", + "auth_forgot_email_label": "Email", + "auth_forgot_email_placeholder": "Email", + "auth_forgot_submit": "Reset Password", + "auth_forgot_signin_prompt": "Remember your password? Sign in", + "auth_forgot_mail_disabled": "Password resets are unavailable on this instance because it has no mail provider configured. Please contact your administrator for help recovering your account.", + "auth_forgot_toast_sent": "Reset password request has been sent to the given email", + "auth_login_breadcrumb": "Login", + "auth_login_title": "Welcome back", + "auth_login_loading_methods": "Loading available login methods", + "auth_login_choose_method": "Login with one of these methods", + "auth_login_with_account": "Login with your OpenShock Account", + "auth_login_activation_after_signup": "Your account has been created. We've sent an activation link to your email address. Check your inbox and spam folder.", + "auth_login_activation_pending": "Your account isn't activated yet. We've sent an activation link to your email address. Check your inbox and spam folder. If nothing arrives, try logging in again later to get a new link.", + "auth_login_oauth_only": "This account has no password. Sign in with the provider you signed up with.", + "auth_login_oauth_only_with_buttons": "This account has no password. Sign in with the provider you signed up with using the buttons above.", + "auth_login_or_continue_with": "Or continue with", + "auth_login_username_label": "Username or Email", + "auth_login_password_label": "Password", + "auth_login_submit": "Login", + "auth_login_signup_prompt": "Don't have an account? Sign up", + "auth_login_legal": "By clicking Login, you agree to our Terms of Service and Privacy Policy.", + "auth_oauth_create_breadcrumb": "Sign Up With {{provider}}", + "auth_oauth_create_title": "Sign Up With {{provider}}", + "auth_oauth_create_description": "Complete your account details", + "auth_oauth_create_username_label": "Username", + "auth_oauth_create_username_placeholder": "Username", + "auth_oauth_create_email_label": "Email", + "auth_oauth_create_email_placeholder": "Email", + "auth_oauth_create_submit": "Sign Up", + "auth_oauth_create_legal": "By clicking Sign Up, you agree to our Terms of Service and Privacy Policy.", + "auth_oauth_error_breadcrumb": "Authentication Error", + "auth_oauth_error_title": "Authentication Error", + "auth_oauth_error_back": "Back to login", + "auth_reset_breadcrumb": "Reset Password", + "auth_reset_title": "Reset Password", + "auth_reset_checking": "Verifying reset link...", + "auth_reset_choose_password": "Choose a new password for your account", + "auth_reset_invalid": "This reset link is invalid or has expired", + "auth_reset_password_label": "New Password", + "auth_reset_password_placeholder": "New Password", + "auth_reset_confirm_label": "Confirm New Password", + "auth_reset_confirm_placeholder": "Confirm New Password", + "auth_reset_submit": "Reset Password", + "auth_reset_request_new": "Request a new reset link", + "auth_reset_toast_success": "Password has been reset", + "auth_signup_breadcrumb": "Sign Up", + "auth_signup_toast_created_mail": "Account created successfully. Please check your email to verify your account.", + "auth_signup_toast_created_no_mail": "Account created successfully. You can log in now.", + "auth_signup_dialog_title": "Welcome! Thank you for signing up! ❤️", + "auth_signup_dialog_created_mail": "Your account has been created. 🎉 Please check your email to verify your account.", + "auth_signup_dialog_verify_then_login": "After verifying your email, you can log in to your account.", + "auth_signup_dialog_created_no_mail": "Your account has been created and is ready to use. 🎉", + "auth_signup_dialog_login_now": "You can log in to your account now.", + "auth_signup_title": "Create your account", + "auth_signup_loading_methods": "Loading available sign-up methods", + "auth_signup_using_email": "Signing up using email", + "auth_signup_choose_method": "Choose your preferred sign-up method", + "auth_signup_back": "Back", + "auth_signup_username_label": "Username", + "auth_signup_username_placeholder": "John OpenShock", + "auth_signup_email_label": "Email", + "auth_signup_email_placeholder": "john@example.com", + "auth_signup_password_label": "Password", + "auth_signup_password_placeholder": "Password", + "auth_signup_confirm_label": "Confirm Password", + "auth_signup_confirm_placeholder": "Confirm Password", + "auth_signup_submit": "Create Account", + "auth_signup_signin_prompt": "Already have an account? Sign in", + "auth_signup_or": "Or", + "auth_signup_with_email": "Signup with Email", + "auth_signup_legal": "By clicking Create Account, you agree to our Terms of Service and Privacy Policy.", + "auth_verify_breadcrumb": "Verify Email", + "auth_verify_title": "Verify Email", + "auth_verify_verifying": "Verifying your email address...", + "auth_verify_success": "Your email has been verified", + "auth_verify_failed": "This verification link is invalid or has expired", + "auth_verify_missing_token": "Missing verification token", + "auth_verify_continue": "Continue to login", + "auth_verify_toast_success": "Email verified", + "common_cancel": "Cancel", + "common_delete": "Delete", + "common_edit": "Edit", + "common_share": "Share", + "common_copy_id": "Copy ID", + "common_id_copied": "ID copied to clipboard", + "common_open_menu": "Open menu", + "common_refresh": "Refresh", + "common_settings": "Settings", + "common_clear": "Clear", + "common_online": "Online", + "common_offline": "Offline", + "common_paused": "Paused", + "common_resume": "Resume", + "common_resuming": "Resuming...", + "common_coming_soon": "(Coming soon)", + "common_save_changes": "Save Changes", + "common_danger_zone": "Danger Zone", + "common_name": "Name", + "control_intensity": "Intensity", + "control_duration": "Duration", + "control_max_intensity": "Max Intensity", + "control_max_duration": "Max Duration", + "control_vibration": "Vibration", + "control_value": "Value", + "control_live_intensity": "Live intensity", + "control_type_stop": "Stop", + "control_type_shock": "Shock", + "control_type_vibrate": "Vibrate", + "control_type_sound": "Sound", + "live_tooltip_active": "Live via {{gateway}} ({{country}}), {{latency}}ms", + "live_tooltip_connecting": "Connecting...", + "live_tooltip_connect": "Connect to Live Control", + "live_tooltip_hub_start": "Ctrl+click to start the whole hub", + "live_tooltip_hub_stop": "Ctrl+click to stop the whole hub", + "pause_resume_shocker": "Resume shocker", + "pause_pause_shocker": "Pause shocker", + "pause_resume_all": "Resume all shockers", + "pause_pause_all": "Pause all shockers", + "shocker_label": "Shocker", + "shocker_hub": "Hub", + "shocker_select_hub": "Select hub", + "shocker_rf_id": "RF ID", + "shocker_rf_id_invalid": "RF ID must be a whole number between {{min}} and {{max}}.", + "shocker_model": "Model", + "shocker_select_model": "Select model", + "shocker_name_placeholder": "Shocker name", + "shocker_menu_view_logs": "View Logs", + "shocker_delete_title": "Delete Shocker", + "shocker_delete_desc": "Are you sure you want to delete \"{{name}}\"? This action cannot be undone.", + "shocker_toast_deleted": "Shocker \"{{name}}\" deleted", + "shocker_toast_paused": "Shocker paused", + "shocker_toast_resumed": "Shocker resumed", + "shocker_add_desc": "Register a new shocker to one of your hubs.", + "shocker_add_name_placeholder": "My Shocker", + "shockers_title": "Shockers", + "shockers_subtitle": "Every shocker paired to your hubs.", + "shockers_loading": "Loading shockers...", + "shockers_toast_refreshed": "Shockers refreshed", + "shockers_toast_need_hub": "You need to create a hub before adding shockers.", + "shockers_toast_added": "Shocker added", + "shockers_unknown_module": "Unknown module type", + "shockers_add": "Add Shocker", + "shockers_view_mode": "View mode", + "shockers_mode_classic": "Classic", + "shockers_mode_rich": "Rich", + "shockers_mode_simple": "Simple", + "shockers_mode_map": "Map", + "shockers_group_by_hub": "Group by Hub", + "shockers_global_limits": "Global Limits", + "shockers_logs_label": "Logs", + "shockers_empty_title": "No shockers yet", + "shockers_empty_no_hubs": "Create a hub first, then add shockers to it.", + "shockers_empty_has_hubs": "Add a shocker to one of your hubs to get started.", + "shockers_create_hub": "Create a Hub", + "shockers_count_one": "{{count}} shocker", + "shockers_count_other": "{{count}} shockers", + "shared_shockers_title": "Shared Shockers", + "shared_shockers_subtitle": "Shockers other users have shared with you.", + "shared_shockers_empty_title": "No shockers have been shared with you yet.", + "shared_shockers_empty_desc": "When someone shares their shockers with you, they'll appear here.", + "shocker_logs_title": "Shocker Logs", + "shocker_logs_subtitle": "Every control command sent to your shockers.", + "shocker_logs_live_title": "New logs appear in real time", + "shocker_logs_paused_title": "Live updates pause when sorting or viewing a page other than the first", + "shocker_logs_live": "Live", + "shocker_logs_col_time": "Time", + "shocker_logs_col_type": "Type", + "shocker_logs_col_by": "By", + "shocker_logs_filter_label": "Filter by shocker", + "shocker_logs_filter_placeholder": "Search shockers...", + "shocker_logs_filter_all": "All shockers", + "shocker_logs_filter_none": "No matching shockers", + "shocker_edit_title": "Edit Shocker", + "shocker_edit_subtitle": "Change this shocker's details or remove it.", + "shocker_edit_back": "Back to Shockers", + "shocker_edit_load_failed": "Failed to load shocker.", + "shocker_edit_loading": "Loading shocker...", + "shocker_edit_details_title": "Shocker Details", + "shocker_edit_details_desc": "Update the name, RF ID, and model for this shocker.", + "shocker_edit_pause_state": "Pause State", + "shocker_edit_is_paused": "Shocker is paused", + "shocker_edit_is_active": "Shocker is active", + "shocker_edit_toast_updated": "Shocker updated", + "shocker_edit_delete_desc": "Permanently delete this shocker. This action cannot be undone.", + "common_close": "Close", + "common_continue": "Continue", + "common_loading": "Loading...", + "common_previous": "Previous", + "common_next": "Next", + "common_steps": "Steps", + "common_step_label": "Step {{number}}: {{title}}", + "common_copy": "Copy", + "common_copied": "Copied", + "common_never": "Never", + "common_error": "Error: {{message}}", + "terminal_title": "Serial Terminal", + "terminal_connecting": "Connecting...", + "terminal_help_button": "I'm having trouble, help?", + "terminal_back_to_modes": "Back to mode picker", + "terminal_mode_configure": "Configure Device", + "terminal_mode_configure_desc": "Configure WiFi, authentication, and more. Includes an interactive serial console.", + "terminal_mode_flash": "Flash Firmware", + "terminal_mode_flash_desc": "Install or update firmware on a connected device.", + "terminal_mode_raw": "Serial Monitor", + "terminal_mode_raw_desc": "Just the console. Read device logs and send commands.", + "terminal_step_channel": "Select Channel", + "terminal_step_board": "Select Board", + "terminal_go_to_step": "Go to step {{number}}: {{title}}", + "terminal_erase": "Erase before flashing", + "terminal_erase_desc": "Clears all data on the device including existing configs", + "terminal_unsupported": "Your browser does not support this feature.", + "terminal_update_browser": "Please update your browser to the latest version.", + "terminal_use_browsers": "Please use one of the following browsers:", + "terminal_connect_failed_bootloader": "Could not enter bootloader mode", + "terminal_connect_failed": "Device connection failed", + "terminal_connect_failed_desc": "We couldn't establish a serial connection with the device.", + "terminal_quick_tries": "Quick things to try:", + "terminal_try_replug": "Unplug and replug the device.", + "terminal_try_cable": "Try a different USB cable or port.", + "terminal_try_driver": "Make sure the serial driver is installed.", + "terminal_open_troubleshooter": "Open troubleshooter", + "terminal_log_reset_no_device": "Host-side error during reset: no device!", + "terminal_log_reset_error": "Host-side error during reset: {{error}}", + "terminal_log_send_no_device": "Couldn't send: no device!", + "terminal_log_send_error": "Couldn't send: {{error}}", + "terminal_log_firmware_disconnected": "Firmware disconnected: {{error}}", + "terminal_log_erase_failed": "Failed to erase flash: {{error}}", + "terminal_log_hard_reset_failed": "Failed to hard reset: {{error}}", + "terminal_log_flash_complete": "Flash complete", + "terminal_log_flash_failed": "Failed to flash: {{error}}", + "terminal_log_command_failed": "Failed to write application command: {{error}}", + "terminal_help_title": "Troubleshooter", + "terminal_help_desc": "Work through these steps in order. Each one rules out a common cause.", + "terminal_help_step_cable": "USB cable", + "terminal_help_step_port": "USB port", + "terminal_help_step_driver": "Install driver", + "terminal_help_step_manual": "Manual driver update", + "terminal_help_step_discord": "Ask on Discord", + "terminal_help_cable_body": "Many USB-C and micro-USB cables are charge-only and don't carry data. Swap to a known-good data cable (one you've used to transfer files or connect other devices) and reconnect the hub.", + "terminal_help_port_body": "Plug the device directly into a USB port on your computer. Avoid USB hubs, docking stations, and front-panel ports if possible; these are common sources of power and signal issues. If you're on a desktop, try a port on the back of the machine.", + "terminal_help_driver_download": "Download the CP210x driver:", + "terminal_help_driver_extract": "Extract the contents of the zip file to a folder on your computer.", + "terminal_help_driver_run": "Open the folder and run {{installer}}. Follow the prompts to install.", + "terminal_help_driver_reconnect": "Reconnect the device.", + "terminal_help_manual_intro": "If the driver installer ran but the device still doesn't show up:", + "terminal_help_manual_open": "Open Device Manager (press Win + X and select Device Manager).", + "terminal_help_manual_ports": "Under Ports (COM & LPT), look for an entry like:", + "terminal_help_manual_missing": "If it's missing, the device isn't being detected by Windows at all; revisit the cable and port steps.", + "terminal_help_manual_update": "Right-click the device and pick Update Driver.", + "terminal_help_manual_browse": "Choose Browse my computer for drivers and select the folder you extracted the driver zip into. Make sure Include subfolders is checked.", + "terminal_help_manual_success": "On success, the entry should now read {{deviceName}}.", + "terminal_help_discord_intro": "Still stuck after all of the above? Hop into our Discord server and ask in the {{channel}} channel. Please include:", + "terminal_help_discord_os": "your operating system and browser", + "terminal_help_discord_device": "the device you're using (board model, where you got it)", + "terminal_help_discord_tried": "what you've already tried from the previous steps", + "terminal_help_discord_errors": "any error messages or relevant terminal output", + "terminal_help_discord_join": "Join our Discord server", + "terminal_risk_title": "⚠️ UNSTABLE FIRMWARE", + "terminal_risk_intro": "You are about to flash experimental firmware that is known to be unstable.", + "terminal_risk_brick": "This may permanently brick your device, require manual recovery, or render it unusable.", + "terminal_risk_no_support": "We will NOT provide support for issues caused by this firmware.", + "terminal_risk_acknowledge": "I understand this is entirely my responsibility", + "terminal_risk_abort": "Abort", + "terminal_risk_accept": "I ACCEPT FULL RESPONSIBILITY", + "firmware_channel_recommended": "This is the recommended channel.", + "firmware_channel_danger": "DO NOT USE THIS UNLESS YOU KNOW WHAT YOU ARE DOING", + "firmware_channel_stable": "Stable", + "firmware_channel_beta": "Beta", + "firmware_channel_develop": "Develop", + "terminal_board_select": "Select a board...", + "terminal_board_search": "Search boards...", + "terminal_board_none": "No board found.", + "terminal_flash_button": "Flash", + "terminal_flash_progress": "Flash Progress: {{status}}", + "terminal_flash_idle": "Idle", + "terminal_flash_no_device": "No device selected.", + "terminal_flash_resetting": "Resetting...", + "terminal_flash_downloading": "Downloading firmware...", + "terminal_flash_download_failed": "Failed to download firmware.", + "terminal_flash_flashing": "Flashing firmware...", + "terminal_flash_rebooting": "Rebooting device... (Reconnect to power manually if stuck)", + "terminal_flash_done": "Rebooted device! Flashing complete.", + "terminal_port_select": "Select Device", + "terminal_port_disconnect": "Disconnect Device", + "terminal_port_connected": "Device connected: {{id}}", + "terminal_console": "Console", + "terminal_connected_device": "Connected device", + "terminal_resize": "Resize terminal panel", + "terminal_reboot": "Reboot", + "terminal_disconnect": "Disconnect", + "terminal_fullscreen_exit_esc": "Exit fullscreen (Esc)", + "terminal_fullscreen_exit": "Exit fullscreen", + "terminal_fullscreen_fill": "Fill the window", + "terminal_command_label": "Serial command", + "terminal_command_placeholder": "Type a command...", + "terminal_command_send": "Send command", + "terminal_colors": "Colors", + "terminal_colors_menu": "Colors...", + "terminal_colors_label": "Console colors", + "terminal_colors_close": "Close colors", + "terminal_color_input": "{{name}} color", + "terminal_colors_reset": "Reset to defaults", + "terminal_color_bg": "Background", + "terminal_color_fg": "Text", + "terminal_color_ts": "Timestamp", + "terminal_color_error": "Error", + "terminal_color_warning": "Warning", + "terminal_color_info": "Info", + "terminal_color_debug": "Debug", + "terminal_color_verbose": "Verbose", + "terminal_options": "Options", + "terminal_options_label": "Console options", + "terminal_hide_system": "Hide system messages", + "terminal_stick_bottom": "Stick to bottom", + "terminal_raw_output": "Raw output", + "terminal_timestamps": "Timestamps", + "terminal_timestamp_uptime": "Uptime", + "terminal_timestamp_local": "Local", + "terminal_timestamp_ms": "Ms", + "terminal_timestamp_off": "Off", + "terminal_copy_settings": "Copy settings", + "terminal_import_settings": "Import settings", + "terminal_copy_selection": "Copy selection", + "terminal_copy_all": "Copy all output", + "terminal_toast_selection_copied": "Selection copied", + "terminal_toast_output_copied": "Console output copied", + "terminal_toast_settings_copied": "Console settings copied", + "terminal_toast_clipboard_unreadable": "Could not read the clipboard", + "terminal_toast_settings_imported": "Console settings imported", + "terminal_toast_settings_invalid": "Clipboard does not contain console settings", + "common_try_again": "Try again", + "terminal_cfg_intro": "Values are sent to the device via UART. Read the device's response in the console below. Commands without an argument act as getters; use the button next to each field to read the current value.", + "terminal_cfg_rf_title": "RF Transmitter", + "terminal_cfg_rf_desc": "Controls the shocker RF output.", + "terminal_cfg_tx_pin": "TX GPIO pin", + "terminal_cfg_example": "e.g. {{value}}", + "terminal_cfg_read_value": "Read current value", + "terminal_cfg_set": "Set", + "terminal_cfg_read": "Read", + "terminal_cfg_reading": "Reading…", + "terminal_cfg_apply": "Apply", + "terminal_cfg_keepalive": "Keepalive enabled", + "terminal_cfg_keepalive_desc": "Periodically pings paired shockers to keep them awake.", + "terminal_cfg_estop_title": "Emergency Stop", + "terminal_cfg_estop_desc": "Hardware button that halts all output.", + "terminal_cfg_estop_enabled": "EStop enabled", + "terminal_cfg_estop_pin": "EStop GPIO pin", + "terminal_cfg_estop_note": "Note: {{latching}} and {{active}} have no dedicated commands; set them via the JSON config below.", + "terminal_cfg_wifi_title": "WiFi", + "terminal_cfg_wifi_desc": "Station credentials and device hostname.", + "terminal_cfg_hostname": "Hostname", + "terminal_cfg_networks": "Networks (JSON array)", + "terminal_cfg_invalid_json_array": "Must be a valid JSON array", + "terminal_cfg_ap_note": "AP settings ({{ssid}}, {{password}}, {{disabled}}, {{staDisabled}}, {{offlineMode}}) have no dedicated commands; use the JSON config.", + "terminal_cfg_backend_title": "Backend", + "terminal_cfg_backend_desc": "OpenShock server and authentication.", + "terminal_cfg_domain": "Domain", + "terminal_cfg_domain_restart": "Setting the domain will restart the device.", + "terminal_cfg_auth_token": "Auth token", + "terminal_cfg_auth_token_placeholder": "Paste device token", + "terminal_cfg_hide": "Hide", + "terminal_cfg_show": "Show", + "terminal_cfg_serial_title": "Serial Input", + "terminal_cfg_echo": "Echo enabled", + "terminal_cfg_echo_desc": "Print typed characters back to the console.", + "terminal_cfg_advanced_title": "Advanced: full config", + "terminal_cfg_advanced_desc": "For fields without dedicated commands (captive portal, OTA, LAN, etc.), replace the entire config.", + "terminal_cfg_json_config": "JSON config", + "terminal_cfg_invalid_json": "Must be valid JSON", + "terminal_cfg_read_json": "Read current config as JSON", + "terminal_cfg_json_restart": "Applying a JSON config will restart the device.", + "terminal_cfg_raw_config": "Raw FlatBuffer config (base64)", + "terminal_cfg_invalid_base64": "Must be a valid base64 string", + "terminal_cfg_read_raw": "Read current config as base64", + "terminal_cfg_factory_reset": "Factory reset", + "terminal_cfg_factory_reset_desc": "Wipes the entire device configuration.", + "terminal_cfg_factory_reset_title": "Factory reset device?", + "terminal_cfg_factory_reset_action": "Wipe config", + "terminal_cfg_factory_reset_confirm": "This will erase all configuration on the device; WiFi networks, backend credentials, pins, and all other settings. The device will be reset to defaults.", + "terminal_cfg_read_failed_json_title": "Couldn't read the JSON config", + "terminal_cfg_read_failed_raw_title": "Couldn't read the raw config", + "terminal_cfg_read_failed_desc": "The device didn't respond after {{attempts}} attempts.", + "terminal_cfg_common_causes": "Common causes:", + "terminal_cfg_cause_busy": "The device is busy handling another command.", + "terminal_cfg_cause_disconnected": "The device disconnected or rebooted.", + "terminal_cfg_cause_unsupported": "The firmware version doesn't support this command.", + "common_status": "Status", + "common_version": "Version", + "common_created": "Created", + "common_create": "Create", + "common_done": "Done", + "common_enable": "Enable", + "common_disable": "Disable", + "common_are_you_sure": "Are you sure?", + "common_generating": "Generating...", + "hubs_title": "Hubs", + "hubs_subtitle": "Every hub registered to your account.", + "hubs_add": "Add Hub", + "hubs_load_failed": "Failed to load hubs.", + "hubs_empty_title": "No hubs yet", + "hubs_empty_desc": "A hub is the device that relays commands to your shockers. Add one to get started.", + "hubs_create_title": "Create hub", + "hubs_name_label": "Hub Name", + "hubs_name_placeholder": "My Hub", + "hub_toast_not_connected": "Not connected to the server", + "hub_toast_try_later": "Try again in a moment.", + "hub_reboot_title": "Reboot {{name}}?", + "hub_reboot_desc": "The hub will disconnect and restart. Any shockers paired to it stop responding until it comes back online.", + "hub_reboot": "Reboot", + "hub_hotspot_enable_title": "Enable Wi-Fi hotspot on {{name}}?", + "hub_hotspot_disable_title": "Disable Wi-Fi hotspot on {{name}}?", + "hub_hotspot_enable_desc": "The hub broadcasts its own setup network. It stays reachable on your Wi-Fi, but the hotspot is open to anyone in range until you turn it off.", + "hub_hotspot_disable_desc": "The setup hotspot shuts down. If the hub is not already on your Wi-Fi you will need physical access to set it up again.", + "hub_delete_desc": "You are about to delete hub {{name}}.", + "hub_delete_shockers": "This will also delete the following shockers:", + "hub_edit_title": "Edit hub", + "hub_edit_apply": "Apply", + "hub_pair_title_generate": "Generate pair code?", + "hub_pair_title_generated": "Pair code generated", + "hub_pair_title_paired": "Hub paired", + "hub_pair_consumed": "{{name}} consumed this pair code and is now paired.", + "hub_pair_used": "The code has been used and is no longer valid.", + "hub_pair_generated_for": "Pair code generated for {{name}}.", + "hub_copy_now": "The code below will not be accessible later, please copy it now and update clients with it.", + "hub_pair_generate_for": "You are about to generate a pair code for {{name}}.", + "hub_pair_valid_for": "It will be valid for 15 minutes after its creation.", + "hub_pair_one_active": "There is only one active pair code per hub, newly generated ones will override the older active ones.", + "hub_pair_complete": "Pairing complete", + "hub_pair_code_label": "Pair code:", + "hub_pair_copied_close": "Code has been copied, close", + "hub_pair_get": "Get Pair Code", + "hub_token_generated": "Token generated", + "hub_token_generated_for": "New token generated for {{name}}.", + "hub_token_regenerate_for": "You are about to regenerate the token for {{name}}.", + "hub_token_invalidate": "This action will invalidate the current token and disconnect clients using it.", + "hub_token_confirm": "Are you sure you want to do this?", + "hub_token_label": "New token:", + "hub_token_copied_close": "Token has been copied, close", + "hub_token_regenerate": "Regenerate Token", + "hub_menu_update": "Update", + "hub_menu_label": "Hub", + "hub_menu_hotspot_enable": "Enable Wi-Fi hotspot", + "hub_menu_hotspot_disable": "Disable Wi-Fi hotspot", + "hub_menu_pair": "Pair", + "hub_menu_estop": "Emergency Stop", + "hub_update_breadcrumb": "Update", + "hub_update_unknown_hub": "Unknown Hub", + "hub_update_unknown_task": "Unknown Task", + "hub_update_task_metadata": "Fetching Metadata", + "hub_update_task_preparing": "Preparing for Update", + "hub_update_task_flash_fs": "Flashing Filesystem", + "hub_update_task_verify_fs": "Verifying Filesystem", + "hub_update_task_flash_app": "Flashing Application", + "hub_update_task_bootable": "Marking Application Bootable", + "hub_update_task_rebooting": "Rebooting", + "hub_update_status_started": "Started", + "hub_update_status_running": "Running", + "hub_update_status_finished": "Finished", + "hub_update_status_error": "Error", + "hub_update_status_timeout": "Timeout", + "hub_update_confirm_title": "Confirm firmware update", + "hub_update_confirm_desc": "Update {{name}} to version {{version}}?", + "hub_update_unstable_warning": "This version may not be from the stable channel and could contain bugs.", + "hub_update_title": "Update {{name}}", + "hub_update_subtitle": "Manage firmware updates for this hub.", + "hub_update_status_title": "Hub Status", + "hub_update_firmware": "Firmware: {{version}}", + "hub_update_confirm": "Update", + "hub_update_success": "Update completed successfully", + "hub_update_rolled_back": "Device rolled back to previous version", + "hub_update_back": "Back to Hubs", + "hub_update_flash_again": "Flash Again", + "hub_update_card_title": "Firmware Update", + "hub_update_card_desc": "Select a firmware channel and version to install.", + "hub_update_to": "Update to {{version}}", + "hub_update_must_be_online": "Hub must be online to start an update.", + "hub_update_updating_to": "Updating to {{version}}...", + "hub_update_total": "Total", + "hub_update_task": "Task", + "hub_update_history": "Update History", + "hub_update_no_history": "No update history found for this hub.", + "hub_update_col_id": "ID", + "hub_update_col_started": "Started", + "hub_update_col_message": "Message", + "hub_update_loading": "Loading hub information...", + "hub_update_not_found": "Hub not found.", + "home_breadcrumb": "Home", + "home_welcome": "Welcome back", + "home_welcome_name": "Welcome back, {{name}}", + "home_subtitle": "Here's an overview of your OpenShock setup.", + "home_hubs_online": "{{count}} online", + "home_hub_status": "Hub Status", + "home_no_hubs": "No hubs", + "home_all_online": "All online", + "home_all_offline": "All offline", + "home_some_online": "{{online}}/{{total}} online", + "home_quick_links": "Quick Links", + "home_my_shockers": "My Shockers", + "home_my_shockers_desc": "Control your shockers", + "home_hubs_desc": "Manage your hubs", + "home_shared_desc": "Shockers shared with you", + "home_public_desc": "Manage share links", + "home_get_started": "Get Started", + "home_get_started_desc": "You don't have any hubs yet. Create a hub to connect your first device, then add shockers to it.", + "home_set_up_hub": "Set Up a Hub", + "home_first_shocker": "Add Your First Shocker", + "home_first_shocker_desc_one": "You have {{count}} hub set up. Add a shocker to start controlling it.", + "home_first_shocker_desc_other": "You have {{count}} hubs set up. Add a shocker to start controlling it.", + "home_go_to_shockers": "Go to Shockers", + "profile_title": "Profile", + "profile_coming_soon": "Profile is coming soon", + "profile_coming_soon_desc": "Your public profile is not available yet. Account details live under Settings.", + "common_retry": "Retry", + "common_never_used": "Never used", + "common_expires": "Expires {{time}}", + "common_search_placeholder": "Search...", + "common_unknown": "Unknown", + "settings_breadcrumb_account": "Account", + "account_subtitle": "Your sign-in details and account actions.", + "account_change_username": "Change Username", + "account_change_email": "Change Email", + "account_change_password": "Change Password", + "account_username_label": "Username", + "account_email_label": "Email", + "account_password_label": "Password", + "account_new_password_label": "New Password", + "account_confirm_password_label": "Confirm New Password", + "account_oauth_only": "Not available for OAuth-only accounts", + "account_oauth_no_password": "This account signs in via OAuth and has no password.", + "account_diagnostics": "Diagnostics", + "account_diagnostics_desc": "Help us fix crashes and slow API calls. Reports include the error message, stack trace and your IP. Off by default.", + "account_diagnostics_level": "Diagnostics level", + "account_telemetry_off": "Off", + "account_telemetry_off_desc": "Send nothing.", + "account_telemetry_errors": "Errors", + "account_telemetry_errors_desc": "Send browser error reports only.", + "account_telemetry_full": "Full", + "account_telemetry_full_desc": "Error reports plus traces of API calls (no page navigations).", + "account_toast_deactivated": "Account deactivated successfully", + "account_deactivate_title": "Deactivate account", + "account_deactivate_desc": "Are you sure you want to deactivate your account?", + "account_deactivate": "Deactivate Account", + "account_email_title": "Change email", + "account_email_desc": "Enter your new email address and confirm with your current password.", + "account_email_toast_sent": "Verification email sent to {{email}}. Click the link in that email to apply the change.", + "account_new_email": "New Email", + "account_current_password": "Current Password", + "account_password_title": "Change password", + "account_password_desc": "Enter your current password and choose a new one.", + "account_password_toast": "Password has been changed", + "account_username_title": "Change username", + "account_username_desc": "Enter a new username.", + "account_new_username": "New Username", + "account_username_toast": "Username changed successfully", + "tokens_subtitle": "API Tokens are used to authenticate with the OpenShock API.", + "tokens_generate": "Generate Token", + "tokens_toast_refreshed": "Tokens refreshed successfully", + "tokens_empty_title": "No API tokens", + "tokens_empty_desc": "Generate a token to authenticate with the OpenShock API.", + "tokens_created_on": "Created {{date}}", + "tokens_last_used": "Last used {{time}}", + "tokens_never_expires": "Never expires", + "tokens_load_failed": "Failed to load API tokens.", + "token_toast_edited": "Token edited successfully", + "token_name_required": "Name is required", + "token_name_too_long": "Name is too long", + "token_edit_title": "Edit API token", + "token_name_label": "Token Name", + "token_name_placeholder": "Token name...", + "token_permissions": "Permissions", + "token_perm_category_shockers": "Shockers", + "token_perm_category_devices": "Hubs", + "token_perm_category_usershares": "User Shares", + "token_perm_category_publicshares": "Public Shares", + "token_perm_use": "Use", + "token_perm_edit": "Edit", + "token_perm_pause": "Pause", + "token_perm_auth": "Authenticate", + "token_shocker_control": "Shocker Control", + "token_toast_paused": "Token paused", + "token_toast_resumed": "Token resumed", + "token_delete_title": "Delete API token", + "token_delete_desc": "Are you sure you want to delete {{name}}?", + "token_delete_permanent": "This action cannot be undone. This will permanently delete the token.", + "token_toast_deleted": "Token deleted successfully", + "token_resume": "Resume token", + "token_pause": "Pause token", + "token_mode_clamp_desc": "Clamp: requests outside the allowed range are capped to the nearest limit (the min or the max).", + "token_mode_lerp_desc": "Lerp: the full input range is linearly rescaled so it fits within your allowed min–max range.", + "token_paused_desc": "A paused token may not send shocker control messages.", + "token_intensity_range": "Intensity range", + "token_duration_range": "Duration range", + "token_new_breadcrumb": "New", + "token_redirect_not_allowed": "The provided redirect_uri is not allowed. Only loopback addresses or custom application schemes are permitted.", + "token_params_missing": "Required get parameters are missing. Make sure name, redirect_uri, and permissions are provided.", + "token_invalid_permissions": "Invalid permissions provided: {{list}}", + "token_toast_created": "Token created successfully", + "token_request_title": "API Token Request", + "token_access_granted": "Access granted", + "token_shared_redirecting": "The token has been created and shared with the application. Redirecting you back to {{uri}}.", + "token_not_redirected": "If you are not redirected automatically, use the button below.", + "token_finish": "Finish", + "token_generated_title": "API Token Generated", + "token_copy_now": "Please copy your API Token now, you will not be able to view it again later!", + "token_new_title": "New API Token", + "token_external_desc": "An external application is requesting access to your account. Review and adjust the permissions below before allowing access.", + "token_new_desc": "Configure and generate a new API token for your account.", + "token_external_requesting": "{{name}} is requesting an API Token. Your token will be shared with the application at {{uri}}.", + "token_allow": "Allow", + "token_generate": "Generate", + "token_deny": "Deny", + "sessions_subtitle": "Every active session on your account. Revoke any you do not recognize.", + "sessions_unknown_device": "Unknown device", + "sessions_toast_refreshed": "Sessions refreshed successfully", + "sessions_load_failed": "Failed to load sessions.", + "sessions_empty_title": "No active sessions", + "sessions_empty_desc": "Sessions appear here once you sign in from a browser or app.", + "sessions_last_seen": "Last seen {{time}}", + "sessions_signed_in": "Signed in {{time}}", + "session_toast_revoked": "Session revoked successfully", + "session_revoke_title": "Revoke session", + "session_revoke": "Revoke", + "session_revoke_desc": "Are you sure you want to revoke this session?", + "session_revoke_from": "Session logged in from {{ip}} using {{agent}}", + "connections_title": "OAuth Connections", + "connections_subtitle": "Link or unlink third-party accounts to sign in faster and keep your profile in sync.", + "connections_toast_linked": "Account linked.", + "connections_toast_cancelled": "Link flow cancelled.", + "connections_toast_failed": "Linking failed.", + "connections_toast_removed": "Connection removed", + "connections_refreshing": "Refreshing…", + "connections_link_new": "Link new provider", + "connections_empty_title": "No connections yet", + "connections_empty_desc": "Choose “Link new provider” above to connect available providers.", + "connections_unlink": "Unlink", + "connections_load_failed": "Failed to load OAuth connections.", + "connections_unlink_title": "Unlink {{name}}?", + "connections_unlink_title_generic": "Unlink this account?", + "connections_unlink_desc": "You'll no longer be able to sign in with this provider unless you link it again.", + "provider_starting": "Starting {{name}}...", + "provider_link": "Link {{name}}", + "audit_subtitle": "Security-relevant activity on your account. Review anything you do not recognize.", + "audit_col_time": "Time", + "audit_col_action": "Action", + "audit_col_details": "Details", + "audit_col_reason": "Reason", + "audit_col_ip": "IP address", + "audit_col_device": "Device", + "audit_action_login": "Signed in", + "audit_action_logout": "Signed out", + "audit_action_password_changed": "Password changed", + "audit_action_email_change_requested": "Email change requested", + "audit_action_email_changed": "Email changed", + "audit_action_username_changed": "Username changed", + "audit_action_api_token_created": "API token created", + "audit_action_api_token_deleted": "API token deleted", + "audit_action_oauth_connected": "Connection added", + "audit_action_oauth_disconnected": "Connection removed", + "audit_action_account_deactivated": "Account deactivated", + "audit_action_account_reactivated": "Account reactivated", + "audit_action_account_deleted": "Account deleted", + "audit_action_automation_token_created": "Automation token created", + "audit_action_automation_token_updated": "Automation token updated", + "audit_action_automation_token_rotated": "Automation token rotated", + "audit_action_automation_token_deleted": "Automation token deleted", + "audit_action_automation_token_used": "Automation token used", + "audit_meta_session": "Session {{id}}", + "audit_meta_changed": "{{old}} to {{new}}", + "audit_meta_email_requested": "Requested change to {{email}}", + "audit_meta_accounts_removed_one": "{{name}} ({{count}} account removed)", + "audit_meta_accounts_removed_other": "{{name}} ({{count}} accounts removed)", + "audit_meta_scheduled_deletion": "Scheduled for deletion", + "audit_meta_kept": "Kept for reactivation", + "common_view": "View", + "common_save": "Save", + "common_saving": "Saving...", + "common_back": "Back", + "common_shared_by": "Shared by", + "common_user_avatar": "User Avatar", + "common_toast_saved": "Changes saved successfully", + "pause_reason_shocker": "Paused at shocker level", + "pause_reason_shocker_user_share": "Paused at shocker and user share level", + "pause_reason_shocker_public_share": "Paused at shocker and public share level", + "pause_reason_user_share": "Paused at user share level", + "pause_reason_public_share": "Paused at public share level", + "public_shares_subtitle": "A link anyone can use, no account required.", + "public_shares_new": "New Share", + "public_share_never_expires": "Never expires", + "public_shares_empty_title": "No public shares yet", + "public_shares_empty_desc": "Create a link that anyone can use to control your shockers.", + "public_share_expired": "Expired", + "public_share_no_expiry": "No expiry", + "public_share_label": "Public Share", + "public_share_toast_created": "Created new public share", + "public_share_create_title": "Create public share", + "public_share_toast_deleted": "Deleted public share", + "public_share_delete_title": "Delete public share", + "public_share_delete_desc": "Are you sure you want to delete public share {{name}}?", + "public_share_edit_title": "Public Share: {{name}}", + "public_share_edit_subtitle": "Editing: changes apply when you save.", + "public_share_add_shocker": "Add Shocker", + "public_share_toast_added_one": "Added {{count}} shocker to share", + "public_share_toast_added_other": "Added {{count}} shockers to share", + "public_share_empty_shockers_title": "No shockers in this share", + "public_share_empty_shockers_desc": "Add a shocker and anyone with the link will be able to control it.", + "public_share_load_failed": "Error fetching public share details", + "public_share_paused_here": "Paused for this share", + "public_share_resume_shocker": "Resume shocker", + "public_share_pause_shocker": "Pause shocker", + "public_share_remove": "Remove from share", + "public_share_toast_removed": "Shocker removed from share", + "public_share_add_title": "Add shockers", + "public_share_add_desc": "Add shockers to this public share. You can set their limits once they are added.", + "public_share_add_placeholder": "Select shockers to share...", + "public_share_add_no_match": "No matching shockers", + "public_share_add_submit": "Add Shockers", + "public_share_view_loading": "Loading share details...", + "public_share_view_title": "Public Share Link", + "public_share_view_desc": "Enter as a guest or login with your OpenShock account", + "public_share_view_guest_name": "Guest Name", + "public_share_view_enter": "Enter", + "public_share_view_enter_guest": "Enter as Guest", + "public_share_login": "Login", + "perm_shock_on": "Shock enabled", + "perm_shock_off": "Shock disabled", + "perm_vibrate_on": "Vibrate enabled", + "perm_vibrate_off": "Vibrate disabled", + "perm_sound_on": "Sound enabled", + "perm_sound_off": "Sound disabled", + "perm_live_on": "Live enabled", + "perm_live_off": "Live disabled", + "perm_live_control": "Live Control", + "user_selector_avatar_of": "{{name}}'s avatar", + "user_selector_placeholder": "Enter user name", + "user_selector_aria": "Username to search", + "user_selector_search": "Search user", + "user_selector_found": "User found", + "common_remove": "Remove", + "user_shares_subtitle": "Direct permanent shares with other users.", + "user_shares_toast_invited": "Sent a shocker invite to {{name}}", + "user_shares_redeem": "Redeem Code", + "user_shares_new": "New Share", + "user_shares_tab_shares": "Shares", + "user_shares_tab_incoming": "Shared with Me", + "user_shares_tab_invites": "Invites", + "share_code_create_title": "New share code", + "share_code_create_desc": "Create a Share Code or Invite", + "share_code_shocker_placeholder": "Select shockers to share...", + "share_code_no_match": "No matching shockers", + "share_code_send_invite": "Send Share Invite", + "share_code_create": "Create Share Code", + "share_code_created_title": "Share code generated", + "share_code_created_desc": "Please copy share code or code link!", + "share_code_redeem_title": "Redeem share code", + "share_code_redeem_desc": "Enter the share code to redeem", + "share_code_redeem_placeholder": "Enter share code", + "share_code_redeemed": "Redeemed successfully!", + "share_code_shared_shockers": "Shared shockers", + "share_code_redeeming": "Redeeming...", + "share_code_redeem": "Redeem", + "incoming_shares_empty_title": "Nothing shared with you", + "incoming_shares_empty_desc": "No one has shared a shocker with you yet.", + "incoming_share_toast_removed": "Removed share for {{name}}", + "incoming_share_remove_title": "Remove Share", + "incoming_share_remove_desc": "Are you sure you want to remove the share for {{name}}?", + "incoming_share_toast_removed_shocker": "Removed {{shocker}} shared by {{name}}", + "incoming_share_remove_shocker_title": "Remove this shared shocker?", + "incoming_share_remove_shocker_desc": "Are you sure you want to remove the shocker share {{shocker}} by {{name}}?", + "incoming_share_manage_from": "Manage shares from", + "share_remove": "Remove share", + "invites_empty_title": "No invites yet", + "invites_empty_desc": "You have no incoming or outgoing share invites.", + "invites_outgoing": "Outgoing", + "invites_outgoing_empty_title": "No outgoing invites", + "invites_outgoing_empty_desc": "You have no outgoing share invites.", + "invites_incoming": "Incoming", + "invites_incoming_empty_title": "No incoming invites", + "invites_incoming_empty_desc": "You have no incoming share invites.", + "invite_toast_accepted": "Accepted share invite from {{name}}", + "invite_toast_declined": "Declined share invite from {{name}}", + "invite_deny_title": "Deny Invite", + "invite_deny_label": "Deny Invite", + "invite_deny": "Deny", + "invite_deny_desc": "Are you sure you want to deny the invite from {{name}}?", + "invite_accept": "Accept Invite", + "invite_toast_cancelled_for": "Cancelled invite for {{name}} ({{id}})", + "invite_toast_cancelled": "Cancelled invite {{id}}", + "invite_cancel_title": "Cancel Invite", + "invite_cancel": "Cancel", + "invite_cancel_for_desc": "Are you sure you want to cancel the invite for {{name}}?", + "invite_cancel_code_desc": "Are you sure you want to cancel the invite with code {{code}}?", + "invite_cancel_outstanding": "Cancel Outstanding Invite", + "outgoing_shares_empty_title": "No shared shockers", + "outgoing_shares_empty_desc": "You haven't shared any shockers with other users yet.", + "outgoing_share_toast_removed": "Removed shocker share {{name}}", + "outgoing_share_remove_title": "Stop sharing this shocker?", + "outgoing_share_editing_for": "Editing shares for", + "outgoing_share_limits": "Limits & Permissions", + "outgoing_share_same": "Same restrictions on every shocker", + "outgoing_share_per_desc": "Tune restrictions per shocker", + "outgoing_share_all": "All", + "outgoing_share_per": "Per shocker", + "outgoing_share_remove_desc": "Are you sure you want to stop sharing {{shocker}} with {{name}}?", + "report_breadcrumb": "Report API Tokens", + "report_toast_clipboard_failed": "Failed to read clipboard: {{error}}", + "report_title": "Report Leaked API Tokens", + "report_paste": "Paste from clipboard", + "report_warning": "This form is only for reporting accidentally leaked API tokens.", + "report_abuse_warning": "Intentional abuse will result in bans or severe endpoint restrictions.", + "report_detected": "Detected Tokens", + "report_invalid": "One or more tokens appear to be invalid. Please check for formatting issues.", + "report_acknowledge": "I confirm I understand what this feature is for and accept responsibility.", + "report_submit": "Submit Report", + "turnstile_disabled": "Turnstile disabled", + "common_internal_error": "Internal error", + "resend_toast_sent": "Activation email sent. Check your inbox and spam folder.", + "resend_toast_throttled": "Too many activation emails have been requested. Please try again later.", + "resend_toast_unavailable": "No activation email can be resent from this browser. If your account isn't activated yet, logging in sends a new link.", + "resend_button": "Didn't get the email? Resend", + "expiration_label": "Expiration", + "expiration_never": "Never", + "expiration_custom": "Custom", + "expiration_days_one": "{{count}} Day", + "expiration_days_other": "{{count}} Days", + "expiration_required": "Expire date is required", + "expiration_never_desc": "This will never expire", + "expiration_expires_at": "Expires {{time}} ({{date}})", + "date_picker_placeholder": "Pick a date", + "telemetry_toast_title": "Help improve OpenShock?", + "telemetry_toast_desc": "Send diagnostics to help us fix crashes and slow API calls. Reports include the error message, stack trace and your IP. You can change this any time in Account settings.", + "telemetry_toast_no": "No thanks", + "telemetry_toast_errors": "Errors only", + "telemetry_toast_full": "Full", + "table_show_details": "Show details", + "table_hide_details": "Hide details", + "table_no_results": "No results.", + "table_sort_asc": "Sort by {{name}}, ascending", + "table_sort_desc": "Sort by {{name}}, descending", + "table_sort_none": "Sort by {{name}}, unsorted", + "cell_na": "N/A", + "cell_not_applicable": "Not applicable", + "cell_invalid": "Invalid", + "cell_unavailable": "Unavailable", + "cell_none": "None", + "oauth_login_with": "Login with {{provider}}", + "oauth_signup_with": "Signup with {{provider}}", + "signalr_connect_failed": "Failed to connect to server!", + "signalr_disconnect_failed": "Encountered error while disconnecting from server!", + "signalr_invalid_update": "Received invalid update from server!", + "signalr_invalid_log": "Received invalid log data from server!", + "signalr_invalid_ota": "Received invalid firmware update data from server!", + "ota_toast_failed": "Hub firmware update failed: {{message}}", + "ota_toast_succeeded": "Hub firmware update completed successfully!", + "ota_toast_rolled_back": "Hub firmware rolled back to previous version", + "lcg_connect_failed": "Failed to connect to live control gateway", + "terminal_toast_bootloader_failed": "Failed to enter bootloader: {{error}}", + "terminal_toast_app_mode_failed": "Failed to enter application mode: {{error}}", + "problem_account_account_not_activated_title": "Account not activated", + "problem_account_account_not_activated_desc": "Check your inbox for the activation email.", + "problem_account_activation_not_found_title": "Activation link is invalid", + "problem_account_activation_not_found_desc": "The link may have expired or already been used.", + "problem_account_activation_resend_too_many_title": "Too many activation emails requested", + "problem_account_activation_resend_too_many_desc": "Please wait a while before trying again.", + "problem_account_activation_resend_unavailable_title": "Cannot resend activation email", + "problem_account_activation_resend_unavailable_desc": "Log in again to request a new activation link.", + "problem_account_deactivate_already_deactivated_title": "Account is already deactivated", + "problem_account_deactivate_denied_privileged_title": "Privileged accounts cannot be deactivated", + "problem_account_deactivate_unauthorized_title": "You are not allowed to do this", + "problem_account_deactivated_title": "This account has been deactivated", + "problem_account_email_already_in_use_title": "That email address is already in use", + "problem_account_email_invalid_title": "That email address is not valid", + "problem_account_email_taken_title": "That email address is already in use", + "problem_account_email_too_many_requests_title": "Too many email change requests", + "problem_account_email_too_many_requests_desc": "Please wait a while before trying again.", + "problem_account_email_unchanged_title": "That is already your email address", + "problem_account_email_verify_not_found_title": "Verification link is invalid", + "problem_account_email_verify_not_found_desc": "The link may have expired or already been used.", + "problem_account_o_auth_only_title": "This account has no password", + "problem_account_o_auth_only_desc": "Sign in with the provider you signed up with.", + "problem_account_password_not_set_title": "No password set", + "problem_account_password_not_set_desc": "This account signs in through an external provider.", + "problem_account_password_old_password_invalid_title": "Current password is incorrect", + "problem_account_username_invalid_title": "That username is not allowed", + "problem_account_username_recently_changed_title": "Username changed too recently", + "problem_account_username_recently_changed_desc": "You can change your username once every 7 days.", + "problem_account_username_taken_title": "That username is already taken", + "problem_admin_user_deactivated_title": "This user is deactivated", + "problem_admin_user_not_activated_title": "This user has not been activated yet", + "problem_api_token_can_only_delete_self_title": "An API token can only delete itself", + "problem_api_token_not_found_title": "API token not found", + "problem_api_token_paused_title": "This API token is paused", + "problem_assign_lcg_bad_schema_version_title": "Unsupported hub protocol version", + "problem_assign_lcg_bad_schema_version_desc": "Update the hub firmware to connect.", + "problem_assign_lcg_no_lcg_available_title": "No gateway available", + "problem_assign_lcg_no_lcg_available_desc": "No live control gateway is available right now. Please try again later.", + "problem_authentication_account_deactivated_title": "This account has been deactivated", + "problem_authentication_account_not_activated_title": "This account has not been activated", + "problem_authentication_cookie_missing_or_invalid_title": "You are not logged in", + "problem_authentication_cookie_missing_or_invalid_desc": "Your session may have expired. Please log in again.", + "problem_authentication_header_missing_or_invalid_title": "Invalid API token", + "problem_authentication_session_invalid_title": "Session expired", + "problem_authentication_session_invalid_desc": "Please log in again.", + "problem_authentication_token_invalid_title": "Invalid API token", + "problem_authentication_unknown_error_title": "Authentication failed", + "problem_authorization_policy_not_met_title": "You do not have permission to do this", + "problem_authorization_token_only_title": "This action requires an API token", + "problem_authorization_token_permission_missing_title": "This API token is missing a required permission", + "problem_authorization_unknown_error_title": "Authorization failed", + "problem_authorization_user_session_only_title": "This action requires a logged-in session", + "problem_automation_token_not_allowed_for_account_title": "Automation tokens cannot be used with privileged accounts", + "problem_configuration_already_exists_title": "A configuration entry with that name already exists", + "problem_configuration_invalid_name_format_title": "Invalid configuration name", + "problem_configuration_invalid_name_format_desc": "Only A to Z and underscores are allowed.", + "problem_configuration_invalid_value_format_title": "Value does not match the configuration type", + "problem_configuration_not_found_title": "Configuration entry not found", + "problem_control_stats_invalid_range_title": "The from date must not be after the to date", + "problem_control_stats_invalid_time_zone_title": "Unknown time zone", + "problem_control_stats_missing_capability_title": "Control statistics are not available on this server", + "problem_device_not_found_title": "Hub not found", + "problem_device_not_online_title": "Hub is offline", + "problem_device_too_many_hubs_title": "You have reached the maximum number of hubs", + "problem_device_too_many_shockers_title": "This hub has reached its maximum number of shockers", + "problem_endpoint_retired_title": "This feature is no longer available", + "problem_expression_error_title": "Invalid filter expression", + "problem_internal_server_error_title": "Something went wrong on our end", + "problem_login_invalid_credentials_title": "Invalid username or password", + "problem_login_invalid_domain_title": "Logging in from this address is not allowed", + "problem_o_auth_connection_already_exists_title": "Your account is already connected to this provider", + "problem_o_auth_connection_already_linked_title": "This external account is already linked to another user", + "problem_o_auth_flow_anonymous_only_title": "You are already signed in", + "problem_o_auth_flow_mismatch_title": "Sign-in attempt does not match", + "problem_o_auth_flow_mismatch_desc": "Please start over.", + "problem_o_auth_flow_missing_data_title": "The provider did not return your account details", + "problem_o_auth_flow_missing_data_desc": "Please try again.", + "problem_o_auth_flow_not_found_title": "Sign-in attempt expired", + "problem_o_auth_flow_not_found_desc": "Please start over.", + "problem_o_auth_flow_unsupported_title": "Unsupported sign-in flow", + "problem_o_auth_internal_error_title": "Something went wrong during sign-in", + "problem_o_auth_internal_error_desc": "Please try again in a moment.", + "problem_o_auth_link_authenticated_user_only_title": "You must be signed in to link an external account", + "problem_o_auth_provider_mismatch_title": "Sign-in attempt does not match the provider", + "problem_o_auth_provider_mismatch_desc": "Please start over.", + "problem_o_auth_provider_unsupported_title": "This sign-in provider is not supported", + "problem_pair_code_not_found_title": "Pair code not found", + "problem_password_reset_not_found_title": "Password reset link is invalid", + "problem_password_reset_not_found_desc": "The link may have expired or already been used.", + "problem_session_not_found_title": "Session not found", + "problem_share_get_no_shares_title": "You have no shares with this user", + "problem_share_request_create_cannot_share_with_self_title": "You cannot share with yourself", + "problem_share_request_create_shocker_not_found_title": "One or more shockers were not found", + "problem_share_request_create_shocker_not_found_desc": "They may have been removed or do not belong to you.", + "problem_share_request_not_found_title": "Share invite not found", + "problem_share_user_not_found_title": "Share not found", + "problem_share_code_already_linked_title": "Shocker is already linked to your account", + "problem_share_code_cant_link_own_share_code_title": "You cannot redeem your own share code", + "problem_share_code_not_found_title": "Share code not found", + "problem_share_link_expiry_date_in_past_title": "Expiry date cannot be in the past", + "problem_share_link_not_found_title": "Public share not found", + "problem_share_link_shocker_already_in_share_link_title": "Shocker is already in this public share", + "problem_share_link_shocker_not_in_share_link_title": "Shocker is not in this public share", + "problem_shocker_control_no_permission_title": "You do not have permission to control this shocker", + "problem_shocker_control_not_found_title": "Shocker not found", + "problem_shocker_control_paused_title": "Shocker is paused", + "problem_shocker_not_found_title": "Shocker not found", + "problem_signup_registration_disabled_title": "Registration is currently disabled", + "problem_signup_username_or_email_exists_title": "That username or email is already in use", + "problem_turnstile_invalid_title": "Verification failed", + "problem_turnstile_invalid_desc": "Please complete the challenge again and retry.", + "problem_user_not_found_title": "User not found", + "problem_user_privileged_delete_denied_title": "Privileged users cannot be deleted", + "problem_validation_error_title": "Some fields are invalid", + "problem_webhook_not_found_title": "Webhook not found", + "problem_webhook_unsupported_title": "Only Discord webhooks are supported", + "problem_webhook_unsupported_desc": "Use a discord.com URL, not canary or ptb.", + "error_too_many_requests": "Too many requests", + "error_retry_after_one": "Try again in {{count}} second.", + "error_retry_after_other": "Try again in {{count}} seconds.", + "error_unexpected_response": "Unexpected server response", + "error_internal": "Internal error occurred", + "error_network": "Network error occurred", + "dev_banner": "This is the OpenShock DEVELOPMENT environment. No data is saved, and it is regularly overwritten by production data.", + "firmware_channel_bugs_warning": "This channel might contain bugs." +}