Files
ObsidianDragon/src/util/i18n.cpp
DanS fbdba1a001 feat: CJK font rendering, force quit confirmation, settings i18n
- Rebuild CJK font subset (1421 glyphs) and convert CFF→TTF for
  stb_truetype compatibility, fixing Chinese/Japanese/Korean rendering
- Add force quit confirmation dialog with cancel/confirm actions
- Show force quit tooltip immediately on hover (no delay)
- Translate hardcoded English strings in settings dropdowns
  (auto-lock timeouts, slider "Off" labels)
- Fix mojibake en-dashes in 7 translation JSON files
- Add helper scripts: build_cjk_subset, convert_cjk_to_ttf,
  check_font_coverage, fix_mojibake
2026-04-12 10:32:58 -05:00

1146 lines
60 KiB
C++

// DragonX Wallet - ImGui Edition
// Copyright 2024-2026 The Hush Developers
// Released under the GPLv3
#include "i18n.h"
#include "platform.h"
#include <fstream>
#include <cstdio>
#include <cstring>
#include <nlohmann/json.hpp>
// Embedded language files
#include "embedded/lang_es.h"
#include "embedded/lang_zh.h"
#include "embedded/lang_ru.h"
#include "embedded/lang_de.h"
#include "embedded/lang_fr.h"
#include "embedded/lang_pt.h"
#include "embedded/lang_ja.h"
#include "embedded/lang_ko.h"
#include "../util/logger.h"
namespace dragonx {
namespace util {
using json = nlohmann::json;
I18n::I18n()
{
// Register built-in languages
// CJK glyphs are provided by the merged NotoSansCJK-Subset fallback font.
// Cyrillic glyphs are included in the Ubuntu font glyph ranges.
registerLanguage("en", "English");
registerLanguage("es", "Español");
registerLanguage("zh", "Chinese");
registerLanguage("ru", "Russian");
registerLanguage("de", "Deutsch");
registerLanguage("fr", "Français");
registerLanguage("pt", "Português");
registerLanguage("ja", "Japanese");
registerLanguage("ko", "Korean");
// Load default English strings (built-in fallback)
loadLanguage("en");
}
I18n& I18n::instance()
{
static I18n instance;
return instance;
}
bool I18n::loadLanguage(const std::string& locale)
{
// Try to load from file: CWD-relative first, then exe-relative
std::string rel_path = "res/lang/" + locale + ".json";
std::string exe_path = Platform::getExecutableDirectory() + "/" + rel_path;
// Try both paths; prefer whichever opens successfully
for (const auto& lang_file : { rel_path, exe_path }) {
std::ifstream file(lang_file);
if (!file.is_open()) continue;
try {
json j;
file >> j;
// Load English built-in as fallback base for non-English
if (locale != "en") {
loadBuiltinEnglish();
} else {
strings_.clear();
}
for (auto& [key, value] : j.items()) {
if (value.is_string()) {
strings_[key] = value.get<std::string>();
}
}
current_locale_ = locale;
DEBUG_LOGF("Loaded language file: %s (%zu strings)\n", lang_file.c_str(), strings_.size());
return true;
} catch (const std::exception& e) {
DEBUG_LOGF("Error parsing language file %s: %s\n", lang_file.c_str(), e.what());
}
}
// Try embedded language data
const unsigned char* embedded_data = nullptr;
unsigned int embedded_size = 0;
if (locale == "es") {
embedded_data = res_lang_es_json;
embedded_size = res_lang_es_json_len;
} else if (locale == "zh") {
embedded_data = res_lang_zh_json;
embedded_size = res_lang_zh_json_len;
} else if (locale == "ru") {
embedded_data = res_lang_ru_json;
embedded_size = res_lang_ru_json_len;
} else if (locale == "de") {
embedded_data = res_lang_de_json;
embedded_size = res_lang_de_json_len;
} else if (locale == "fr") {
embedded_data = res_lang_fr_json;
embedded_size = res_lang_fr_json_len;
} else if (locale == "pt") {
embedded_data = res_lang_pt_json;
embedded_size = res_lang_pt_json_len;
} else if (locale == "ja") {
embedded_data = res_lang_ja_json;
embedded_size = res_lang_ja_json_len;
} else if (locale == "ko") {
embedded_data = res_lang_ko_json;
embedded_size = res_lang_ko_json_len;
}
if (embedded_data != nullptr && embedded_size > 0) {
try {
std::string json_str(reinterpret_cast<const char*>(embedded_data), embedded_size);
json j = json::parse(json_str);
// Load English built-in as fallback base for non-English
if (locale != "en") {
loadBuiltinEnglish();
} else {
strings_.clear();
}
for (auto& [key, value] : j.items()) {
if (value.is_string()) {
strings_[key] = value.get<std::string>();
}
}
current_locale_ = locale;
DEBUG_LOGF("Loaded embedded language: %s (%zu strings)\n", locale.c_str(), strings_.size());
return true;
} catch (const std::exception& e) {
DEBUG_LOGF("Error parsing embedded language %s: %s\n", locale.c_str(), e.what());
}
}
// If English, use built-in strings
if (locale == "en") {
loadBuiltinEnglish();
current_locale_ = "en";
return true;
}
return false;
}
void I18n::loadBuiltinEnglish()
{
strings_.clear();
// Navigation & Tabs
strings_["overview"] = "Overview";
strings_["balance"] = "Balance";
strings_["send"] = "Send";
strings_["receive"] = "Receive";
strings_["transactions"] = "Transactions";
strings_["history"] = "History";
strings_["mining"] = "Mining";
strings_["peers"] = "Peers";
strings_["market"] = "Market";
strings_["settings"] = "Settings";
strings_["console"] = "Console";
strings_["tools"] = "TOOLS";
strings_["advanced"] = "ADVANCED";
// Settings sections
strings_["appearance"] = "APPEARANCE";
strings_["theme_language"] = "THEME & LANGUAGE";
strings_["advanced_effects"] = "Advanced Effects...";
strings_["tools_actions"] = "Tools & Actions...";
strings_["wallet"] = "WALLET";
strings_["node_security"] = "NODE & SECURITY";
strings_["node"] = "NODE";
strings_["security"] = "SECURITY";
strings_["explorer"] = "EXPLORER";
strings_["about"] = "About";
strings_["backup_data"] = "BACKUP & DATA";
strings_["balance_layout"] = "Balance Layout";
strings_["low_spec_mode"] = "Low-spec mode";
strings_["simple_background"] = "Simple background";
strings_["console_scanline"] = "Console scanline";
strings_["theme_effects"] = "Theme effects";
strings_["acrylic"] = "Acrylic";
strings_["noise"] = "Noise";
strings_["ui_opacity"] = "UI Opacity";
strings_["window_opacity"] = "Window Opacity";
strings_["font_scale"] = "Font Scale";
strings_["refresh"] = "Refresh";
strings_["website"] = "Website";
strings_["report_bug"] = "Report Bug";
strings_["save_settings"] = "Save Settings";
strings_["reset_to_defaults"] = "Reset to Defaults";
// Wallet settings
strings_["save_z_transactions"] = "Save shielded tx history";
strings_["auto_shield"] = "Auto-shield";
strings_["use_tor"] = "Use Tor";
strings_["keep_daemon"] = "Keep daemon running";
strings_["stop_external"] = "Stop external daemon";
strings_["verbose_logging"] = "Verbose logging";
strings_["mine_when_idle"] = "Mine when idle";
strings_["setup_wizard"] = "Run Setup Wizard...";
// RPC / Explorer settings
strings_["rpc_host"] = "Host";
strings_["rpc_port"] = "Port";
strings_["rpc_user"] = "Username";
strings_["rpc_pass"] = "Password";
strings_["transaction_url"] = "Transaction URL";
strings_["address_url"] = "Address URL";
strings_["custom_fees"] = "Allow custom transaction fees";
strings_["fetch_prices"] = "Fetch price data from CoinGecko";
strings_["block_explorer"] = "Block Explorer";
strings_["test_connection"] = "Test Connection";
strings_["rescan"] = "Rescan Blockchain";
// Settings: buttons
strings_["settings_address_book"] = "Address Book...";
strings_["settings_validate_address"] = "Validate Address...";
strings_["settings_request_payment"] = "Request Payment...";
strings_["settings_shield_mining"] = "Shield Mining...";
strings_["settings_merge_to_address"] = "Merge to Address...";
strings_["settings_clear_ztx"] = "Clear Z-Tx History";
strings_["settings_import_key"] = "Import Key...";
strings_["settings_export_key"] = "Export Key...";
strings_["settings_export_all"] = "Export All...";
strings_["settings_backup"] = "Backup...";
strings_["settings_export_csv"] = "Export CSV...";
strings_["settings_encrypt_wallet"] = "Encrypt Wallet";
strings_["settings_change_passphrase"] = "Change Passphrase";
strings_["settings_lock_now"] = "Lock Now";
strings_["settings_remove_encryption"] = "Remove Encryption";
strings_["settings_set_pin"] = "Set PIN";
strings_["settings_change_pin"] = "Change PIN";
strings_["settings_remove_pin"] = "Remove PIN";
strings_["settings_restart_daemon"] = "Restart daemon";
strings_["clear_anyway"] = "Clear Anyway";
// Settings: labels / text
strings_["settings_builtin"] = "Built-in";
strings_["settings_custom"] = "Custom";
strings_["settings_not_found"] = "Not found";
strings_["settings_idle_after"] = "after";
strings_["settings_not_encrypted"] = "Not encrypted";
strings_["settings_locked"] = "Locked";
strings_["settings_unlocked"] = "Unlocked";
strings_["settings_quick_unlock_pin"] = "Quick-unlock PIN";
strings_["settings_pin_active"] = "PIN";
strings_["settings_encrypt_first_pin"] = "Encrypt wallet first to enable PIN";
strings_["incorrect_pin"] = "Incorrect PIN";
strings_["incorrect_passphrase"] = "Incorrect passphrase";
strings_["pin_not_set"] = "PIN not set. Use passphrase to unlock.";
strings_["restarting_after_encryption"] = "Restarting daemon after encryption...";
strings_["force_quit"] = "Force Quit";
strings_["force_quit_warning"] = "This will immediately kill the daemon without a clean shutdown. May require a blockchain resync.";
strings_["force_quit_confirm_title"] = "Force Quit?";
strings_["force_quit_confirm_msg"] = "This will immediately kill the daemon without a clean shutdown.\nThis may corrupt the blockchain index and require a resync.";
strings_["force_quit_yes"] = "Force Quit";
strings_["reduce_motion"] = "Reduce Motion";
strings_["tt_reduce_motion"] = "Disable animated transitions and balance lerp for accessibility";
strings_["ago"] = "ago";
strings_["wizard_daemon_start_failed"] = "Failed to start daemon \xe2\x80\x94 it will be retried automatically";
strings_["settings_data_dir"] = "Data Dir:";
strings_["settings_wallet_size_label"] = "Wallet Size:";
strings_["settings_debug_changed"] = "Debug categories changed \xe2\x80\x94 restart daemon to apply";
strings_["settings_auto_detected"] = "Auto-detected from DRAGONX.conf";
strings_["settings_visual_effects"] = "Visual Effects";
strings_["settings_acrylic_level"] = "Acrylic Level:";
strings_["settings_noise_opacity"] = "Noise Opacity:";
strings_["settings_privacy"] = "Privacy";
strings_["settings_other"] = "Other";
strings_["settings_rpc_connection"] = "RPC Connection";
strings_["settings_configure_rpc"] = "Configure connection to dragonxd daemon";
strings_["settings_wallet_maintenance"] = "Wallet Maintenance";
strings_["settings_wallet_info"] = "Wallet Info";
strings_["settings_block_explorer_urls"] = "Block Explorer URLs";
strings_["settings_configure_explorer"] = "Configure external block explorer links";
strings_["settings_auto_lock"] = "AUTO-LOCK";
strings_["timeout_off"] = "Off";
strings_["timeout_1min"] = "1 min";
strings_["timeout_5min"] = "5 min";
strings_["timeout_15min"] = "15 min";
strings_["timeout_30min"] = "30 min";
strings_["timeout_1hour"] = "1 hour";
strings_["slider_off"] = "Off";
strings_["settings_wallet_file_size"] = "Wallet file size: %s";
strings_["settings_wallet_location"] = "Wallet location: %s";
strings_["settings_rpc_note"] = "Note: Connection settings are usually auto-detected from DRAGONX.conf";
strings_["settings_explorer_hint"] = "URLs should include a trailing slash. The txid/address will be appended.";
strings_["settings_connection"] = "Connection";
strings_["settings_reduce_transparency"] = "Reduce transparency";
strings_["settings_save_shielded_local"] = "Save shielded transaction history locally";
strings_["settings_auto_shield_funds"] = "Auto-shield transparent funds";
strings_["settings_use_tor_network"] = "Use Tor for network connections";
strings_["settings_gradient_bg"] = "Gradient bg";
// Settings: tooltips
strings_["tt_theme_hotkey"] = "Hotkey: Ctrl+Left/Right to cycle themes";
strings_["tt_layout_hotkey"] = "Hotkey: Left/Right arrow keys to cycle Balance layouts";
strings_["tt_language"] = "Interface language for the wallet UI";
strings_["tt_scan_themes"] = "Scan for new themes.\nPlace theme folders in:\n%s";
strings_["tt_low_spec"] = "Disable all heavy visual effects\nHotkey: Ctrl+Shift+Down";
strings_["tt_simple_bg"] = "Use a simple gradient for the background\nHotkey: Ctrl+Up";
strings_["tt_simple_bg_alt"] = "Use a gradient version of the theme background image\nHotkey: Ctrl+Up";
strings_["tt_scanline"] = "CRT scanline effect in console";
strings_["tt_theme_effects"] = "Shimmer, glow, hue-cycling per theme";
strings_["tt_blur"] = "Blur amount (0%% = off, 100%% = maximum)";
strings_["tt_noise"] = "Grain texture intensity (0%% = off, 100%% = maximum)";
strings_["tt_ui_opacity"] = "Card and sidebar opacity (100%% = fully opaque, lower = more see-through)";
strings_["tt_window_opacity"] = "Background opacity (lower = desktop visible through window)";
strings_["tt_font_scale"] = "Scale all text and UI (1.0x = default, up to 1.5x). Hotkey: Alt + Scroll Wheel";
strings_["tt_custom_theme"] = "Custom theme active";
strings_["tt_address_book"] = "Manage saved addresses for quick sending";
strings_["tt_validate"] = "Check if a DragonX address is valid";
strings_["tt_request_payment"] = "Generate a payment request with QR code";
strings_["tt_shield_mining"] = "Move transparent mining rewards to a shielded address";
strings_["tt_merge"] = "Consolidate multiple UTXOs into one address";
strings_["tt_clear_ztx"] = "Delete locally cached z-transaction history";
strings_["tt_save_ztx"] = "Store z-address transaction history locally for faster loading";
strings_["tt_auto_shield"] = "Automatically move transparent balance to shielded addresses for privacy";
strings_["tt_tor"] = "Route daemon connections through the Tor network for anonymity";
strings_["tt_keep_daemon"] = "Daemon will still stop when running the setup wizard";
strings_["tt_stop_external"] = "Applies when connecting to a daemon\nyou started outside this wallet";
strings_["tt_verbose"] = "Log detailed connection diagnostics,\ndaemon state, and port owner info\nto the Console tab";
strings_["tt_mine_idle"] = "Automatically start mining when the\nsystem is idle (no keyboard/mouse input)";
strings_["tt_idle_delay"] = "How long to wait before starting mining";
strings_["tt_wizard"] = "Re-run the initial setup wizard\nDaemon will be restarted";
strings_["tt_open_dir"] = "Click to open in file explorer";
strings_["tt_rpc_host"] = "Hostname of the DragonX daemon";
strings_["tt_rpc_user"] = "RPC authentication username";
strings_["tt_rpc_port"] = "Port for daemon RPC connections";
strings_["tt_rpc_pass"] = "RPC authentication password";
strings_["tt_test_conn"] = "Verify the RPC connection to the daemon";
strings_["tt_rescan"] = "Rescan the blockchain for missing transactions";
strings_["tt_delete_blockchain"] = "Delete all blockchain data and start a fresh sync. Your wallet.dat and config are preserved.";
strings_["delete_blockchain"] = "Delete Blockchain";
strings_["delete_blockchain_confirm"] = "Delete & Resync";
strings_["confirm_delete_blockchain_title"] = "Delete Blockchain Data";
strings_["confirm_delete_blockchain_msg"] = "This will stop the daemon, delete all blockchain data (blocks, chainstate, peers), and start a fresh sync from scratch. This can take several hours to complete.";
strings_["confirm_delete_blockchain_safe"] = "Your wallet.dat, config, and transaction history are safe and will not be deleted.";
strings_["tt_encrypt"] = "Encrypt wallet.dat with a passphrase";
strings_["tt_change_pass"] = "Change the wallet encryption passphrase";
strings_["tt_lock"] = "Lock the wallet immediately";
strings_["tt_remove_encrypt"] = "Remove encryption and store wallet unprotected";
strings_["tt_auto_lock"] = "Lock wallet after this much inactivity";
strings_["tt_set_pin"] = "Set a 4-8 digit PIN for quick unlock";
strings_["tt_change_pin"] = "Change your unlock PIN";
strings_["tt_remove_pin"] = "Remove PIN and require passphrase to unlock";
strings_["tt_tx_url"] = "Base URL for viewing transactions in a block explorer";
strings_["tt_addr_url"] = "Base URL for viewing addresses in a block explorer";
strings_["tt_custom_fees"] = "Enable manual fee entry when sending transactions";
strings_["tt_fetch_prices"] = "Retrieve DRGX market prices from CoinGecko API";
strings_["tt_block_explorer"] = "Open the DragonX block explorer in your browser";
strings_["tt_website"] = "Open the DragonX website";
strings_["tt_report_bug"] = "Report an issue on the project tracker";
strings_["tt_save_settings"] = "Save all settings to disk";
strings_["tt_reset_settings"] = "Reload settings from disk (undo unsaved changes)";
strings_["tt_debug_collapse"] = "Collapse debug logging options";
strings_["tt_debug_expand"] = "Expand debug logging options";
strings_["tt_restart_daemon"] = "Restart the daemon to apply debug logging changes";
// Settings: additional tooltips (keys/data row)
strings_["tt_import_key"] = "Import a private key (zkey or tkey) into this wallet";
strings_["tt_export_key"] = "Export the private key for the selected address";
strings_["tt_export_all"] = "Export all private keys to a file";
strings_["tt_backup"] = "Create a backup of your wallet.dat file";
strings_["tt_export_csv"] = "Export transaction history as a CSV spreadsheet";
// Settings: about / debug
strings_["settings_about_text"] = "A shielded cryptocurrency wallet for DragonX (DRGX), built with Dear ImGui for a lightweight, portable experience.";
strings_["settings_copyright"] = "Copyright 2024-2026 DragonX Developers | GPLv3 License";
strings_["debug_logging"] = "DEBUG LOGGING";
strings_["settings_debug_select"] = "Select categories to enable daemon debug logging (-debug= flags).";
strings_["settings_debug_restart_note"] = "Changes take effect after restarting the daemon.";
// Settings window (legacy dialog) descriptions
strings_["settings_language_note"] = "Note: Some text requires restart to update";
strings_["settings_solid_colors_desc"] = "Use solid colors instead of blur effects (accessibility)";
strings_["settings_gradient_desc"] = "Replace textured backgrounds with smooth gradients";
strings_["settings_save_shielded_desc"] = "Stores z-addr transactions in a local file for viewing";
strings_["settings_auto_shield_desc"] = "Automatically move transparent funds to shielded addresses";
strings_["settings_tor_desc"] = "Route all connections through Tor for enhanced privacy";
strings_["settings_rescan_desc"] = "Rescan blockchain for missing transactions";
strings_["settings_clear_ztx_long"] = "Clear Saved Z-Transaction History";
strings_["settings_clear_ztx_desc"] = "Delete locally stored shielded transaction data";
strings_["settings_wallet_not_found"] = "Wallet file not found";
// Balance tab: address actions
strings_["hide_zero_balances"] = "Hide 0 Balances";
strings_["restore_address"] = "Restore Address";
strings_["hide_address"] = "Hide Address";
strings_["remove_favorite"] = "Remove Favorite";
strings_["favorite_address"] = "Favorite Address";
strings_["show_hidden"] = "Show Hidden (%d)";
// Misc dialog strings
strings_["shield_operation_id"] = "Operation ID: %s";
strings_["peers_peer_label"] = "Peer: %s";
strings_["key_export_click_retrieve"] = "Click to retrieve the key from your wallet";
strings_["backup_source"] = "Source: %s";
strings_["export_keys_progress"] = "Exporting %d/%d...";
strings_["import_key_progress"] = "Importing %d/%d...";
strings_["block_click_copy"] = "Click to copy";
strings_["confirm_clear_ztx_title"] = "Confirm Clear Z-Tx History";
strings_["confirm_clear_ztx_warning1"] = "Clearing z-transaction history may cause your shielded balance to show as 0 until a wallet rescan is performed.";
strings_["confirm_clear_ztx_warning2"] = "If this happens, you will need to re-import your z-address private keys with rescan enabled to recover your balance.";
// Send tab
strings_["sending_from"] = "SENDING FROM";
strings_["recent_sends"] = "RECENT SENDS";
strings_["recipient"] = "RECIPIENT";
strings_["memo_optional"] = "MEMO (OPTIONAL)";
strings_["no_recent_sends"] = "No recent sends";
strings_["network_fee"] = "NETWORK FEE";
strings_["amount_details"] = "AMOUNT DETAILS";
strings_["not_connected_to_daemon"] = "Not connected to daemon";
strings_["select_source_address"] = "Select a source address...";
strings_["no_addresses_with_balance"] = "No addresses with balance";
strings_["blockchain_syncing"] = "Blockchain syncing (%.1f%%)... Balances may be inaccurate.";
strings_["wallet_empty"] = "Your wallet is empty";
strings_["wallet_empty_hint"] = "Switch to Receive to get your address and start receiving funds.";
strings_["go_to_receive"] = "Go to Receive";
strings_["review_send"] = "Review Send";
strings_["fee_low"] = "Low";
strings_["fee_normal"] = "Normal";
strings_["fee_high"] = "High";
strings_["submitting_transaction"] = "Submitting transaction...";
strings_["transaction_sent_msg"] = "Transaction sent!";
strings_["copy_error"] = "Copy Error";
strings_["dismiss"] = "Dismiss";
strings_["clear_form_confirm"] = "Clear all form fields?";
strings_["yes_clear"] = "Yes, Clear";
strings_["keep"] = "Keep";
strings_["undo_clear"] = "Undo Clear";
// Receive tab
strings_["recent_received"] = "RECENT RECEIVED";
strings_["payment_request"] = "PAYMENT REQUEST";
strings_["copy"] = "Copy";
strings_["new"] = "+ New";
strings_["share"] = "Share";
strings_["select_receiving_address"] = "Select a receiving address...";
strings_["no_addresses_match"] = "No addresses match filter";
strings_["no_recent_receives"] = "No recent receives";
strings_["waiting_for_daemon"] = "Waiting for daemon connection...";
strings_["addresses_appear_here"] = "Your receiving addresses will appear here once connected.";
strings_["loading_addresses"] = "Loading addresses...";
strings_["clear_request"] = "Clear Request";
strings_["copy_uri"] = "Copy URI";
strings_["qr_unavailable"] = "QR unavailable";
strings_["received_label"] = "Received";
// Transactions tab
strings_["no_transactions"] = "No transactions found";
strings_["no_matching"] = "No matching transactions";
strings_["transaction_id"] = "TRANSACTION ID";
strings_["search_placeholder"] = "Search...";
strings_["all_filter"] = "All";
strings_["sent_filter"] = "Sent";
strings_["received_filter"] = "Received";
strings_["mined_filter"] = "Mined";
strings_["export_csv"] = "Export CSV";
strings_["transactions_upper"] = "TRANSACTIONS";
strings_["received_upper"] = "RECEIVED";
strings_["sent_upper"] = "SENT";
strings_["mined_upper"] = "MINED";
strings_["from_upper"] = "FROM";
strings_["to_upper"] = "TO";
strings_["shielded_to"] = "SHIELDED TO";
strings_["address_upper"] = "ADDRESS";
strings_["memo_upper"] = "MEMO";
strings_["shielded_type"] = "Shielded";
strings_["recv_type"] = "Recv";
strings_["sent_type"] = "Sent";
strings_["immature_type"] = "Immature";
strings_["mined_type"] = "Mined";
strings_["mature"] = "Mature";
strings_["copy_txid"] = "Copy TxID";
strings_["view_details"] = "View Details";
strings_["full_details"] = "Full Details";
strings_["showing_transactions"] = "Showing %d\xe2\x80\x93%d of %d transactions (total: %zu)";
strings_["txs_count"] = "%d txs";
strings_["conf_count"] = "%d conf";
strings_["confirmations_display"] = "%d confirmations | %s";
// Balance Tab
strings_["summary"] = "Summary";
strings_["shielded"] = "Shielded";
strings_["transparent"] = "Transparent";
strings_["total"] = "Total";
strings_["unconfirmed"] = "Unconfirmed";
strings_["your_addresses"] = "Your Addresses";
strings_["z_addresses"] = "Z-Addresses";
strings_["t_addresses"] = "T-Addresses";
strings_["no_addresses"] = "No addresses found. Create one using the buttons above.";
strings_["new_z_address"] = "New Z-Address";
strings_["new_t_address"] = "New T-Address";
strings_["type"] = "Type";
strings_["address"] = "Address";
strings_["copy_address"] = "Copy Full Address";
strings_["send_from_this_address"] = "Send From This Address";
strings_["export_private_key"] = "Export Private Key";
strings_["export_viewing_key"] = "Export Viewing Key";
strings_["show_qr_code"] = "Show QR Code";
strings_["not_connected"] = "Not connected to daemon...";
// Send Tab
strings_["pay_from"] = "Pay From";
strings_["send_to"] = "Send To";
strings_["amount"] = "Amount";
strings_["memo"] = "Memo (optional, encrypted)";
strings_["miner_fee"] = "Miner Fee";
strings_["fee"] = "Fee";
strings_["send_transaction"] = "Send Transaction";
strings_["clear"] = "Clear";
strings_["select_address"] = "Select address...";
strings_["paste"] = "Paste";
strings_["max"] = "Max";
strings_["available"] = "Available";
strings_["invalid_address"] = "Invalid address format";
strings_["memo_z_only"] = "Note: Memos are only available when sending to shielded (z) addresses";
strings_["characters"] = "characters";
strings_["from"] = "From";
strings_["to"] = "To";
strings_["sending"] = "Sending transaction";
strings_["confirm_send"] = "Confirm Send";
strings_["confirm_transaction"] = "Confirm Transaction";
strings_["confirm_and_send"] = "Confirm & Send";
strings_["cancel"] = "Cancel";
// Receive Tab
strings_["receiving_addresses"] = "Your Receiving Addresses";
strings_["new_z_shielded"] = "New z-Address (Shielded)";
strings_["new_t_transparent"] = "New t-Address (Transparent)";
strings_["address_details"] = "Address Details";
strings_["view_on_explorer"] = "View on Explorer";
strings_["qr_code"] = "QR Code";
strings_["request_payment"] = "Request Payment";
// Transactions Tab
strings_["date"] = "Date";
strings_["status"] = "Status";
strings_["confirmations"] = "Confirmations";
strings_["confirmed"] = "Confirmed";
strings_["pending"] = "Pending";
strings_["sent"] = "sent";
strings_["received"] = "received";
strings_["mined"] = "mined";
// Mining Tab
strings_["mining_control"] = "Mining Control";
strings_["start_mining"] = "Start Mining";
strings_["stop_mining"] = "Stop Mining";
strings_["mining_threads"] = "Mining Threads";
strings_["mining_statistics"] = "Mining Statistics";
strings_["local_hashrate"] = "Local Hashrate";
strings_["network_hashrate"] = "Network Hashrate";
strings_["difficulty"] = "Difficulty";
strings_["est_time_to_block"] = "Est. Time to Block";
strings_["mining_off"] = "Mining is OFF";
strings_["mining_on"] = "Mining is ON";
// Peers Tab
strings_["connected_peers"] = "Connected Peers";
strings_["banned_peers"] = "Banned Peers";
strings_["ip_address"] = "IP Address";
strings_["version"] = "Version";
strings_["height"] = "Height";
strings_["ping"] = "Ping";
strings_["ban"] = "Ban";
strings_["unban"] = "Unban";
strings_["clear_all_bans"] = "Clear All Bans";
// Market Tab
strings_["price_chart"] = "Price Chart";
strings_["current_price"] = "Current Price";
strings_["24h_change"] = "24h Change";
strings_["24h_volume"] = "24h Volume";
strings_["market_cap"] = "Market Cap";
// Settings
strings_["general"] = "General";
strings_["display"] = "Display";
strings_["network"] = "Network";
strings_["theme"] = "Theme";
strings_["language"] = "Language";
strings_["dragonx_green"] = "DragonX (Green)";
strings_["dark"] = "Dark";
strings_["light"] = "Light";
strings_["allow_custom_fees"] = "Allow custom fees";
strings_["use_embedded_daemon"] = "Use embedded dragonxd";
strings_["save"] = "Save";
strings_["close"] = "Close";
// Menu
strings_["file"] = "File";
strings_["edit"] = "Edit";
strings_["view"] = "View";
strings_["help"] = "Help";
strings_["import_private_key"] = "Import Private Key...";
strings_["backup_wallet"] = "Backup Wallet...";
strings_["exit"] = "Exit";
strings_["about_dragonx"] = "About ObsidianDragon";
strings_["refresh_now"] = "Refresh Now";
// Dialogs
strings_["about"] = "About";
strings_["import"] = "Import";
strings_["export"] = "Export";
strings_["copy_to_clipboard"] = "Copy to Clipboard";
// Status
strings_["connected"] = "Connected";
strings_["disconnected"] = "Disconnected";
strings_["connecting"] = "Connecting...";
strings_["syncing"] = "Syncing...";
strings_["block"] = "Block";
strings_["no_addresses_available"] = "No addresses available";
// Errors & Messages
strings_["error"] = "Error";
strings_["success"] = "Success";
strings_["warning"] = "Warning";
strings_["amount_exceeds_balance"] = "Amount exceeds balance";
strings_["transaction_sent"] = "Transaction sent successfully";
// --- Common / Shared ---
strings_["add"] = "Add";
strings_["address_copied"] = "Address copied to clipboard";
strings_["address_label"] = "Address:";
strings_["amount_label"] = "Amount:";
strings_["date_label"] = "Date:";
strings_["delete"] = "Delete";
strings_["fee_label"] = "Fee:";
strings_["file_save_location"] = "File will be saved in: ~/.config/ObsidianDragon/";
strings_["hide"] = "Hide";
strings_["label"] = "Label:";
strings_["loading"] = "Loading...";
strings_["memo_label"] = "Memo:";
strings_["notes"] = "Notes";
strings_["notes_optional"] = "Notes (optional):";
strings_["output_filename"] = "Output filename:";
strings_["paste_from_clipboard"] = "Paste from Clipboard";
strings_["show"] = "Show";
strings_["time_days_ago"] = "%d days ago";
strings_["time_hours_ago"] = "%d hours ago";
strings_["time_minutes_ago"] = "%d minutes ago";
strings_["time_seconds_ago"] = "%d seconds ago";
strings_["unknown"] = "Unknown";
strings_["validating"] = "Validating...";
strings_["warning_upper"] = "WARNING!";
// --- About Dialog ---
strings_["about_block_explorer"] = "Block Explorer";
strings_["about_block_height"] = "Block Height:";
strings_["about_build_date"] = "Build Date:";
strings_["about_build_type"] = "Build Type:";
strings_["about_chain"] = "Chain:";
strings_["about_connections"] = "Connections:";
strings_["about_credits"] = "Credits";
strings_["about_daemon"] = "Daemon:";
strings_["about_debug"] = "Debug";
strings_["about_edition"] = "ImGui Edition";
strings_["about_github"] = "GitHub";
strings_["about_imgui"] = "ImGui:";
strings_["about_license"] = "License";
strings_["about_license_text"] = "This software is released under the GNU General Public License v3 (GPLv3). You are free to use, modify, and distribute this software under the terms of the license.";
strings_["about_peers_count"] = "%zu peers";
strings_["about_release"] = "Release";
strings_["about_title"] = "About ObsidianDragon";
strings_["about_version"] = "Version:";
strings_["about_website"] = "Website";
// --- Address Book Dialog ---
strings_["address_book_add"] = "Add Address";
strings_["address_book_add_new"] = "Add New";
strings_["address_book_added"] = "Address added to book";
strings_["address_book_count"] = "%zu addresses saved";
strings_["address_book_deleted"] = "Entry deleted";
strings_["address_book_edit"] = "Edit Address";
strings_["address_book_empty"] = "No saved addresses. Click 'Add New' to add one.";
strings_["address_book_exists"] = "Address already exists in book";
strings_["address_book_title"] = "Address Book";
strings_["address_book_update_failed"] = "Failed to update - address may be duplicate";
strings_["address_book_updated"] = "Address updated";
// --- Backup Dialog ---
strings_["backup_backing_up"] = "Backing up...";
strings_["backup_create"] = "Create Backup";
strings_["backup_created"] = "Wallet backup created";
strings_["backup_description"] = "Create a backup of your wallet.dat file. This file contains all your private keys and transaction history. Store the backup in a secure location.";
strings_["backup_destination"] = "Backup destination:";
strings_["backup_tip_external"] = "Store backups on external drives or cloud storage";
strings_["backup_tip_multiple"] = "Create multiple backups in different locations";
strings_["backup_tip_test"] = "Test restoring from backup periodically";
strings_["backup_tips"] = "Tips:";
strings_["backup_title"] = "Backup Wallet";
strings_["backup_wallet_not_found"] = "Warning: wallet.dat not found at expected location";
// --- Block Info Dialog ---
strings_["block_bits"] = "Bits:";
strings_["block_click_next"] = "Click to view next block";
strings_["block_click_prev"] = "Click to view previous block";
strings_["block_get_info"] = "Get Block Info";
strings_["block_hash"] = "Block Hash:";
strings_["block_height"] = "Block Height:";
strings_["block_info_title"] = "Block Information";
strings_["block_merkle_root"] = "Merkle Root:";
strings_["block_nav_next"] = "Next >>";
strings_["block_nav_prev"] = "<< Previous";
strings_["block_next"] = "Next Block:";
strings_["block_previous"] = "Previous Block:";
strings_["block_size"] = "Size:";
strings_["block_timestamp"] = "Timestamp:";
strings_["block_transactions"] = "Transactions:";
// --- Console Tab ---
strings_["console_auto_scroll"] = "Auto-scroll";
strings_["console_available_commands"] = "Available commands:";
strings_["console_capturing_output"] = "Capturing daemon output...";
strings_["console_clear"] = "Clear";
strings_["console_clear_console"] = "Clear Console";
strings_["console_cleared"] = "Console cleared";
strings_["console_click_commands"] = "Click commands above to insert them";
strings_["console_click_insert"] = "Click to insert";
strings_["console_click_insert_params"] = "Click to insert with parameters";
strings_["console_close"] = "Close";
strings_["console_commands"] = "Commands";
strings_["console_common_rpc"] = "Common RPC commands:";
strings_["console_completions"] = "Completions:";
strings_["console_connected"] = "Connected to daemon";
strings_["console_copy_all"] = "Copy All";
strings_["console_copy_selected"] = "Copy";
strings_["console_daemon"] = "Daemon";
strings_["console_daemon_error"] = "Daemon error!";
strings_["console_daemon_started"] = "Daemon started";
strings_["console_daemon_stopped"] = "Daemon stopped";
strings_["daemon_version"] = "Daemon";
strings_["console_disconnected"] = "Disconnected from daemon";
strings_["console_errors"] = "Errors";
strings_["console_filter_hint"] = "Filter output...";
strings_["console_help_clear"] = " clear - Clear the console";
strings_["console_help_getbalance"] = " getbalance - Show transparent balance";
strings_["console_help_getblockcount"] = " getblockcount - Show current block height";
strings_["console_help_getinfo"] = " getinfo - Show node information";
strings_["console_help_getmininginfo"] = " getmininginfo - Show mining status";
strings_["console_help_getpeerinfo"] = " getpeerinfo - Show connected peers";
strings_["console_help_gettotalbalance"] = " gettotalbalance - Show total balance";
strings_["console_help_help"] = " help - Show this help message";
strings_["console_help_setgenerate"] = " setgenerate - Control mining";
strings_["console_help_stop"] = " stop - Stop the daemon";
strings_["console_line_count"] = "%zu lines";
strings_["console_new_lines"] = "%d new lines";
strings_["console_no_daemon"] = "No daemon";
strings_["console_not_connected"] = "Error: Not connected to daemon";
strings_["console_rpc_reference"] = "RPC Command Reference";
strings_["console_search_commands"] = "Search commands...";
strings_["console_select_all"] = "Select All";
strings_["console_show_daemon_output"] = "Show daemon output";
strings_["console_show_errors_only"] = "Show errors only";
strings_["console_show_rpc_ref"] = "Show RPC command reference";
strings_["console_showing_lines"] = "Showing %zu of %zu lines";
strings_["console_starting_node"] = "Starting node...";
strings_["console_status_error"] = "Error";
strings_["console_status_running"] = "Running";
strings_["console_status_starting"] = "Starting";
strings_["console_status_stopped"] = "Stopped";
strings_["console_status_stopping"] = "Stopping";
strings_["console_status_unknown"] = "Unknown";
strings_["console_tab_completion"] = "Tab for completion";
strings_["console_type_help"] = "Type 'help' for available commands";
strings_["console_welcome"] = "Welcome to ObsidianDragon Console";
strings_["console_zoom_in"] = "Zoom in";
strings_["console_zoom_out"] = "Zoom out";
// --- Export All Keys Dialog ---
strings_["export_keys_btn"] = "Export Keys";
strings_["export_keys_danger"] = "DANGER: This will export ALL private keys from your wallet! Anyone with access to this file can steal your funds. Store it securely and delete after use.";
strings_["export_keys_include_t"] = "Include T-addresses (transparent)";
strings_["export_keys_include_z"] = "Include Z-addresses (shielded)";
strings_["export_keys_options"] = "Export options:";
strings_["export_keys_success"] = "Keys exported successfully";
strings_["export_keys_title"] = "Export All Private Keys";
// --- Export Transactions Dialog ---
strings_["export_tx_count"] = "Export %zu transactions to CSV file.";
strings_["export_tx_file_fail"] = "Failed to create CSV file";
strings_["export_tx_none"] = "No transactions to export";
strings_["export_tx_success"] = "Transactions exported successfully";
strings_["export_tx_title"] = "Export Transactions to CSV";
// --- Import Key Dialog ---
strings_["import_key_btn"] = "Import Key(s)";
strings_["import_key_formats"] = "Supported key formats:";
strings_["import_key_full_rescan"] = "(0 = full rescan)";
strings_["import_key_label"] = "Private Key(s):";
strings_["import_key_no_valid"] = "No valid keys found in input";
strings_["import_key_rescan"] = "Rescan blockchain after import";
strings_["import_key_start_height"] = "Start height:";
strings_["import_key_success"] = "Keys imported successfully";
strings_["import_key_t_format"] = "T-address WIF private keys";
strings_["import_key_title"] = "Import Private Key";
strings_["import_key_tooltip"] = "Enter one or more private keys, one per line.\nSupports both z-address and t-address keys.\nLines starting with # are treated as comments.";
strings_["import_key_warning"] = "Warning: Never share your private keys! Importing keys from untrusted sources can compromise your wallet.";
strings_["import_key_z_format"] = "Z-address spending keys (secret-extended-key-...)";
// --- Key Export Dialog ---
strings_["key_export_fetching"] = "Fetching key from wallet...";
strings_["key_export_private_key"] = "Private Key:";
strings_["key_export_private_warning"] = "Keep this key SECRET! Anyone with this key can spend your funds. Never share it online or with untrusted parties.";
strings_["key_export_reveal"] = "Reveal Key";
strings_["key_export_viewing_key"] = "Viewing Key:";
strings_["key_export_viewing_warning"] = "This viewing key allows others to see your incoming transactions and balance, but NOT spend your funds. Share only with trusted parties.";
// --- Market Tab ---
strings_["market_12h"] = "12h";
strings_["market_18h"] = "18h";
strings_["market_24h"] = "24h";
strings_["market_24h_volume"] = "24H VOLUME";
strings_["market_6h"] = "6h";
strings_["market_attribution"] = "Price data from NonKYC";
strings_["market_btc_price"] = "BTC PRICE";
strings_["market_no_history"] = "No price history available";
strings_["market_no_price"] = "No price data";
strings_["market_now"] = "Now";
strings_["market_pct_shielded"] = "%.0f%% Shielded";
strings_["market_portfolio"] = "PORTFOLIO";
strings_["market_price_unavailable"] = "Price data unavailable";
strings_["market_refresh_price"] = "Refresh price data";
strings_["market_trade_on"] = "Trade on %s";
// --- Mining Tab ---
strings_["mining_active"] = "Active";
strings_["mining_address_copied"] = "Mining address copied";
strings_["mining_all_time"] = "All Time";
strings_["mining_already_saved"] = "Pool URL already saved";
strings_["mining_block_copied"] = "Block hash copied";
strings_["mining_chart_1m_ago"] = "1m ago";
strings_["mining_chart_5m_ago"] = "5m ago";
strings_["mining_chart_now"] = "Now";
strings_["mining_chart_start"] = "Start";
strings_["mining_click"] = "Click";
strings_["mining_click_copy_address"] = "Click to copy address";
strings_["mining_click_copy_block"] = "Click to copy block hash";
strings_["mining_click_copy_difficulty"] = "Click to copy difficulty";
strings_["mining_connected"] = "Connected";
strings_["mining_connecting"] = "Connecting...";
strings_["mining_difficulty_copied"] = "Difficulty copied";
strings_["mining_est_block"] = "Est. Block";
strings_["mining_est_daily"] = "Est. Daily";
strings_["mining_filter_all"] = "All";
strings_["mining_filter_tip_all"] = "Show all earnings";
strings_["mining_filter_tip_pool"] = "Show pool earnings only";
strings_["mining_filter_tip_solo"] = "Show solo earnings only";
strings_["mining_idle_off_tooltip"] = "Enable idle mining";
strings_["mining_idle_on_tooltip"] = "Disable idle mining";
strings_["mining_idle_scale_on_tooltip"] = "Thread scaling: ON\nClick to switch to start/stop mode";
strings_["mining_idle_scale_off_tooltip"] = "Start/stop mode: ON\nClick to switch to thread scaling mode";
strings_["mining_idle_gpu_on_tooltip"] = "GPU-aware: ON\nGPU activity (video, games) prevents idle mining\nClick for unrestricted mode";
strings_["mining_idle_gpu_off_tooltip"] = "Unrestricted: ON\nOnly keyboard/mouse input determines idle state\nClick to enable GPU-aware detection";
strings_["mining_idle_threads_active_tooltip"] = "Threads when user is active";
strings_["mining_idle_threads_idle_tooltip"] = "Threads when system is idle";
strings_["mining_local_hashrate"] = "Local Hashrate";
strings_["mining_mine"] = "Mine";
strings_["mining_mining_addr"] = "Mining Addr";
strings_["mining_network"] = "Network";
strings_["mining_no_blocks_yet"] = "No blocks found yet";
strings_["mining_no_payouts_yet"] = "No pool payouts yet";
strings_["mining_no_saved_addresses"] = "No saved addresses";
strings_["mining_no_saved_pools"] = "No saved pools";
strings_["mining_open_in_explorer"] = "Open in explorer";
strings_["mining_payout_address"] = "Payout Address";
strings_["mining_payout_tooltip"] = "Address to receive mining rewards";
strings_["mining_generate_z_address_hint"] = "Generate a Z address in the Receive tab to use as your payout address";
strings_["mining_pool"] = "Pool";
strings_["mining_pool_hashrate"] = "Pool Hashrate";
strings_["mining_pool_url"] = "Pool URL";
strings_["mining_recent_blocks"] = "RECENT BLOCKS";
strings_["mining_recent_payouts"] = "RECENT POOL PAYOUTS";
strings_["mining_remove"] = "Remove";
strings_["mining_reset_defaults"] = "Reset Defaults";
strings_["mining_benchmark_tooltip"] = "Find optimal thread count for this CPU";
strings_["mining_benchmark_testing"] = "Testing";
strings_["mining_benchmark_cooling"] = "Cooling";
strings_["mining_benchmark_stabilizing"] = "Stabilizing";
strings_["mining_benchmark_cancel"] = "Cancel benchmark";
strings_["mining_benchmark_result"] = "Optimal";
strings_["mining_benchmark_dismiss"] = "Dismiss";
strings_["mining_save_payout_address"] = "Save payout address";
strings_["mining_save_pool_url"] = "Save pool URL";
strings_["mining_saved_addresses"] = "Saved Addresses:";
strings_["mining_saved_pools"] = "Saved Pools:";
strings_["mining_shares"] = "Shares";
strings_["mining_show_chart"] = "Chart";
strings_["mining_show_log"] = "Log";
strings_["mining_solo"] = "Solo";
strings_["mining_starting"] = "Starting...";
strings_["mining_starting_tooltip"] = "Miner is starting...";
strings_["mining_stop"] = "Stop";
strings_["mining_stop_solo_for_pool"] = "Stop solo mining before starting pool mining";
strings_["mining_stop_solo_for_pool_settings"] = "Stop solo mining to change pool settings";
strings_["mining_stopping"] = "Stopping...";
strings_["mining_stopping_tooltip"] = "Miner is stopping...";
strings_["mining_syncing_tooltip"] = "Blockchain is syncing...";
strings_["mining_to_save"] = "to save";
strings_["mining_today"] = "Today";
strings_["mining_uptime"] = "Uptime";
strings_["mining_yesterday"] = "Yesterday";
// --- Peers Tab ---
strings_["peers_avg_ping"] = "Avg Ping";
strings_["peers_ban_24h"] = "Ban Peer 24h";
strings_["peers_ban_score"] = "Ban Score: %d";
strings_["peers_banned"] = "Banned";
strings_["peers_banned_count"] = "Banned: %d";
strings_["peers_best_block"] = "Best Block";
strings_["peers_blockchain"] = "BLOCKCHAIN";
strings_["peers_blocks"] = "Blocks";
strings_["peers_blocks_left"] = "%d blocks left";
strings_["peers_clear_all_bans"] = "Clear All Bans";
strings_["peers_click_copy"] = "Click to copy";
strings_["peers_connected"] = "Connected";
strings_["peers_connected_count"] = "Connected: %d";
strings_["peers_copy_ip"] = "Copy IP";
strings_["peers_dir_in"] = "In";
strings_["peers_dir_out"] = "Out";
strings_["peers_hash_copied"] = "Hash copied";
strings_["peers_hashrate"] = "Hashrate";
strings_["peers_in_out"] = "In/Out";
strings_["peers_longest"] = "Longest";
strings_["peers_longest_chain"] = "Longest Chain";
strings_["peers_memory"] = "Memory";
strings_["peers_no_banned"] = "No banned peers";
strings_["peers_no_connected"] = "No connected peers";
strings_["peers_no_tls"] = "No TLS";
strings_["peers_notarized"] = "Notarized";
strings_["peers_p2p_port"] = "P2P Port";
strings_["peers_protocol"] = "Protocol";
strings_["peers_received"] = "Received";
strings_["peers_refresh"] = "Refresh";
strings_["peers_refresh_tooltip"] = "Refresh peer list";
strings_["peers_refreshing"] = "Refreshing...";
strings_["peers_sent"] = "Sent";
strings_["peers_tt_id"] = "ID: %d";
strings_["peers_tt_received"] = "Received: %s";
strings_["peers_tt_sent"] = "Sent: %s";
strings_["peers_tt_services"] = "Services: %s";
strings_["peers_tt_start_height"] = "Start Height: %d";
strings_["peers_tt_synced"] = "Synced H/B: %d/%d";
strings_["peers_tt_tls_cipher"] = "TLS: %s";
strings_["peers_unban"] = "Unban";
strings_["peers_upper"] = "PEERS";
strings_["peers_version"] = "Version";
// --- QR Popup Dialog ---
strings_["qr_failed"] = "Failed to generate QR code";
strings_["qr_title"] = "QR Code";
// --- Receive Tab ---
strings_["click_copy_address"] = "Click to copy address";
strings_["click_copy_uri"] = "Click to copy URI";
strings_["generating"] = "Generating";
strings_["failed_create_shielded"] = "Failed to create shielded address";
strings_["failed_create_transparent"] = "Failed to create transparent address";
strings_["new_shielded_created"] = "New shielded address created";
strings_["new_transparent_created"] = "New transparent address created";
strings_["payment_request_copied"] = "Payment request copied";
strings_["payment_uri_copied"] = "Payment URI copied";
// --- Request Payment Dialog ---
strings_["request_amount"] = "Amount (optional):";
strings_["request_copy_uri"] = "Copy URI";
strings_["request_description"] = "Generate a payment request that others can scan or copy. The QR code contains your address and optional amount/memo.";
strings_["request_label"] = "Label (optional):";
strings_["request_memo"] = "Memo (optional):";
strings_["request_payment_uri"] = "Payment URI:";
strings_["request_receive_address"] = "Receive Address:";
strings_["request_select_address"] = "Select address...";
strings_["request_shielded_addrs"] = "-- Shielded Addresses --";
strings_["request_title"] = "Request Payment";
strings_["request_transparent_addrs"] = "-- Transparent Addresses --";
strings_["request_uri_copied"] = "Payment URI copied to clipboard";
// --- Send Tab ---
strings_["send_amount"] = "Amount";
strings_["send_amount_details"] = "AMOUNT DETAILS";
strings_["send_amount_upper"] = "AMOUNT";
strings_["send_clear_fields"] = "Clear all form fields?";
strings_["send_copy_error"] = "Copy Error";
strings_["send_dismiss"] = "Dismiss";
strings_["send_error_copied"] = "Error copied to clipboard";
strings_["send_error_prefix"] = "Error: %s";
strings_["send_exceeds_available"] = "Exceeds available (%.8f)";
strings_["send_fee"] = "Fee";
strings_["send_fee_high"] = "High";
strings_["send_fee_low"] = "Low";
strings_["send_fee_normal"] = "Normal";
strings_["send_form_restored"] = "Form restored";
strings_["send_go_to_receive"] = "Go to Receive";
strings_["send_keep"] = "Keep";
strings_["send_network_fee"] = "NETWORK FEE";
strings_["send_no_balance"] = "No balance";
strings_["send_no_recent"] = "No recent sends";
strings_["send_recent_sends"] = "RECENT SENDS";
strings_["send_recipient"] = "RECIPIENT";
strings_["send_select_source"] = "Select a source address...";
strings_["send_sending_from"] = "SENDING FROM";
strings_["send_submitting"] = "Submitting transaction...";
strings_["send_switch_to_receive"] = "Switch to Receive to get your address and start receiving funds.";
strings_["send_tooltip_enter_amount"] = "Enter an amount to send";
strings_["send_tooltip_exceeds_balance"] = "Amount exceeds available balance";
strings_["send_tooltip_in_progress"] = "Transaction already in progress";
strings_["send_tooltip_invalid_address"] = "Enter a valid recipient address";
strings_["send_tooltip_not_connected"] = "Not connected to daemon";
strings_["send_tooltip_select_source"] = "Select a source address first";
strings_["send_tooltip_syncing"] = "Wait for blockchain to sync";
strings_["send_total"] = "Total";
strings_["send_tx_failed"] = "Transaction failed";
strings_["send_tx_sent"] = "Transaction sent!";
strings_["send_tx_success"] = "Transaction sent successfully!";
strings_["send_txid_copied"] = "TxID copied to clipboard";
strings_["send_txid_label"] = "TxID: %s";
strings_["send_valid_shielded"] = "Valid shielded address";
strings_["send_valid_transparent"] = "Valid transparent address";
strings_["send_wallet_empty"] = "Your wallet is empty";
strings_["send_yes_clear"] = "Yes, Clear";
// --- Shield Dialog ---
strings_["shield_check_status"] = "Check Status";
strings_["shield_completed"] = "Operation completed successfully!";
strings_["shield_description"] = "Shield your mining rewards by sending coinbase outputs from transparent addresses to a shielded address. This improves privacy by hiding your mining income.";
strings_["shield_from_address"] = "From Address:";
strings_["shield_funds"] = "Shield Funds";
strings_["shield_in_progress"] = "Operation in progress...";
strings_["shield_max_utxos"] = "Max UTXOs per operation";
strings_["shield_merge_done"] = "Shield/merge completed!";
strings_["shield_select_z"] = "Select z-address...";
strings_["shield_started"] = "Shield operation started";
strings_["shield_title"] = "Shield Coinbase Rewards";
strings_["shield_to_address"] = "To Address (Shielded):";
strings_["shield_utxo_limit"] = "UTXO Limit:";
strings_["shield_wildcard_hint"] = "Use '*' to shield from all transparent addresses";
strings_["merge_description"] = "Merge multiple UTXOs into a single shielded address. This can help reduce wallet size and improve privacy.";
strings_["merge_funds"] = "Merge Funds";
strings_["merge_started"] = "Merge operation started";
strings_["merge_title"] = "Merge to Address";
// --- Transaction Details Dialog ---
strings_["tx_confirmations"] = "%d confirmations";
strings_["tx_details_title"] = "Transaction Details";
strings_["tx_from_address"] = "From Address:";
strings_["tx_id_label"] = "Transaction ID:";
strings_["tx_immature"] = "IMMATURE";
strings_["tx_mined"] = "MINED";
strings_["tx_received"] = "RECEIVED";
strings_["tx_sent"] = "SENT";
strings_["tx_to_address"] = "To Address:";
strings_["tx_view_explorer"] = "View on Explorer";
// --- Validate Address Dialog ---
strings_["validate_btn"] = "Validate";
strings_["validate_description"] = "Enter a DragonX address to check if it's valid and whether it belongs to this wallet.";
strings_["validate_invalid"] = "INVALID";
strings_["validate_is_mine"] = "This wallet owns this address";
strings_["validate_not_mine"] = "Not owned by this wallet";
strings_["validate_ownership"] = "Ownership:";
strings_["validate_results"] = "Results:";
strings_["validate_shielded_type"] = "Shielded (z-address)";
strings_["validate_status"] = "Status:";
strings_["validate_title"] = "Validate Address";
strings_["validate_transparent_type"] = "Transparent (t-address)";
strings_["validate_type"] = "Type:";
strings_["validate_valid"] = "VALID";
// Misc dialog/tab strings
strings_["ram_wallet_gb"] = "Wallet: %.1f GB";
strings_["ram_wallet_mb"] = "Wallet: %.0f MB";
strings_["ram_daemon_gb"] = "Daemon: %.1f GB (%s)";
strings_["ram_daemon_mb"] = "Daemon: %.0f MB (%s)";
strings_["ram_system_gb"] = "System: %.1f / %.0f GB";
strings_["shield_operation_id"] = "Operation ID: %s";
strings_["peers_peer_label"] = "Peer: %s";
strings_["error_format"] = "Error: %s";
strings_["key_export_click_retrieve"] = "Click to retrieve the key from your wallet";
strings_["key_export_viewing_keys_zonly"] = "Viewing keys are only available for shielded (z) addresses";
strings_["backup_source"] = "Source: %s";
strings_["export_keys_progress"] = "Exporting %d/%d...";
strings_["import_key_progress"] = "Importing %d/%d...";
strings_["click_to_copy"] = "Click to copy";
strings_["block_hash_copied"] = "Block hash copied";
// Explorer tab
strings_["explorer"] = "Explorer";
strings_["explorer_search"] = "Search";
strings_["explorer_chain_stats"] = "Chain";
strings_["explorer_mempool"] = "Mempool";
strings_["explorer_mempool_txs"] = "Transactions";
strings_["explorer_mempool_size"] = "Size";
strings_["explorer_recent_blocks"] = "Recent Blocks";
strings_["explorer_block_detail"] = "Block";
strings_["explorer_block_height"] = "Height";
strings_["explorer_block_hash"] = "Hash";
strings_["explorer_block_txs"] = "Transactions";
strings_["explorer_block_size"] = "Size";
strings_["explorer_block_time"] = "Time";
strings_["explorer_block_merkle"] = "Merkle Root";
strings_["explorer_tx_outputs"] = "Outputs";
strings_["explorer_tx_size"] = "Size";
strings_["explorer_invalid_query"] = "Enter a block height or 64-character hash";
}
const char* I18n::translate(const char* key) const
{
if (!key) return "";
auto it = strings_.find(key);
if (it != strings_.end()) {
return it->second.c_str();
}
// Return key if translation not found
return key;
}
void I18n::registerLanguage(const std::string& code, const std::string& name)
{
// Check if already registered
for (const auto& lang : available_languages_) {
if (lang.first == code) return;
}
available_languages_.emplace_back(code, name);
}
} // namespace util
} // namespace dragonx