feat(ui): say "Node busy" instead of "Launching dragonxd"; honest quit copy
A node rebuilding note witnesses for an hour was shown as "Starting DragonX node... Launching dragonxd", which invited closing it. - Overlay, a new NodeBusy banner and the status bar now say what the node is doing (rebuilding witnesses / catching up on blocks / up but not answering), with the elapsed time and Phase-1 block progress. A rebuild during startup warm-up replaces the stale "-28 Activating best chain" text, and the overlay re-applies its text once a second instead of only on a connect attempt (30s apart while the node is busy). - Quit prompt: elapsed time, "Keep node running & quit" is the default, "Stop anyway & quit" becomes "Stop node & wait" (it no longer kills). - A reinstall skipped because the node is still running now notifies. - Status bar: don't repeat the warm-up status on the right, and don't print "Connected" there in non-English locales. - i18n: 31 new keys in all 8 languages; 10 dead force-quit/old-modal keys removed; CJK subset rebuilt for the new glyphs. - Tests: chooseDaemonStatus, NodeBusy banner priority, and every new key present in all 8 JSONs with matching printf conversions. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Binary file not shown.
+31
-10
@@ -78,6 +78,7 @@
|
||||
"appx_creating_your_wallet": "Ihr Wallet wird erstellt…",
|
||||
"appx_daemon_error": "Daemon-Fehler",
|
||||
"appx_daemon_reinstall_in_progress": "Die Daemon-Neuinstallation läuft bereits.",
|
||||
"appx_daemon_reinstall_node_busy": "Der Node läuft noch, daher wurde der Daemon nicht neu installiert. Versuchen Sie es erneut, sobald er beendet ist.",
|
||||
"appx_disconnecting": "Verbindung wird getrennt...",
|
||||
"appx_done": "Fertig",
|
||||
"appx_dragonxd_output": "dragonxd-Ausgabe",
|
||||
@@ -99,7 +100,6 @@
|
||||
"appx_no_bundled_daemon_to_install": "Dieser Build enthält keinen mitgelieferten Daemon zur Installation",
|
||||
"appx_no_embedded_daemon_to_install": "Dieser Build enthält keinen eingebetteten Daemon zur Installation",
|
||||
"appx_node_busy_restarting": "Der Node ist mit dem Neustart beschäftigt — versuchen Sie es gleich erneut.",
|
||||
"appx_node_rebuilding_witness_cache": "Node baut seinen Witness-Cache neu auf",
|
||||
"appx_not_next_word": " — das ist nicht das nächste Wort",
|
||||
"appx_payment_request_loaded": "Zahlungsanforderung geladen",
|
||||
"appx_pool_miner_connected_and_hashing": "Pool-Miner verbunden und aktiv.",
|
||||
@@ -120,11 +120,7 @@
|
||||
"appx_simple_background_enabled": "Einfacher Hintergrund aktiviert",
|
||||
"appx_skip": "Überspringen",
|
||||
"appx_skip_anyway": "Trotzdem überspringen",
|
||||
"appx_still_status_prefix": "Weiterhin \"",
|
||||
"appx_still_status_suffix": "\" — ein erzwungenes Beenden jetzt kann die Chain-Daten beschädigen.",
|
||||
"appx_stop_anyway_and_quit": "Trotzdem stoppen & beenden",
|
||||
"appx_stopping_daemon_deleting_blockchain": "Daemon wird gestoppt und Blockchain-Daten werden gelöscht...",
|
||||
"appx_stopping_node_discards_rebuild": "Wenn Sie den Node jetzt stoppen, wird der laufende Neuaufbau verworfen und beim nächsten Öffnen des Wallets neu gestartet (mehrere Minuten). Sie können den Node stattdessen weiterlaufen lassen.",
|
||||
"appx_stopping_pool_miner": "Pool-Miner wird gestoppt...",
|
||||
"appx_syncing_pct_block_n_of_n": "Synchronisierung %.1f%% — Block %d / %d",
|
||||
"appx_tap_words_in_order": "Tippen Sie die Wörter in der richtigen Reihenfolge an, um zu bestätigen, dass Sie sie gespeichert haben.",
|
||||
@@ -867,11 +863,6 @@
|
||||
"file_save_location": "Datei wird gespeichert in: ~/.config/ObsidianDragon/",
|
||||
"filter": "Filtern...",
|
||||
"font_scale": "Schriftgröße",
|
||||
"force_quit": "Sofort beenden",
|
||||
"force_quit_confirm_msg": "Dies wird den Daemon sofort beenden ohne sauberes Herunterfahren.\nDies kann den Blockchain-Index beschädigen und eine Neusynchronisierung erfordern.",
|
||||
"force_quit_confirm_title": "Sofort beenden?",
|
||||
"force_quit_warning": "Dies wird den Daemon sofort beenden ohne sauberes Herunterfahren. Kann eine Neusynchronisierung der Blockchain erfordern.",
|
||||
"force_quit_yes": "Sofort beenden",
|
||||
"from": "Von",
|
||||
"from_upper": "VON",
|
||||
"full_details": "Alle Details",
|
||||
@@ -1358,7 +1349,19 @@
|
||||
"node_banner_offline_title": "Nicht mit dem DragonX-Node verbunden",
|
||||
"node_banner_reconnect": "Erneut verbinden",
|
||||
"node_banner_restart": "Node neu starten",
|
||||
"node_busy_rebuild_desc": "Läuft seit %s. Bei großen Wallets kann das etwa eine Stunde dauern, und der Node kann der Wallet erst danach antworten.",
|
||||
"node_busy_rebuild_extending": "Witnesses werden erweitert (der Node meldet für diesen Schritt keinen Fortschritt).",
|
||||
"node_busy_rebuild_reading": "Blöcke werden gelesen: %ld / %ld",
|
||||
"node_busy_rebuild_title": "Node beschäftigt: Note-Witnesses werden neu aufgebaut",
|
||||
"node_busy_replay_desc": "Läuft seit %s. Der Node wendet Blöcke erneut an, die er vor dem letzten Beenden empfangen hat.",
|
||||
"node_busy_replay_title": "Node beschäftigt: Blöcke werden nachgeholt",
|
||||
"node_busy_rpc_desc": "Der Node läuft, ist aber seit %s zu beschäftigt, um der Wallet zu antworten – meist wegen eines langen Vorgangs wie dem Neuaufbau der Witnesses.",
|
||||
"node_busy_rpc_title": "Node beschäftigt: antwortet noch nicht",
|
||||
"node_busy_running": "Läuft seit %s",
|
||||
"node_security": "KNOTEN & SICHERHEIT",
|
||||
"node_starting_busy_desc": "Der Node ist erreichbar, aber beschäftigt und antwortet noch nicht. Das ist nach einem Update oder beim ersten Start normal und kann einige Minuten dauern.",
|
||||
"node_starting_launch_desc": "dragonxd wird gestartet, warte auf Verbindung…",
|
||||
"node_starting_title": "DragonX-Node wird gestartet…",
|
||||
"noise": "Rauschen",
|
||||
"not_connected": "Nicht mit Daemon verbunden...",
|
||||
"not_connected_to_daemon": "Nicht mit Daemon verbunden",
|
||||
@@ -1587,6 +1590,7 @@
|
||||
"sb_net_khs": "Netz: %.2f KH/s",
|
||||
"sb_net_mhs": "Netz: %.2f MH/s",
|
||||
"sb_no_conf": "DRAGONX.conf nicht gefunden",
|
||||
"sb_node_busy": "Node beschäftigt",
|
||||
"sb_peers": "Peers: %zu",
|
||||
"sb_plaintext_remote_blocked": "RPC-Anmeldedaten werden nicht im Klartext an einen entfernten Host gesendet. Füge rpcallowplaintext=1 zu DRAGONX.conf hinzu, um dies zu erlauben, oder aktiviere TLS mit rpctls=1.",
|
||||
"sb_rescanning": "Neuscan",
|
||||
@@ -1850,6 +1854,18 @@
|
||||
"show_qr_code": "QR-Code anzeigen",
|
||||
"showing_transactions": "Zeige %d–%d von %d Transaktionen (gesamt: %zu)",
|
||||
"showing_x_of_y": "%d von %d Adressen angezeigt",
|
||||
"shutdown_kill_confirm_msg": "Der Node zeigt seit Langem keine CPU- oder Festplattenaktivität und hängt möglicherweise.\nWenn Sie ihn erzwungen beenden, geht alles Ungespeicherte verloren; sein nächster Start kann deutlich länger dauern.",
|
||||
"shutdown_kill_confirm_title": "Node erzwungen beenden?",
|
||||
"shutdown_kill_confirm_yes": "Erzwungen beenden",
|
||||
"shutdown_kill_node": "Node erzwungen beenden (unsicher)",
|
||||
"shutdown_kill_node_tip": "Beendet den Node sofort. Alles, was er noch nicht gespeichert hat, geht verloren, und beim nächsten Start spielt er die Blöcke seit dem letzten Speichern erneut ein.",
|
||||
"shutdown_leave_running": "Wallet schließen – Node weiterlaufen lassen",
|
||||
"shutdown_leave_running_tip": "Schließt die Wallet sofort. Der Node läuft allein weiter und beendet, was er gerade tut; nichts geht verloren.",
|
||||
"shutdown_stop_asking": "Node wird zum Beenden aufgefordert…",
|
||||
"shutdown_stop_cpu_suffix": " · CPU %d%%",
|
||||
"shutdown_stop_delivered": "Der Node fährt herunter und speichert seinen Zustand",
|
||||
"shutdown_stop_idle": "Seit %d Min. keine CPU- oder Festplattenaktivität – der Node hängt möglicherweise",
|
||||
"shutdown_stop_queued": "Der Node hat die Stopp-Anforderung erhalten, ist aber beschäftigt – er stoppt, sobald er kann",
|
||||
"simple_background": "Einfacher Hintergrund",
|
||||
"slider_off": "Aus",
|
||||
"sort_amount_high": "Größter Betrag",
|
||||
@@ -1860,6 +1876,11 @@
|
||||
"status": "Status",
|
||||
"stop_external": "Externen Daemon stoppen",
|
||||
"stop_mining": "Mining stoppen",
|
||||
"stopconfirm_busy_body": "Er ist seit %s zu beschäftigt, um der Wallet zu antworten – vermutlich wegen eines langen Vorgangs wie dem Neuaufbau der Witnesses. Wenn Sie ihn jetzt stoppen, muss der nächste Start diese Arbeit eventuell wiederholen.\n\nEmpfohlen: Wallet schließen und den Node weiterlaufen lassen. Er beendet die Arbeit selbstständig.",
|
||||
"stopconfirm_busy_title": "Der Node ist beschäftigt",
|
||||
"stopconfirm_rebuild_body": "Er läuft seit %s, und bei großen Wallets kann das etwa eine Stunde dauern. Wenn Sie den Node jetzt stoppen, wird entweder bis zum Ende des Neuaufbaus gewartet, oder der nächste Start muss den Neuaufbau samt Nachholen wiederholen.\n\nEmpfohlen: Wallet schließen und den Node weiterlaufen lassen. Er beendet die Arbeit selbstständig.",
|
||||
"stopconfirm_rebuild_title": "Der Node baut die Note-Witnesses neu auf",
|
||||
"stopconfirm_stop_wait": "Node stoppen & warten",
|
||||
"stratum_allowip_hint": "Miner von IP oder CIDR zulassen (leer = nur dieser Computer)",
|
||||
"stratum_expose_warn": "Öffnet einen Mining-Port für das von Ihnen zugelassene Netzwerk — nur in einem vertrauenswürdigen LAN verwenden.",
|
||||
"stratum_host": "Mining-Pool hosten (Stratum)",
|
||||
|
||||
+31
-10
@@ -78,6 +78,7 @@
|
||||
"appx_creating_your_wallet": "Creando tu cartera…",
|
||||
"appx_daemon_error": "Error del daemon",
|
||||
"appx_daemon_reinstall_in_progress": "La reinstalación del daemon ya está en curso.",
|
||||
"appx_daemon_reinstall_node_busy": "El nodo sigue en marcha, así que no se reinstaló el daemon. Vuelve a intentarlo cuando se haya detenido.",
|
||||
"appx_disconnecting": "Desconectando...",
|
||||
"appx_done": "Listo",
|
||||
"appx_dragonxd_output": "Salida de dragonxd",
|
||||
@@ -99,7 +100,6 @@
|
||||
"appx_no_bundled_daemon_to_install": "Esta versión no incluye un daemon para instalar",
|
||||
"appx_no_embedded_daemon_to_install": "Esta versión no incluye un daemon integrado para instalar",
|
||||
"appx_node_busy_restarting": "El nodo está ocupado reiniciándose; inténtalo de nuevo en un momento.",
|
||||
"appx_node_rebuilding_witness_cache": "El nodo está reconstruyendo su caché de testigos",
|
||||
"appx_not_next_word": " — esa no es la siguiente palabra",
|
||||
"appx_payment_request_loaded": "Solicitud de pago cargada",
|
||||
"appx_pool_miner_connected_and_hashing": "Minero de pool conectado y calculando hashes.",
|
||||
@@ -120,11 +120,7 @@
|
||||
"appx_simple_background_enabled": "Fondo simple activado",
|
||||
"appx_skip": "Omitir",
|
||||
"appx_skip_anyway": "Omitir de todos modos",
|
||||
"appx_still_status_prefix": "Aún \"",
|
||||
"appx_still_status_suffix": "\" — forzar el cierre ahora podría dañar los datos de la cadena.",
|
||||
"appx_stop_anyway_and_quit": "Detener de todos modos y salir",
|
||||
"appx_stopping_daemon_deleting_blockchain": "Deteniendo el daemon y eliminando los datos de la cadena de bloques...",
|
||||
"appx_stopping_node_discards_rebuild": "Detener el nodo ahora descarta la reconstrucción en curso y la reinicia (varios minutos) la próxima vez que abras la cartera. También puedes dejar el nodo en ejecución.",
|
||||
"appx_stopping_pool_miner": "Deteniendo el minero de pool...",
|
||||
"appx_syncing_pct_block_n_of_n": "Sincronizando %.1f%% — Bloque %d / %d",
|
||||
"appx_tap_words_in_order": "Toca las palabras en el orden correcto para confirmar que las guardaste.",
|
||||
@@ -867,11 +863,6 @@
|
||||
"file_save_location": "El archivo se guardará en: ~/.config/ObsidianDragon/",
|
||||
"filter": "Filtrar...",
|
||||
"font_scale": "Escala de fuente",
|
||||
"force_quit": "Forzar Salida",
|
||||
"force_quit_confirm_msg": "Esto matará inmediatamente el daemon sin un apagado limpio.\nEsto puede corromper el índice de la blockchain y requerir una resincronización.",
|
||||
"force_quit_confirm_title": "¿Forzar Salida?",
|
||||
"force_quit_warning": "Esto matará inmediatamente el daemon sin un apagado limpio. Puede requerir una resincronización de la blockchain.",
|
||||
"force_quit_yes": "Forzar Salida",
|
||||
"from": "Desde",
|
||||
"from_upper": "DESDE",
|
||||
"full_details": "Detalles Completos",
|
||||
@@ -1358,7 +1349,19 @@
|
||||
"node_banner_offline_title": "No conectado al nodo DragonX",
|
||||
"node_banner_reconnect": "Reconectar",
|
||||
"node_banner_restart": "Reiniciar nodo",
|
||||
"node_busy_rebuild_desc": "En curso desde hace %s. En carteras grandes puede tardar alrededor de una hora, y el nodo no puede responder a la cartera hasta que termine.",
|
||||
"node_busy_rebuild_extending": "Ampliando testigos (el nodo no informa del progreso de este paso).",
|
||||
"node_busy_rebuild_reading": "Leyendo bloques: %ld / %ld",
|
||||
"node_busy_rebuild_title": "Nodo ocupado: reconstruyendo testigos de notas",
|
||||
"node_busy_replay_desc": "En curso desde hace %s. El nodo está volviendo a aplicar bloques que recibió antes de detenerse por última vez.",
|
||||
"node_busy_replay_title": "Nodo ocupado: poniéndose al día con los bloques",
|
||||
"node_busy_rpc_desc": "El nodo está en marcha, pero lleva %s demasiado ocupado para responder a la cartera, normalmente por una operación larga como la reconstrucción de testigos.",
|
||||
"node_busy_rpc_title": "Nodo ocupado: aún no responde",
|
||||
"node_busy_running": "En curso desde hace %s",
|
||||
"node_security": "NODO Y SEGURIDAD",
|
||||
"node_starting_busy_desc": "El nodo está accesible pero ocupado y aún no responde. Es normal tras una actualización o en el primer inicio; puede tardar unos minutos.",
|
||||
"node_starting_launch_desc": "Iniciando dragonxd y esperando a que esté en línea…",
|
||||
"node_starting_title": "Iniciando el nodo DragonX…",
|
||||
"noise": "Ruido",
|
||||
"not_connected": "No conectado al daemon...",
|
||||
"not_connected_to_daemon": "No conectado al daemon",
|
||||
@@ -1587,6 +1590,7 @@
|
||||
"sb_net_khs": "Red: %.2f KH/s",
|
||||
"sb_net_mhs": "Red: %.2f MH/s",
|
||||
"sb_no_conf": "DRAGONX.conf no encontrado",
|
||||
"sb_node_busy": "Nodo ocupado",
|
||||
"sb_peers": "Pares: %zu",
|
||||
"sb_plaintext_remote_blocked": "Se rechaza enviar credenciales RPC en texto plano a un host remoto. Añade rpcallowplaintext=1 a DRAGONX.conf para permitirlo, o habilita TLS con rpctls=1.",
|
||||
"sb_rescanning": "Reescaneando",
|
||||
@@ -1850,6 +1854,18 @@
|
||||
"show_qr_code": "Mostrar Código QR",
|
||||
"showing_transactions": "Mostrando %d–%d de %d transacciones (total: %zu)",
|
||||
"showing_x_of_y": "Mostrando %d de %d direcciones",
|
||||
"shutdown_kill_confirm_msg": "El nodo lleva mucho tiempo sin actividad de CPU ni de disco y puede estar bloqueado.\nSi fuerzas su cierre se perderá todo lo que no haya guardado; su próximo inicio puede tardar mucho más.",
|
||||
"shutdown_kill_confirm_title": "¿Forzar el cierre del nodo?",
|
||||
"shutdown_kill_confirm_yes": "Forzar cierre",
|
||||
"shutdown_kill_node": "Forzar cierre del nodo (inseguro)",
|
||||
"shutdown_kill_node_tip": "Detiene el nodo de inmediato. Se pierde todo lo que no haya guardado, y en el próximo inicio volverá a procesar los bloques desde el último guardado.",
|
||||
"shutdown_leave_running": "Cerrar la cartera y dejar el nodo en marcha",
|
||||
"shutdown_leave_running_tip": "Cierra la cartera ahora. El nodo sigue funcionando por su cuenta y termina lo que está haciendo; no se pierde nada.",
|
||||
"shutdown_stop_asking": "Pidiendo al nodo que se detenga…",
|
||||
"shutdown_stop_cpu_suffix": " · CPU %d%%",
|
||||
"shutdown_stop_delivered": "El nodo se está cerrando y guardando su estado",
|
||||
"shutdown_stop_idle": "Sin actividad de CPU ni de disco desde hace %d min; puede que el nodo esté bloqueado",
|
||||
"shutdown_stop_queued": "El nodo recibió la orden de detenerse, pero está ocupado; se detendrá en cuanto pueda",
|
||||
"simple_background": "Fondo simple",
|
||||
"slider_off": "Apagado",
|
||||
"sort_amount_high": "Mayor importe",
|
||||
@@ -1860,6 +1876,11 @@
|
||||
"status": "Estado",
|
||||
"stop_external": "Detener daemon externo",
|
||||
"stop_mining": "Detener Minería",
|
||||
"stopconfirm_busy_body": "Lleva %s demasiado ocupado para responder a la cartera, probablemente por una operación larga como la reconstrucción de testigos. Detenerlo ahora puede hacer que el próximo inicio repita ese trabajo.\n\nRecomendado: cierra la cartera y deja el nodo en marcha. Terminará por su cuenta.",
|
||||
"stopconfirm_busy_title": "El nodo está ocupado",
|
||||
"stopconfirm_rebuild_body": "Lleva %s en curso, y en carteras grandes puede tardar alrededor de una hora. Detener el nodo ahora o bien espera a que termine la reconstrucción, o bien hace que el próximo inicio la repita junto con cualquier puesta al día.\n\nRecomendado: cierra la cartera y deja el nodo en marcha. Terminará por su cuenta.",
|
||||
"stopconfirm_rebuild_title": "El nodo está reconstruyendo los testigos de notas",
|
||||
"stopconfirm_stop_wait": "Detener el nodo y esperar",
|
||||
"stratum_allowip_hint": "Permitir mineros desde IP o CIDR (en blanco = solo este equipo)",
|
||||
"stratum_expose_warn": "Abre un puerto de minería a la red que permitas — úsalo solo en una LAN de confianza.",
|
||||
"stratum_host": "Alojar un pool de minería (stratum)",
|
||||
|
||||
+31
-10
@@ -78,6 +78,7 @@
|
||||
"appx_creating_your_wallet": "Création de votre portefeuille…",
|
||||
"appx_daemon_error": "Erreur du démon",
|
||||
"appx_daemon_reinstall_in_progress": "La réinstallation du démon est déjà en cours.",
|
||||
"appx_daemon_reinstall_node_busy": "Le nœud est toujours actif, le démon n'a donc pas été réinstallé. Réessayez une fois qu'il sera arrêté.",
|
||||
"appx_disconnecting": "Déconnexion...",
|
||||
"appx_done": "Terminé",
|
||||
"appx_dragonxd_output": "Sortie de dragonxd",
|
||||
@@ -99,7 +100,6 @@
|
||||
"appx_no_bundled_daemon_to_install": "Cette version ne contient aucun démon intégré à installer",
|
||||
"appx_no_embedded_daemon_to_install": "Cette version ne contient aucun démon embarqué à installer",
|
||||
"appx_node_busy_restarting": "Le nœud est occupé à redémarrer — réessayez dans un instant.",
|
||||
"appx_node_rebuilding_witness_cache": "Le nœud reconstruit son cache de témoins",
|
||||
"appx_not_next_word": " — ce n'est pas le mot suivant",
|
||||
"appx_payment_request_loaded": "Demande de paiement chargée",
|
||||
"appx_pool_miner_connected_and_hashing": "Mineur de pool connecté et en cours de hachage.",
|
||||
@@ -120,11 +120,7 @@
|
||||
"appx_simple_background_enabled": "Arrière-plan simple activé",
|
||||
"appx_skip": "Ignorer",
|
||||
"appx_skip_anyway": "Ignorer quand même",
|
||||
"appx_still_status_prefix": "Toujours « ",
|
||||
"appx_still_status_suffix": " » — forcer la fermeture maintenant peut corrompre les données de la chaîne.",
|
||||
"appx_stop_anyway_and_quit": "Arrêter quand même et quitter",
|
||||
"appx_stopping_daemon_deleting_blockchain": "Arrêt du démon et suppression des données de la blockchain...",
|
||||
"appx_stopping_node_discards_rebuild": "Arrêter le nœud maintenant abandonne la reconstruction en cours et la relance (plusieurs minutes) à la prochaine ouverture du portefeuille. Vous pouvez plutôt laisser le nœud en marche.",
|
||||
"appx_stopping_pool_miner": "Arrêt du mineur de pool...",
|
||||
"appx_syncing_pct_block_n_of_n": "Synchronisation %.1f%% — Bloc %d / %d",
|
||||
"appx_tap_words_in_order": "Touchez les mots dans le bon ordre pour confirmer que vous les avez enregistrés.",
|
||||
@@ -867,11 +863,6 @@
|
||||
"file_save_location": "Le fichier sera enregistré dans : ~/.config/ObsidianDragon/",
|
||||
"filter": "Filtrer...",
|
||||
"font_scale": "Taille de police",
|
||||
"force_quit": "Forcer la fermeture",
|
||||
"force_quit_confirm_msg": "Cela tuera immédiatement le daemon sans arrêt propre.\nCela peut corrompre l'index de la blockchain et nécessiter une resynchronisation.",
|
||||
"force_quit_confirm_title": "Forcer la fermeture ?",
|
||||
"force_quit_warning": "Cela tuera immédiatement le daemon sans arrêt propre. Peut nécessiter une resynchronisation de la blockchain.",
|
||||
"force_quit_yes": "Forcer la fermeture",
|
||||
"from": "De",
|
||||
"from_upper": "DE",
|
||||
"full_details": "Tous les détails",
|
||||
@@ -1358,7 +1349,19 @@
|
||||
"node_banner_offline_title": "Non connecté au nœud DragonX",
|
||||
"node_banner_reconnect": "Reconnecter",
|
||||
"node_banner_restart": "Redémarrer le nœud",
|
||||
"node_busy_rebuild_desc": "En cours depuis %s. Pour un gros portefeuille, cela peut prendre environ une heure, et le nœud ne peut pas répondre au portefeuille avant la fin.",
|
||||
"node_busy_rebuild_extending": "Extension des témoins (le nœud ne signale aucune progression pour cette étape).",
|
||||
"node_busy_rebuild_reading": "Lecture des blocs : %ld / %ld",
|
||||
"node_busy_rebuild_title": "Nœud occupé : reconstruction des témoins de notes",
|
||||
"node_busy_replay_desc": "En cours depuis %s. Le nœud réapplique les blocs reçus avant son dernier arrêt.",
|
||||
"node_busy_replay_title": "Nœud occupé : rattrapage des blocs",
|
||||
"node_busy_rpc_desc": "Le nœud fonctionne mais est trop occupé pour répondre au portefeuille depuis %s, généralement à cause d'une longue opération comme la reconstruction des témoins.",
|
||||
"node_busy_rpc_title": "Nœud occupé : ne répond pas encore",
|
||||
"node_busy_running": "En cours depuis %s",
|
||||
"node_security": "NŒUD & SÉCURITÉ",
|
||||
"node_starting_busy_desc": "Le nœud est joignable mais occupé et ne répond pas encore. C'est normal après une mise à jour ou au premier lancement ; cela peut prendre quelques minutes.",
|
||||
"node_starting_launch_desc": "Lancement de dragonxd, en attente de sa disponibilité…",
|
||||
"node_starting_title": "Démarrage du nœud DragonX…",
|
||||
"noise": "Bruit",
|
||||
"not_connected": "Non connecté au daemon...",
|
||||
"not_connected_to_daemon": "Non connecté au daemon",
|
||||
@@ -1587,6 +1590,7 @@
|
||||
"sb_net_khs": "Rés: %.2f KH/s",
|
||||
"sb_net_mhs": "Rés: %.2f MH/s",
|
||||
"sb_no_conf": "DRAGONX.conf introuvable",
|
||||
"sb_node_busy": "Nœud occupé",
|
||||
"sb_peers": "Pairs : %zu",
|
||||
"sb_plaintext_remote_blocked": "Refus d'envoyer les identifiants RPC en clair vers un hôte distant. Ajoutez rpcallowplaintext=1 à DRAGONX.conf pour l'autoriser, ou activez TLS avec rpctls=1.",
|
||||
"sb_rescanning": "Rescan",
|
||||
@@ -1850,6 +1854,18 @@
|
||||
"show_qr_code": "Afficher le code QR",
|
||||
"showing_transactions": "Affichage %d–%d sur %d transactions (total : %zu)",
|
||||
"showing_x_of_y": "Affichage de %d sur %d adresses",
|
||||
"shutdown_kill_confirm_msg": "Le nœud ne montre plus d'activité processeur ni disque depuis longtemps et est peut-être bloqué.\nLe tuer fait perdre tout ce qu'il n'a pas enregistré ; son prochain démarrage peut être beaucoup plus long.",
|
||||
"shutdown_kill_confirm_title": "Tuer le nœud ?",
|
||||
"shutdown_kill_confirm_yes": "Tuer le nœud",
|
||||
"shutdown_kill_node": "Tuer le nœud (risqué)",
|
||||
"shutdown_kill_node_tip": "Arrête le nœud immédiatement. Tout ce qu'il n'a pas enregistré est perdu, et au prochain démarrage il rejouera les blocs depuis son dernier enregistrement.",
|
||||
"shutdown_leave_running": "Fermer le portefeuille — laisser le nœud actif",
|
||||
"shutdown_leave_running_tip": "Ferme le portefeuille maintenant. Le nœud continue de fonctionner seul et termine ce qu'il fait ; rien n'est perdu.",
|
||||
"shutdown_stop_asking": "Demande d'arrêt envoyée au nœud…",
|
||||
"shutdown_stop_cpu_suffix": " · CPU %d%%",
|
||||
"shutdown_stop_delivered": "Le nœud s'arrête et enregistre son état",
|
||||
"shutdown_stop_idle": "Aucune activité processeur ni disque depuis %d min — le nœud est peut-être bloqué",
|
||||
"shutdown_stop_queued": "Le nœud a reçu la demande d'arrêt mais il est occupé — il s'arrêtera dès que possible",
|
||||
"simple_background": "Arrière-plan simple",
|
||||
"slider_off": "Désactivé",
|
||||
"sort_amount_high": "Montant le plus élevé",
|
||||
@@ -1860,6 +1876,11 @@
|
||||
"status": "Statut",
|
||||
"stop_external": "Arrêter le daemon externe",
|
||||
"stop_mining": "Arrêter le minage",
|
||||
"stopconfirm_busy_body": "Il est trop occupé pour répondre au portefeuille depuis %s, probablement à cause d'une longue opération comme la reconstruction des témoins. L'arrêter maintenant peut obliger son prochain démarrage à refaire ce travail.\n\nRecommandé : fermez le portefeuille et laissez le nœud actif. Il terminera seul.",
|
||||
"stopconfirm_busy_title": "Le nœud est occupé",
|
||||
"stopconfirm_rebuild_body": "Elle est en cours depuis %s, et pour un gros portefeuille elle peut prendre environ une heure. Arrêter le nœud maintenant attend la fin de la reconstruction, ou oblige son prochain démarrage à la refaire, rattrapage compris.\n\nRecommandé : fermez le portefeuille et laissez le nœud actif. Il terminera seul.",
|
||||
"stopconfirm_rebuild_title": "Le nœud reconstruit les témoins de notes",
|
||||
"stopconfirm_stop_wait": "Arrêter le nœud et attendre",
|
||||
"stratum_allowip_hint": "Autoriser les mineurs depuis une IP ou un CIDR (vide = cet ordinateur uniquement)",
|
||||
"stratum_expose_warn": "Ouvre un port de minage vers le réseau que vous autorisez — à utiliser uniquement sur un réseau local de confiance.",
|
||||
"stratum_host": "Héberger un pool de minage (stratum)",
|
||||
|
||||
+31
-10
@@ -78,6 +78,7 @@
|
||||
"appx_creating_your_wallet": "ウォレットを作成しています…",
|
||||
"appx_daemon_error": "デーモンエラー",
|
||||
"appx_daemon_reinstall_in_progress": "デーモンの再インストールがすでに進行中です。",
|
||||
"appx_daemon_reinstall_node_busy": "ノードがまだ実行中のため、デーモンは再インストールされませんでした。停止してからもう一度お試しください。",
|
||||
"appx_disconnecting": "切断しています...",
|
||||
"appx_done": "完了",
|
||||
"appx_dragonxd_output": "dragonxd の出力",
|
||||
@@ -99,7 +100,6 @@
|
||||
"appx_no_bundled_daemon_to_install": "このビルドにはインストールできる同梱デーモンがありません",
|
||||
"appx_no_embedded_daemon_to_install": "このビルドにはインストールできる組み込みデーモンがありません",
|
||||
"appx_node_busy_restarting": "ノードが再起動中でビジー状態です。少し待ってから再試行してください。",
|
||||
"appx_node_rebuilding_witness_cache": "ノードがウィットネスキャッシュを再構築しています",
|
||||
"appx_not_next_word": " — 次の単語ではありません",
|
||||
"appx_payment_request_loaded": "支払いリクエストを読み込みました",
|
||||
"appx_pool_miner_connected_and_hashing": "プールマイナーが接続し、ハッシュ計算中です。",
|
||||
@@ -120,11 +120,7 @@
|
||||
"appx_simple_background_enabled": "シンプル背景を有効にしました",
|
||||
"appx_skip": "スキップ",
|
||||
"appx_skip_anyway": "それでもスキップ",
|
||||
"appx_still_status_prefix": "まだ「",
|
||||
"appx_still_status_suffix": "」です — 今強制終了するとチェーンデータが破損する可能性があります。",
|
||||
"appx_stop_anyway_and_quit": "それでも停止して終了",
|
||||
"appx_stopping_daemon_deleting_blockchain": "デーモンを停止し、ブロックチェーンデータを削除しています...",
|
||||
"appx_stopping_node_discards_rebuild": "今ノードを停止すると、進行中の再構築が破棄され、次回ウォレットを開いたときに再度実行されます(数分かかります)。代わりにノードを起動したままにすることもできます。",
|
||||
"appx_stopping_pool_miner": "プールマイナーを停止しています...",
|
||||
"appx_syncing_pct_block_n_of_n": "同期中 %.1f%% — ブロック %d / %d",
|
||||
"appx_tap_words_in_order": "保存したことを確認するため、単語を正しい順番でタップしてください。",
|
||||
@@ -867,11 +863,6 @@
|
||||
"file_save_location": "ファイルの保存先:~/.config/ObsidianDragon/",
|
||||
"filter": "フィルター...",
|
||||
"font_scale": "フォントサイズ",
|
||||
"force_quit": "強制終了",
|
||||
"force_quit_confirm_msg": "クリーンシャットダウンなしでデーモンを即座に終了します。\nブロックチェーンインデックスが破損し、再同期が必要になる可能性があります。",
|
||||
"force_quit_confirm_title": "強制終了しますか?",
|
||||
"force_quit_warning": "クリーンシャットダウンなしでデーモンを即座に終了します。ブロックチェーンの再同期が必要になる場合があります。",
|
||||
"force_quit_yes": "強制終了",
|
||||
"from": "送信元",
|
||||
"from_upper": "送信元",
|
||||
"full_details": "詳細情報",
|
||||
@@ -1358,7 +1349,19 @@
|
||||
"node_banner_offline_title": "DragonX ノードに接続されていません",
|
||||
"node_banner_reconnect": "再接続",
|
||||
"node_banner_restart": "ノードを再起動",
|
||||
"node_busy_rebuild_desc": "経過時間 %s。大きなウォレットでは約 1 時間かかることがあり、完了するまでノードはウォレットに応答できません。",
|
||||
"node_busy_rebuild_extending": "ウィットネスを拡張しています(この段階ではノードは進捗を報告しません)。",
|
||||
"node_busy_rebuild_reading": "ブロックを読み込み中:%ld / %ld",
|
||||
"node_busy_rebuild_title": "ノード処理中:ノートウィットネスを再構築しています",
|
||||
"node_busy_replay_desc": "経過時間 %s。ノードは前回停止する前に受信したブロックを再適用しています。",
|
||||
"node_busy_replay_title": "ノード処理中:ブロックを追いかけています",
|
||||
"node_busy_rpc_desc": "ノードは実行中ですが、%s の間ウォレットに応答できないほど処理中です。通常はウィットネスの再構築などの長時間の処理が原因です。",
|
||||
"node_busy_rpc_title": "ノード処理中:まだ応答していません",
|
||||
"node_busy_running": "経過時間 %s",
|
||||
"node_security": "ノードとセキュリティ",
|
||||
"node_starting_busy_desc": "ノードには接続できますが処理中のため、まだ応答していません。更新後や初回起動時には正常な状態で、数分かかることがあります。",
|
||||
"node_starting_launch_desc": "dragonxd を起動し、オンラインになるのを待っています…",
|
||||
"node_starting_title": "DragonX ノードを起動しています…",
|
||||
"noise": "ノイズ",
|
||||
"not_connected": "デーモンに未接続...",
|
||||
"not_connected_to_daemon": "デーモンに未接続",
|
||||
@@ -1587,6 +1590,7 @@
|
||||
"sb_net_khs": "ネット: %.2f KH/s",
|
||||
"sb_net_mhs": "ネット: %.2f MH/s",
|
||||
"sb_no_conf": "DRAGONX.conf が見つかりません",
|
||||
"sb_node_busy": "ノード処理中",
|
||||
"sb_peers": "ピア: %zu",
|
||||
"sb_plaintext_remote_blocked": "リモートホストへRPC認証情報を平文で送信することを拒否しました。許可するにはDRAGONX.confにrpcallowplaintext=1を追加するか、rpctls=1でTLSを有効にしてください。",
|
||||
"sb_rescanning": "再スキャン",
|
||||
@@ -1850,6 +1854,18 @@
|
||||
"show_qr_code": "QRコードを表示",
|
||||
"showing_transactions": "%d–%d / %d 件の取引を表示中(合計:%zu)",
|
||||
"showing_x_of_y": "%d / %d アドレスを表示",
|
||||
"shutdown_kill_confirm_msg": "ノードは長時間 CPU やディスクの活動がなく、停止している可能性があります。\n強制終了すると保存されていない内容はすべて失われ、次回の起動に大幅に時間がかかることがあります。",
|
||||
"shutdown_kill_confirm_title": "ノードを強制終了しますか?",
|
||||
"shutdown_kill_confirm_yes": "強制終了",
|
||||
"shutdown_kill_node": "ノードを強制終了(危険)",
|
||||
"shutdown_kill_node_tip": "ノードを直ちに終了します。保存されていない内容はすべて失われ、次回の起動時に前回の保存以降のブロックを再処理します。",
|
||||
"shutdown_leave_running": "ウォレットを閉じる — ノードは実行したまま",
|
||||
"shutdown_leave_running_tip": "ウォレットをすぐに閉じます。ノードは単独で実行を続け、処理中の作業を完了します。何も失われません。",
|
||||
"shutdown_stop_asking": "ノードに停止を要求しています…",
|
||||
"shutdown_stop_cpu_suffix": " · CPU %d%%",
|
||||
"shutdown_stop_delivered": "ノードを終了し、状態を保存しています",
|
||||
"shutdown_stop_idle": "%d 分間 CPU やディスクの活動がありません — ノードが停止している可能性があります",
|
||||
"shutdown_stop_queued": "ノードは停止要求を受け取りましたが処理中です — 可能になり次第停止します",
|
||||
"simple_background": "シンプル背景",
|
||||
"slider_off": "オフ",
|
||||
"sort_amount_high": "金額が大きい順",
|
||||
@@ -1860,6 +1876,11 @@
|
||||
"status": "ステータス",
|
||||
"stop_external": "外部デーモンを停止",
|
||||
"stop_mining": "マイニング停止",
|
||||
"stopconfirm_busy_body": "%s の間、ウォレットに応答できないほど処理中です。ウィットネスの再構築などの長時間の処理が原因と考えられます。今停止すると、次回の起動時にその処理をやり直すことがあります。\n\n推奨:ウォレットを閉じ、ノードは実行したままにしてください。ノードは自動的に完了します。",
|
||||
"stopconfirm_busy_title": "ノードは処理中です",
|
||||
"stopconfirm_rebuild_body": "経過時間は %s で、大きなウォレットでは約 1 時間かかることがあります。今ノードを停止すると、再構築の完了まで待つか、次回の起動時に再構築とブロックの追いつきをやり直すことになります。\n\n推奨:ウォレットを閉じ、ノードは実行したままにしてください。ノードは自動的に完了します。",
|
||||
"stopconfirm_rebuild_title": "ノードはノートウィットネスを再構築しています",
|
||||
"stopconfirm_stop_wait": "ノードを停止して待つ",
|
||||
"stratum_allowip_hint": "マイナーの接続を許可するIPまたはCIDR(空欄=このコンピューターのみ)",
|
||||
"stratum_expose_warn": "許可したネットワークにマイニングポートを公開します — 信頼できるLANでのみ使用してください。",
|
||||
"stratum_host": "マイニングプールをホストする(stratum)",
|
||||
|
||||
+31
-10
@@ -78,6 +78,7 @@
|
||||
"appx_creating_your_wallet": "지갑을 생성하는 중…",
|
||||
"appx_daemon_error": "데몬 오류",
|
||||
"appx_daemon_reinstall_in_progress": "데몬 재설치가 이미 진행 중입니다.",
|
||||
"appx_daemon_reinstall_node_busy": "노드가 아직 실행 중이라 데몬을 다시 설치하지 않았습니다. 노드가 멈춘 뒤 다시 시도하세요.",
|
||||
"appx_disconnecting": "연결 해제 중...",
|
||||
"appx_done": "완료",
|
||||
"appx_dragonxd_output": "dragonxd 출력",
|
||||
@@ -99,7 +100,6 @@
|
||||
"appx_no_bundled_daemon_to_install": "이 빌드에는 설치할 번들 데몬이 없습니다",
|
||||
"appx_no_embedded_daemon_to_install": "이 빌드에는 설치할 내장 데몬이 없습니다",
|
||||
"appx_node_busy_restarting": "노드가 재시작 중입니다 — 잠시 후 다시 시도하세요.",
|
||||
"appx_node_rebuilding_witness_cache": "노드가 위트니스 캐시를 재구성하는 중입니다",
|
||||
"appx_not_next_word": " — 다음 단어가 아닙니다",
|
||||
"appx_payment_request_loaded": "결제 요청을 불러왔습니다",
|
||||
"appx_pool_miner_connected_and_hashing": "풀 채굴기가 연결되어 해싱 중입니다.",
|
||||
@@ -120,11 +120,7 @@
|
||||
"appx_simple_background_enabled": "단순 배경 활성화됨",
|
||||
"appx_skip": "건너뛰기",
|
||||
"appx_skip_anyway": "그래도 건너뛰기",
|
||||
"appx_still_status_prefix": "아직 \"",
|
||||
"appx_still_status_suffix": "\" 상태입니다 — 지금 강제 종료하면 체인 데이터가 손상될 수 있습니다.",
|
||||
"appx_stop_anyway_and_quit": "그래도 중지하고 종료",
|
||||
"appx_stopping_daemon_deleting_blockchain": "데몬을 중지하고 블록체인 데이터를 삭제하는 중...",
|
||||
"appx_stopping_node_discards_rebuild": "지금 노드를 중지하면 진행 중인 재구성이 취소되며, 다음에 지갑을 열 때 다시 시작됩니다(몇 분 소요). 대신 노드를 계속 실행할 수 있습니다.",
|
||||
"appx_stopping_pool_miner": "풀 채굴기를 중지하는 중...",
|
||||
"appx_syncing_pct_block_n_of_n": "동기화 중 %.1f%% — 블록 %d / %d",
|
||||
"appx_tap_words_in_order": "저장한 내용을 확인하도록 단어를 올바른 순서대로 탭하세요.",
|
||||
@@ -867,11 +863,6 @@
|
||||
"file_save_location": "파일 저장 위치: ~/.config/ObsidianDragon/",
|
||||
"filter": "필터...",
|
||||
"font_scale": "글꼴 크기",
|
||||
"force_quit": "강제 종료",
|
||||
"force_quit_confirm_msg": "정상 종료 없이 데몬을 즉시 종료합니다.\n블록체인 인덱스가 손상되어 재동기화가 필요할 수 있습니다.",
|
||||
"force_quit_confirm_title": "강제 종료하시겠습니까?",
|
||||
"force_quit_warning": "정상 종료 없이 데몬을 즉시 종료합니다. 블록체인 재동기화가 필요할 수 있습니다.",
|
||||
"force_quit_yes": "강제 종료",
|
||||
"from": "보낸 곳",
|
||||
"from_upper": "보낸 곳",
|
||||
"full_details": "전체 세부 정보",
|
||||
@@ -1358,7 +1349,19 @@
|
||||
"node_banner_offline_title": "DragonX 노드에 연결되지 않음",
|
||||
"node_banner_reconnect": "재연결",
|
||||
"node_banner_restart": "노드 재시작",
|
||||
"node_busy_rebuild_desc": "%s 동안 진행 중입니다. 큰 지갑은 약 1시간이 걸릴 수 있으며, 끝날 때까지 노드가 지갑에 응답할 수 없습니다.",
|
||||
"node_busy_rebuild_extending": "위트니스 확장 중(이 단계에서는 노드가 진행 상황을 보고하지 않습니다).",
|
||||
"node_busy_rebuild_reading": "블록 읽는 중: %ld / %ld",
|
||||
"node_busy_rebuild_title": "노드 작업 중: 노트 위트니스 재구성 중",
|
||||
"node_busy_replay_desc": "%s 동안 진행 중입니다. 노드가 마지막으로 멈추기 전에 받은 블록을 다시 적용하고 있습니다.",
|
||||
"node_busy_replay_title": "노드 작업 중: 블록 따라잡는 중",
|
||||
"node_busy_rpc_desc": "노드는 실행 중이지만 %s 동안 지갑에 응답할 수 없을 만큼 바쁩니다. 보통 위트니스 재구성 같은 긴 작업 때문입니다.",
|
||||
"node_busy_rpc_title": "노드 작업 중: 아직 응답하지 않음",
|
||||
"node_busy_running": "%s 동안 진행 중",
|
||||
"node_security": "노드 및 보안",
|
||||
"node_starting_busy_desc": "노드에 연결할 수 있지만 바빠서 아직 응답하지 않습니다. 업데이트 후나 처음 실행할 때는 정상이며, 몇 분 걸릴 수 있습니다.",
|
||||
"node_starting_launch_desc": "dragonxd를 시작하고 온라인 상태가 되기를 기다리는 중…",
|
||||
"node_starting_title": "DragonX 노드 시작 중…",
|
||||
"noise": "노이즈",
|
||||
"not_connected": "데몬에 연결되지 않음...",
|
||||
"not_connected_to_daemon": "데몬에 연결되지 않음",
|
||||
@@ -1587,6 +1590,7 @@
|
||||
"sb_net_khs": "네트: %.2f KH/s",
|
||||
"sb_net_mhs": "네트: %.2f MH/s",
|
||||
"sb_no_conf": "DRAGONX.conf를 찾을 수 없음",
|
||||
"sb_node_busy": "노드 작업 중",
|
||||
"sb_peers": "피어: %zu",
|
||||
"sb_plaintext_remote_blocked": "원격 호스트로 RPC 자격 증명을 평문으로 보내는 것을 거부했습니다. 허용하려면 DRAGONX.conf에 rpcallowplaintext=1을 추가하거나 rpctls=1로 TLS를 활성화하세요.",
|
||||
"sb_rescanning": "재스캔",
|
||||
@@ -1850,6 +1854,18 @@
|
||||
"show_qr_code": "QR 코드 표시",
|
||||
"showing_transactions": "%d–%d / %d건의 거래 표시 중 (총: %zu)",
|
||||
"showing_x_of_y": "%d / %d 주소 표시",
|
||||
"shutdown_kill_confirm_msg": "노드가 오랫동안 CPU나 디스크 활동이 없어 멈췄을 수 있습니다.\n강제 종료하면 저장되지 않은 내용이 모두 사라지고, 다음 시작이 훨씬 오래 걸릴 수 있습니다.",
|
||||
"shutdown_kill_confirm_title": "노드를 강제 종료할까요?",
|
||||
"shutdown_kill_confirm_yes": "강제 종료",
|
||||
"shutdown_kill_node": "노드 강제 종료(위험)",
|
||||
"shutdown_kill_node_tip": "노드를 즉시 종료합니다. 저장되지 않은 내용은 모두 사라지며, 다음 시작 시 마지막 저장 이후의 블록을 다시 처리합니다.",
|
||||
"shutdown_leave_running": "지갑 닫기 — 노드는 계속 실행",
|
||||
"shutdown_leave_running_tip": "지갑을 지금 닫습니다. 노드는 혼자 계속 실행되며 진행 중인 작업을 마칩니다. 잃는 것은 없습니다.",
|
||||
"shutdown_stop_asking": "노드에 중지를 요청하는 중…",
|
||||
"shutdown_stop_cpu_suffix": " · CPU %d%%",
|
||||
"shutdown_stop_delivered": "노드가 종료 중이며 상태를 저장하고 있습니다",
|
||||
"shutdown_stop_idle": "%d분 동안 CPU나 디스크 활동이 없습니다 — 노드가 멈췄을 수 있습니다",
|
||||
"shutdown_stop_queued": "노드가 중지 요청을 받았지만 작업 중입니다 — 가능해지면 중지됩니다",
|
||||
"simple_background": "단순 배경",
|
||||
"slider_off": "끔",
|
||||
"sort_amount_high": "금액 큰 순",
|
||||
@@ -1860,6 +1876,11 @@
|
||||
"status": "상태",
|
||||
"stop_external": "외부 데몬 중지",
|
||||
"stop_mining": "채굴 중지",
|
||||
"stopconfirm_busy_body": "%s 동안 지갑에 응답할 수 없을 만큼 바빴습니다. 위트니스 재구성 같은 긴 작업 때문일 가능성이 큽니다. 지금 중지하면 다음 시작 시 그 작업을 다시 해야 할 수 있습니다.\n\n권장: 지갑을 닫고 노드는 계속 실행하세요. 노드가 스스로 마칩니다.",
|
||||
"stopconfirm_busy_title": "노드가 작업 중입니다",
|
||||
"stopconfirm_rebuild_body": "%s 동안 진행 중이며, 큰 지갑은 약 1시간이 걸릴 수 있습니다. 지금 노드를 중지하면 재구성이 끝날 때까지 기다리거나, 다음 시작 시 재구성과 블록 따라잡기를 다시 해야 합니다.\n\n권장: 지갑을 닫고 노드는 계속 실행하세요. 노드가 스스로 마칩니다.",
|
||||
"stopconfirm_rebuild_title": "노드가 노트 위트니스를 재구성하고 있습니다",
|
||||
"stopconfirm_stop_wait": "노드 중지 후 대기",
|
||||
"stratum_allowip_hint": "채굴자를 허용할 IP 또는 CIDR (비워두면 이 컴퓨터만 허용)",
|
||||
"stratum_expose_warn": "허용한 네트워크로 채굴 포트를 엽니다 — 신뢰할 수 있는 LAN에서만 사용하세요.",
|
||||
"stratum_host": "마이닝 풀 호스팅 (stratum)",
|
||||
|
||||
+31
-10
@@ -78,6 +78,7 @@
|
||||
"appx_creating_your_wallet": "Criando sua carteira…",
|
||||
"appx_daemon_error": "Erro do Daemon",
|
||||
"appx_daemon_reinstall_in_progress": "A reinstalação do daemon já está em andamento.",
|
||||
"appx_daemon_reinstall_node_busy": "O nó ainda está em execução, por isso o daemon não foi reinstalado. Tente novamente quando ele tiver parado.",
|
||||
"appx_disconnecting": "Desconectando...",
|
||||
"appx_done": "Concluído",
|
||||
"appx_dragonxd_output": "saída do dragonxd",
|
||||
@@ -99,7 +100,6 @@
|
||||
"appx_no_bundled_daemon_to_install": "Esta versão não tem daemon incluído para instalar",
|
||||
"appx_no_embedded_daemon_to_install": "Esta versão não tem daemon embutido para instalar",
|
||||
"appx_node_busy_restarting": "O nó está ocupado reiniciando — tente novamente em instantes.",
|
||||
"appx_node_rebuilding_witness_cache": "O nó está reconstruindo seu cache de testemunhas",
|
||||
"appx_not_next_word": " — essa não é a próxima palavra",
|
||||
"appx_payment_request_loaded": "Solicitação de pagamento carregada",
|
||||
"appx_pool_miner_connected_and_hashing": "Minerador de pool conectado e processando hashes.",
|
||||
@@ -120,11 +120,7 @@
|
||||
"appx_simple_background_enabled": "Fundo simples ativado",
|
||||
"appx_skip": "Pular",
|
||||
"appx_skip_anyway": "Pular mesmo assim",
|
||||
"appx_still_status_prefix": "Ainda \"",
|
||||
"appx_still_status_suffix": "\" — forçar o encerramento agora pode corromper os dados da chain.",
|
||||
"appx_stop_anyway_and_quit": "Parar mesmo assim e sair",
|
||||
"appx_stopping_daemon_deleting_blockchain": "Parando o daemon e excluindo os dados da blockchain...",
|
||||
"appx_stopping_node_discards_rebuild": "Parar o nó agora descarta a reconstrução em andamento e a reinicia (vários minutos) na próxima vez que você abrir a carteira. Em vez disso, você pode manter o nó em execução.",
|
||||
"appx_stopping_pool_miner": "Parando o minerador de pool...",
|
||||
"appx_syncing_pct_block_n_of_n": "Sincronizando %.1f%% — Bloco %d / %d",
|
||||
"appx_tap_words_in_order": "Toque nas palavras na ordem correta para confirmar que você as salvou.",
|
||||
@@ -867,11 +863,6 @@
|
||||
"file_save_location": "O arquivo será salvo em: ~/.config/ObsidianDragon/",
|
||||
"filter": "Filtrar...",
|
||||
"font_scale": "Escala da Fonte",
|
||||
"force_quit": "Forçar Saída",
|
||||
"force_quit_confirm_msg": "Isso matará imediatamente o daemon sem um desligamento limpo.\nIsso pode corromper o índice da blockchain e exigir uma ressincronização.",
|
||||
"force_quit_confirm_title": "Forçar Saída?",
|
||||
"force_quit_warning": "Isso matará imediatamente o daemon sem um desligamento limpo. Pode exigir uma ressincronização da blockchain.",
|
||||
"force_quit_yes": "Forçar Saída",
|
||||
"from": "De",
|
||||
"from_upper": "DE",
|
||||
"full_details": "Detalhes Completos",
|
||||
@@ -1358,7 +1349,19 @@
|
||||
"node_banner_offline_title": "Não conectado ao nó DragonX",
|
||||
"node_banner_reconnect": "Reconectar",
|
||||
"node_banner_restart": "Reiniciar nó",
|
||||
"node_busy_rebuild_desc": "Em andamento há %s. Em carteiras grandes pode levar cerca de uma hora, e o nó não consegue responder à carteira até terminar.",
|
||||
"node_busy_rebuild_extending": "Estendendo testemunhas (o nó não informa o progresso desta etapa).",
|
||||
"node_busy_rebuild_reading": "Lendo blocos: %ld / %ld",
|
||||
"node_busy_rebuild_title": "Nó ocupado: reconstruindo testemunhas de notas",
|
||||
"node_busy_replay_desc": "Em andamento há %s. O nó está reaplicando blocos que recebeu antes da última parada.",
|
||||
"node_busy_replay_title": "Nó ocupado: recuperando blocos",
|
||||
"node_busy_rpc_desc": "O nó está em execução, mas está ocupado demais para responder à carteira há %s, geralmente por causa de uma operação longa como a reconstrução de testemunhas.",
|
||||
"node_busy_rpc_title": "Nó ocupado: ainda não responde",
|
||||
"node_busy_running": "Em andamento há %s",
|
||||
"node_security": "NÓ & SEGURANÇA",
|
||||
"node_starting_busy_desc": "O nó está acessível, mas ocupado, e ainda não responde. Isso é normal após uma atualização ou na primeira execução; pode levar alguns minutos.",
|
||||
"node_starting_launch_desc": "Iniciando o dragonxd e aguardando ficar online…",
|
||||
"node_starting_title": "Iniciando o nó DragonX…",
|
||||
"noise": "Ruído",
|
||||
"not_connected": "Não conectado ao daemon...",
|
||||
"not_connected_to_daemon": "Não conectado ao daemon",
|
||||
@@ -1587,6 +1590,7 @@
|
||||
"sb_net_khs": "Rede: %.2f KH/s",
|
||||
"sb_net_mhs": "Rede: %.2f MH/s",
|
||||
"sb_no_conf": "DRAGONX.conf não encontrado",
|
||||
"sb_node_busy": "Nó ocupado",
|
||||
"sb_peers": "Pares: %zu",
|
||||
"sb_plaintext_remote_blocked": "Recusando enviar credenciais RPC em texto simples para um host remoto. Adicione rpcallowplaintext=1 ao DRAGONX.conf para permitir, ou habilite TLS com rpctls=1.",
|
||||
"sb_rescanning": "Reescaneando",
|
||||
@@ -1850,6 +1854,18 @@
|
||||
"show_qr_code": "Mostrar Código QR",
|
||||
"showing_transactions": "Mostrando %d–%d de %d transações (total: %zu)",
|
||||
"showing_x_of_y": "Mostrando %d de %d endereços",
|
||||
"shutdown_kill_confirm_msg": "O nó não mostra atividade de CPU nem de disco há muito tempo e pode estar travado.\nForçar o encerramento perde tudo o que não foi salvo; o próximo início pode demorar muito mais.",
|
||||
"shutdown_kill_confirm_title": "Forçar o encerramento do nó?",
|
||||
"shutdown_kill_confirm_yes": "Forçar encerramento",
|
||||
"shutdown_kill_node": "Forçar encerramento do nó (inseguro)",
|
||||
"shutdown_kill_node_tip": "Encerra o nó imediatamente. Tudo o que não foi salvo se perde, e no próximo início ele reprocessa os blocos desde o último salvamento.",
|
||||
"shutdown_leave_running": "Fechar a carteira e deixar o nó em execução",
|
||||
"shutdown_leave_running_tip": "Fecha a carteira agora. O nó continua em execução sozinho e termina o que está fazendo; nada é perdido.",
|
||||
"shutdown_stop_asking": "Pedindo ao nó para parar…",
|
||||
"shutdown_stop_cpu_suffix": " · CPU %d%%",
|
||||
"shutdown_stop_delivered": "O nó está encerrando e salvando seu estado",
|
||||
"shutdown_stop_idle": "Sem atividade de CPU ou disco há %d min; o nó pode estar travado",
|
||||
"shutdown_stop_queued": "O nó recebeu o pedido de parada, mas está ocupado; ele vai parar assim que puder",
|
||||
"simple_background": "Fundo simples",
|
||||
"slider_off": "Desligado",
|
||||
"sort_amount_high": "Maior valor",
|
||||
@@ -1860,6 +1876,11 @@
|
||||
"status": "Status",
|
||||
"stop_external": "Parar daemon externo",
|
||||
"stop_mining": "Parar Mineração",
|
||||
"stopconfirm_busy_body": "Está ocupado demais para responder à carteira há %s, provavelmente por causa de uma operação longa como a reconstrução de testemunhas. Pará-lo agora pode fazer o próximo início refazer esse trabalho.\n\nRecomendado: feche a carteira e deixe o nó em execução. Ele termina sozinho.",
|
||||
"stopconfirm_busy_title": "O nó está ocupado",
|
||||
"stopconfirm_rebuild_body": "Está em andamento há %s, e em carteiras grandes pode levar cerca de uma hora. Parar o nó agora ou espera a reconstrução terminar, ou faz o próximo início refazê-la junto com qualquer recuperação.\n\nRecomendado: feche a carteira e deixe o nó em execução. Ele termina sozinho.",
|
||||
"stopconfirm_rebuild_title": "O nó está reconstruindo as testemunhas de notas",
|
||||
"stopconfirm_stop_wait": "Parar o nó e aguardar",
|
||||
"stratum_allowip_hint": "Permitir mineradores a partir de IP ou CIDR (em branco = apenas este computador)",
|
||||
"stratum_expose_warn": "Abre uma porta de mineração para a rede que você permitir — use apenas em uma LAN confiável.",
|
||||
"stratum_host": "Hospedar um pool de mineração (stratum)",
|
||||
|
||||
+31
-10
@@ -78,6 +78,7 @@
|
||||
"appx_creating_your_wallet": "Создание кошелька…",
|
||||
"appx_daemon_error": "Ошибка демона",
|
||||
"appx_daemon_reinstall_in_progress": "Переустановка демона уже выполняется.",
|
||||
"appx_daemon_reinstall_node_busy": "Узел всё ещё работает, поэтому демон не был переустановлен. Повторите попытку, когда он остановится.",
|
||||
"appx_disconnecting": "Отключение...",
|
||||
"appx_done": "Готово",
|
||||
"appx_dragonxd_output": "вывод dragonxd",
|
||||
@@ -99,7 +100,6 @@
|
||||
"appx_no_bundled_daemon_to_install": "В этой сборке нет встроенного демона для установки",
|
||||
"appx_no_embedded_daemon_to_install": "В этой сборке нет встроенного демона для установки",
|
||||
"appx_node_busy_restarting": "Узел занят перезапуском — попробуйте ещё раз через мгновение.",
|
||||
"appx_node_rebuilding_witness_cache": "Узел перестраивает кэш свидетелей",
|
||||
"appx_not_next_word": " — это не следующее слово",
|
||||
"appx_payment_request_loaded": "Запрос на оплату загружен",
|
||||
"appx_pool_miner_connected_and_hashing": "Пул-майнер подключён и вычисляет хеши.",
|
||||
@@ -120,11 +120,7 @@
|
||||
"appx_simple_background_enabled": "Простой фон включён",
|
||||
"appx_skip": "Пропустить",
|
||||
"appx_skip_anyway": "Всё равно пропустить",
|
||||
"appx_still_status_prefix": "Всё ещё \"",
|
||||
"appx_still_status_suffix": "\" — принудительный выход сейчас может повредить данные цепи.",
|
||||
"appx_stop_anyway_and_quit": "Всё равно остановить и выйти",
|
||||
"appx_stopping_daemon_deleting_blockchain": "Остановка демона и удаление данных блокчейна...",
|
||||
"appx_stopping_node_discards_rebuild": "Остановка узла сейчас отменит текущую перестройку и запустит её заново (несколько минут) при следующем открытии кошелька. Вместо этого можно оставить узел работать.",
|
||||
"appx_stopping_pool_miner": "Остановка пул-майнера...",
|
||||
"appx_syncing_pct_block_n_of_n": "Синхронизация %.1f%% — Блок %d / %d",
|
||||
"appx_tap_words_in_order": "Нажимайте слова в правильном порядке, чтобы подтвердить, что вы их сохранили.",
|
||||
@@ -867,11 +863,6 @@
|
||||
"file_save_location": "Файл будет сохранён в: ~/.config/ObsidianDragon/",
|
||||
"filter": "Фильтр...",
|
||||
"font_scale": "Масштаб шрифта",
|
||||
"force_quit": "Принудительный выход",
|
||||
"force_quit_confirm_msg": "Это немедленно завершит демон без корректного завершения.\nЭто может повредить индекс блокчейна и потребовать повторной синхронизации.",
|
||||
"force_quit_confirm_title": "Принудительный выход?",
|
||||
"force_quit_warning": "Это немедленно завершит демон без корректного завершения. Может потребоваться повторная синхронизация блокчейна.",
|
||||
"force_quit_yes": "Принудительный выход",
|
||||
"from": "От",
|
||||
"from_upper": "ОТ",
|
||||
"full_details": "Полные детали",
|
||||
@@ -1358,7 +1349,19 @@
|
||||
"node_banner_offline_title": "Нет подключения к узлу DragonX",
|
||||
"node_banner_reconnect": "Переподключить",
|
||||
"node_banner_restart": "Перезапустить узел",
|
||||
"node_busy_rebuild_desc": "Выполняется %s. Для больших кошельков это может занять около часа, и до окончания узел не может отвечать кошельку.",
|
||||
"node_busy_rebuild_extending": "Расширение свидетелей (узел не сообщает о ходе этого этапа).",
|
||||
"node_busy_rebuild_reading": "Чтение блоков: %ld / %ld",
|
||||
"node_busy_rebuild_title": "Узел занят: перестройка свидетелей заметок",
|
||||
"node_busy_replay_desc": "Выполняется %s. Узел повторно применяет блоки, полученные до последней остановки.",
|
||||
"node_busy_replay_title": "Узел занят: догоняет блоки",
|
||||
"node_busy_rpc_desc": "Узел работает, но уже %s слишком занят, чтобы отвечать кошельку, обычно из-за долгой операции, например перестройки свидетелей.",
|
||||
"node_busy_rpc_title": "Узел занят: пока не отвечает",
|
||||
"node_busy_running": "Выполняется %s",
|
||||
"node_security": "УЗЕЛ И БЕЗОПАСНОСТЬ",
|
||||
"node_starting_busy_desc": "Узел доступен, но занят и пока не отвечает. Это нормально после обновления или при первом запуске; может занять несколько минут.",
|
||||
"node_starting_launch_desc": "Запуск dragonxd и ожидание его готовности…",
|
||||
"node_starting_title": "Запуск узла DragonX…",
|
||||
"noise": "Шум",
|
||||
"not_connected": "Не подключено к daemon...",
|
||||
"not_connected_to_daemon": "Не подключено к daemon",
|
||||
@@ -1587,6 +1590,7 @@
|
||||
"sb_net_khs": "Сеть: %.2f KH/s",
|
||||
"sb_net_mhs": "Сеть: %.2f MH/s",
|
||||
"sb_no_conf": "DRAGONX.conf не найден",
|
||||
"sb_node_busy": "Узел занят",
|
||||
"sb_peers": "Пиры: %zu",
|
||||
"sb_plaintext_remote_blocked": "Отправка учётных данных RPC открытым текстом на удалённый узел запрещена. Добавьте rpcallowplaintext=1 в DRAGONX.conf, чтобы разрешить, или включите TLS с помощью rpctls=1.",
|
||||
"sb_rescanning": "Пересканирование",
|
||||
@@ -1850,6 +1854,18 @@
|
||||
"show_qr_code": "Показать QR-код",
|
||||
"showing_transactions": "Показано %d–%d из %d транзакций (всего: %zu)",
|
||||
"showing_x_of_y": "Показано %d из %d адресов",
|
||||
"shutdown_kill_confirm_msg": "Узел давно не проявляет активности процессора и диска и, возможно, завис.\nПри принудительном завершении всё несохранённое будет потеряно; следующий запуск может занять гораздо больше времени.",
|
||||
"shutdown_kill_confirm_title": "Принудительно завершить узел?",
|
||||
"shutdown_kill_confirm_yes": "Завершить узел",
|
||||
"shutdown_kill_node": "Принудительно завершить узел (небезопасно)",
|
||||
"shutdown_kill_node_tip": "Немедленно завершает узел. Всё несохранённое будет потеряно, а при следующем запуске он заново обработает блоки с момента последнего сохранения.",
|
||||
"shutdown_leave_running": "Закрыть кошелёк — оставить узел работать",
|
||||
"shutdown_leave_running_tip": "Закрывает кошелёк сейчас. Узел продолжит работать сам и завершит текущую операцию; ничего не теряется.",
|
||||
"shutdown_stop_asking": "Отправка узлу команды остановки…",
|
||||
"shutdown_stop_cpu_suffix": " · ЦП %d%%",
|
||||
"shutdown_stop_delivered": "Узел завершает работу и сохраняет своё состояние",
|
||||
"shutdown_stop_idle": "Нет активности процессора и диска уже %d мин — возможно, узел завис",
|
||||
"shutdown_stop_queued": "Узел получил команду остановки, но занят — он остановится, как только сможет",
|
||||
"simple_background": "Простой фон",
|
||||
"slider_off": "Выкл",
|
||||
"sort_amount_high": "Наибольшая сумма",
|
||||
@@ -1860,6 +1876,11 @@
|
||||
"status": "Статус",
|
||||
"stop_external": "Остановить внешний daemon",
|
||||
"stop_mining": "Остановить майнинг",
|
||||
"stopconfirm_busy_body": "Уже %s он слишком занят, чтобы отвечать кошельку, вероятно, из-за долгой операции, например перестройки свидетелей. Если остановить его сейчас, при следующем запуске эту работу, возможно, придётся выполнить заново.\n\nРекомендуется: закройте кошелёк и оставьте узел работать. Он завершит всё сам.",
|
||||
"stopconfirm_busy_title": "Узел занят",
|
||||
"stopconfirm_rebuild_body": "Она выполняется уже %s, а для больших кошельков может занять около часа. Если остановить узел сейчас, он либо дождётся окончания перестройки, либо при следующем запуске выполнит её заново вместе с догонянием блоков.\n\nРекомендуется: закройте кошелёк и оставьте узел работать. Он завершит всё сам.",
|
||||
"stopconfirm_rebuild_title": "Узел перестраивает свидетелей заметок",
|
||||
"stopconfirm_stop_wait": "Остановить узел и подождать",
|
||||
"stratum_allowip_hint": "Разрешить майнерам подключаться с IP или CIDR (пусто = только этот компьютер)",
|
||||
"stratum_expose_warn": "Открывает порт для майнинга в разрешённую вами сеть — используйте только в доверенной локальной сети.",
|
||||
"stratum_host": "Разместить майнинг-пул (stratum)",
|
||||
|
||||
+31
-10
@@ -78,6 +78,7 @@
|
||||
"appx_creating_your_wallet": "正在创建你的钱包…",
|
||||
"appx_daemon_error": "守护进程错误",
|
||||
"appx_daemon_reinstall_in_progress": "守护进程重新安装已在进行中。",
|
||||
"appx_daemon_reinstall_node_busy": "节点仍在运行,因此未重新安装守护进程。请在它停止后重试。",
|
||||
"appx_disconnecting": "正在断开连接…",
|
||||
"appx_done": "完成",
|
||||
"appx_dragonxd_output": "dragonxd 输出",
|
||||
@@ -99,7 +100,6 @@
|
||||
"appx_no_bundled_daemon_to_install": "此版本没有可安装的捆绑守护进程",
|
||||
"appx_no_embedded_daemon_to_install": "此版本没有可安装的内嵌守护进程",
|
||||
"appx_node_busy_restarting": "节点正忙于重启——请稍后再试。",
|
||||
"appx_node_rebuilding_witness_cache": "节点正在重建其见证缓存",
|
||||
"appx_not_next_word": " — 这不是下一个词",
|
||||
"appx_payment_request_loaded": "支付请求已加载",
|
||||
"appx_pool_miner_connected_and_hashing": "矿池矿工已连接并正在计算哈希。",
|
||||
@@ -120,11 +120,7 @@
|
||||
"appx_simple_background_enabled": "已启用简约背景",
|
||||
"appx_skip": "跳过",
|
||||
"appx_skip_anyway": "仍要跳过",
|
||||
"appx_still_status_prefix": "仍处于“",
|
||||
"appx_still_status_suffix": "”——现在强制退出可能损坏链数据。",
|
||||
"appx_stop_anyway_and_quit": "仍要停止并退出",
|
||||
"appx_stopping_daemon_deleting_blockchain": "正在停止守护进程并删除区块链数据…",
|
||||
"appx_stopping_node_discards_rebuild": "现在停止节点会丢弃正在进行的重建,下次打开钱包时将重新开始(需要几分钟)。你也可以让节点继续运行。",
|
||||
"appx_stopping_pool_miner": "正在停止矿池矿工…",
|
||||
"appx_syncing_pct_block_n_of_n": "正在同步 %.1f%% —— 区块 %d / %d",
|
||||
"appx_tap_words_in_order": "按正确顺序点击这些词,以确认你已保存。",
|
||||
@@ -867,11 +863,6 @@
|
||||
"file_save_location": "文件将保存至:~/.config/ObsidianDragon/",
|
||||
"filter": "筛选...",
|
||||
"font_scale": "字体大小",
|
||||
"force_quit": "强制退出",
|
||||
"force_quit_confirm_msg": "这将立即终止守护进程而不进行正常关闭。\n这可能会损坏区块链索引并需要重新同步。",
|
||||
"force_quit_confirm_title": "强制退出?",
|
||||
"force_quit_warning": "这将立即终止守护进程而不进行正常关闭。可能需要重新同步区块链。",
|
||||
"force_quit_yes": "强制退出",
|
||||
"from": "从",
|
||||
"from_upper": "从",
|
||||
"full_details": "完整详情",
|
||||
@@ -1358,7 +1349,19 @@
|
||||
"node_banner_offline_title": "未连接到 DragonX 节点",
|
||||
"node_banner_reconnect": "重新连接",
|
||||
"node_banner_restart": "重启节点",
|
||||
"node_busy_rebuild_desc": "已运行 %s。大型钱包可能需要约一小时,完成前节点无法响应钱包。",
|
||||
"node_busy_rebuild_extending": "正在扩展见证(此步骤节点不报告进度)。",
|
||||
"node_busy_rebuild_reading": "正在读取区块:%ld / %ld",
|
||||
"node_busy_rebuild_title": "节点繁忙:正在重建票据见证",
|
||||
"node_busy_replay_desc": "已运行 %s。节点正在重新应用上次停止前收到的区块。",
|
||||
"node_busy_replay_title": "节点繁忙:正在追赶区块",
|
||||
"node_busy_rpc_desc": "节点正在运行,但已有 %s 忙于其他任务而无法响应钱包,通常是因为见证重建等耗时操作。",
|
||||
"node_busy_rpc_title": "节点繁忙:暂未响应",
|
||||
"node_busy_running": "已运行 %s",
|
||||
"node_security": "节点与安全",
|
||||
"node_starting_busy_desc": "节点可以访问,但正忙,暂未响应。更新后或首次启动时属正常现象,可能需要几分钟。",
|
||||
"node_starting_launch_desc": "正在启动 dragonxd 并等待其上线…",
|
||||
"node_starting_title": "正在启动 DragonX 节点…",
|
||||
"noise": "噪点",
|
||||
"not_connected": "未连接到守护进程...",
|
||||
"not_connected_to_daemon": "未连接到守护进程",
|
||||
@@ -1587,6 +1590,7 @@
|
||||
"sb_net_khs": "网络: %.2f KH/s",
|
||||
"sb_net_mhs": "网络: %.2f MH/s",
|
||||
"sb_no_conf": "未找到 DRAGONX.conf",
|
||||
"sb_node_busy": "节点繁忙",
|
||||
"sb_peers": "节点: %zu",
|
||||
"sb_plaintext_remote_blocked": "拒绝以明文形式向远程主机发送 RPC 凭据。请在 DRAGONX.conf 中添加 rpcallowplaintext=1 以允许此操作,或启用 rpctls=1 使用 TLS。",
|
||||
"sb_rescanning": "重新扫描",
|
||||
@@ -1850,6 +1854,18 @@
|
||||
"show_qr_code": "显示二维码",
|
||||
"showing_transactions": "显示第 %d–%d 笔,共 %d 笔交易(总计:%zu)",
|
||||
"showing_x_of_y": "显示 %d / %d 个地址",
|
||||
"shutdown_kill_confirm_msg": "节点已长时间没有 CPU 或磁盘活动,可能已卡住。\n强制结束会丢失所有未保存的数据;下次启动可能需要更长时间。",
|
||||
"shutdown_kill_confirm_title": "强制结束节点?",
|
||||
"shutdown_kill_confirm_yes": "强制结束",
|
||||
"shutdown_kill_node": "强制结束节点(不安全)",
|
||||
"shutdown_kill_node_tip": "立即结束节点。所有尚未保存的数据都会丢失,下次启动时会重新处理自上次保存以来的区块。",
|
||||
"shutdown_leave_running": "关闭钱包——保持节点运行",
|
||||
"shutdown_leave_running_tip": "立即关闭钱包。节点会继续独立运行并完成当前操作,不会丢失任何数据。",
|
||||
"shutdown_stop_asking": "正在请求节点停止…",
|
||||
"shutdown_stop_cpu_suffix": " · CPU %d%%",
|
||||
"shutdown_stop_delivered": "节点正在关闭并保存其状态",
|
||||
"shutdown_stop_idle": "已 %d 分钟没有 CPU 或磁盘活动——节点可能已卡住",
|
||||
"shutdown_stop_queued": "节点已收到停止请求,但正忙——它会尽快停止",
|
||||
"simple_background": "简单背景",
|
||||
"slider_off": "关闭",
|
||||
"sort_amount_high": "金额最大",
|
||||
@@ -1860,6 +1876,11 @@
|
||||
"status": "状态",
|
||||
"stop_external": "停止外部守护进程",
|
||||
"stop_mining": "停止挖矿",
|
||||
"stopconfirm_busy_body": "节点已有 %s 忙于其他任务而无法响应钱包,可能是因为见证重建等耗时操作。现在停止它,下次启动时可能需要重做这些工作。\n\n建议:关闭钱包并保持节点运行,它会自行完成。",
|
||||
"stopconfirm_busy_title": "节点正忙",
|
||||
"stopconfirm_rebuild_body": "已运行 %s,大型钱包可能需要约一小时。现在停止节点,要么会等待重建完成,要么下次启动时需要重新进行重建以及区块追赶。\n\n建议:关闭钱包并保持节点运行,它会自行完成。",
|
||||
"stopconfirm_rebuild_title": "节点正在重建票据见证",
|
||||
"stopconfirm_stop_wait": "停止节点并等待",
|
||||
"stratum_allowip_hint": "允许来自指定 IP 或 CIDR 的矿工连接(留空 = 仅限本机)",
|
||||
"stratum_expose_warn": "会向您允许的网络开放挖矿端口——仅在受信任的局域网中使用。",
|
||||
"stratum_host": "托管矿池(stratum)",
|
||||
|
||||
@@ -25,6 +25,244 @@ def load_english_keys():
|
||||
|
||||
# All translations for the 158 missing keys
|
||||
TRANSLATIONS = {
|
||||
# --- Daemon shutdown hardening: stopping the node on quit (never kill unasked) ---
|
||||
"shutdown_leave_running": {
|
||||
"de": "Wallet schließen – Node weiterlaufen lassen", "es": "Cerrar la cartera y dejar el nodo en marcha",
|
||||
"fr": "Fermer le portefeuille — laisser le nœud actif", "pt": "Fechar a carteira e deixar o nó em execução",
|
||||
"ru": "Закрыть кошелёк — оставить узел работать", "zh": "关闭钱包——保持节点运行",
|
||||
"ja": "ウォレットを閉じる — ノードは実行したまま", "ko": "지갑 닫기 — 노드는 계속 실행"
|
||||
},
|
||||
"shutdown_leave_running_tip": {
|
||||
"de": "Schließt die Wallet sofort. Der Node läuft allein weiter und beendet, was er gerade tut; nichts geht verloren.",
|
||||
"es": "Cierra la cartera ahora. El nodo sigue funcionando por su cuenta y termina lo que está haciendo; no se pierde nada.",
|
||||
"fr": "Ferme le portefeuille maintenant. Le nœud continue de fonctionner seul et termine ce qu'il fait ; rien n'est perdu.",
|
||||
"pt": "Fecha a carteira agora. O nó continua em execução sozinho e termina o que está fazendo; nada é perdido.",
|
||||
"ru": "Закрывает кошелёк сейчас. Узел продолжит работать сам и завершит текущую операцию; ничего не теряется.",
|
||||
"zh": "立即关闭钱包。节点会继续独立运行并完成当前操作,不会丢失任何数据。",
|
||||
"ja": "ウォレットをすぐに閉じます。ノードは単独で実行を続け、処理中の作業を完了します。何も失われません。",
|
||||
"ko": "지갑을 지금 닫습니다. 노드는 혼자 계속 실행되며 진행 중인 작업을 마칩니다. 잃는 것은 없습니다."
|
||||
},
|
||||
"shutdown_kill_node": {
|
||||
"de": "Node erzwungen beenden (unsicher)", "es": "Forzar cierre del nodo (inseguro)",
|
||||
"fr": "Tuer le nœud (risqué)", "pt": "Forçar encerramento do nó (inseguro)",
|
||||
"ru": "Принудительно завершить узел (небезопасно)", "zh": "强制结束节点(不安全)",
|
||||
"ja": "ノードを強制終了(危険)", "ko": "노드 강제 종료(위험)"
|
||||
},
|
||||
"shutdown_kill_node_tip": {
|
||||
"de": "Beendet den Node sofort. Alles, was er noch nicht gespeichert hat, geht verloren, und beim nächsten Start spielt er die Blöcke seit dem letzten Speichern erneut ein.",
|
||||
"es": "Detiene el nodo de inmediato. Se pierde todo lo que no haya guardado, y en el próximo inicio volverá a procesar los bloques desde el último guardado.",
|
||||
"fr": "Arrête le nœud immédiatement. Tout ce qu'il n'a pas enregistré est perdu, et au prochain démarrage il rejouera les blocs depuis son dernier enregistrement.",
|
||||
"pt": "Encerra o nó imediatamente. Tudo o que não foi salvo se perde, e no próximo início ele reprocessa os blocos desde o último salvamento.",
|
||||
"ru": "Немедленно завершает узел. Всё несохранённое будет потеряно, а при следующем запуске он заново обработает блоки с момента последнего сохранения.",
|
||||
"zh": "立即结束节点。所有尚未保存的数据都会丢失,下次启动时会重新处理自上次保存以来的区块。",
|
||||
"ja": "ノードを直ちに終了します。保存されていない内容はすべて失われ、次回の起動時に前回の保存以降のブロックを再処理します。",
|
||||
"ko": "노드를 즉시 종료합니다. 저장되지 않은 내용은 모두 사라지며, 다음 시작 시 마지막 저장 이후의 블록을 다시 처리합니다."
|
||||
},
|
||||
"shutdown_kill_confirm_title": {
|
||||
"de": "Node erzwungen beenden?", "es": "¿Forzar el cierre del nodo?", "fr": "Tuer le nœud ?",
|
||||
"pt": "Forçar o encerramento do nó?", "ru": "Принудительно завершить узел?", "zh": "强制结束节点?",
|
||||
"ja": "ノードを強制終了しますか?", "ko": "노드를 강제 종료할까요?"
|
||||
},
|
||||
"shutdown_kill_confirm_msg": {
|
||||
"de": "Der Node zeigt seit Langem keine CPU- oder Festplattenaktivität und hängt möglicherweise.\nWenn Sie ihn erzwungen beenden, geht alles Ungespeicherte verloren; sein nächster Start kann deutlich länger dauern.",
|
||||
"es": "El nodo lleva mucho tiempo sin actividad de CPU ni de disco y puede estar bloqueado.\nSi fuerzas su cierre se perderá todo lo que no haya guardado; su próximo inicio puede tardar mucho más.",
|
||||
"fr": "Le nœud ne montre plus d'activité processeur ni disque depuis longtemps et est peut-être bloqué.\nLe tuer fait perdre tout ce qu'il n'a pas enregistré ; son prochain démarrage peut être beaucoup plus long.",
|
||||
"pt": "O nó não mostra atividade de CPU nem de disco há muito tempo e pode estar travado.\nForçar o encerramento perde tudo o que não foi salvo; o próximo início pode demorar muito mais.",
|
||||
"ru": "Узел давно не проявляет активности процессора и диска и, возможно, завис.\nПри принудительном завершении всё несохранённое будет потеряно; следующий запуск может занять гораздо больше времени.",
|
||||
"zh": "节点已长时间没有 CPU 或磁盘活动,可能已卡住。\n强制结束会丢失所有未保存的数据;下次启动可能需要更长时间。",
|
||||
"ja": "ノードは長時間 CPU やディスクの活動がなく、停止している可能性があります。\n強制終了すると保存されていない内容はすべて失われ、次回の起動に大幅に時間がかかることがあります。",
|
||||
"ko": "노드가 오랫동안 CPU나 디스크 활동이 없어 멈췄을 수 있습니다.\n강제 종료하면 저장되지 않은 내용이 모두 사라지고, 다음 시작이 훨씬 오래 걸릴 수 있습니다."
|
||||
},
|
||||
"shutdown_kill_confirm_yes": {
|
||||
"de": "Erzwungen beenden", "es": "Forzar cierre", "fr": "Tuer le nœud", "pt": "Forçar encerramento",
|
||||
"ru": "Завершить узел", "zh": "强制结束", "ja": "強制終了", "ko": "강제 종료"
|
||||
},
|
||||
"shutdown_stop_asking": {
|
||||
"de": "Node wird zum Beenden aufgefordert…", "es": "Pidiendo al nodo que se detenga…",
|
||||
"fr": "Demande d'arrêt envoyée au nœud…", "pt": "Pedindo ao nó para parar…",
|
||||
"ru": "Отправка узлу команды остановки…", "zh": "正在请求节点停止…",
|
||||
"ja": "ノードに停止を要求しています…", "ko": "노드에 중지를 요청하는 중…"
|
||||
},
|
||||
"shutdown_stop_queued": {
|
||||
"de": "Der Node hat die Stopp-Anforderung erhalten, ist aber beschäftigt – er stoppt, sobald er kann",
|
||||
"es": "El nodo recibió la orden de detenerse, pero está ocupado; se detendrá en cuanto pueda",
|
||||
"fr": "Le nœud a reçu la demande d'arrêt mais il est occupé — il s'arrêtera dès que possible",
|
||||
"pt": "O nó recebeu o pedido de parada, mas está ocupado; ele vai parar assim que puder",
|
||||
"ru": "Узел получил команду остановки, но занят — он остановится, как только сможет",
|
||||
"zh": "节点已收到停止请求,但正忙——它会尽快停止",
|
||||
"ja": "ノードは停止要求を受け取りましたが処理中です — 可能になり次第停止します",
|
||||
"ko": "노드가 중지 요청을 받았지만 작업 중입니다 — 가능해지면 중지됩니다"
|
||||
},
|
||||
"shutdown_stop_delivered": {
|
||||
"de": "Der Node fährt herunter und speichert seinen Zustand", "es": "El nodo se está cerrando y guardando su estado",
|
||||
"fr": "Le nœud s'arrête et enregistre son état", "pt": "O nó está encerrando e salvando seu estado",
|
||||
"ru": "Узел завершает работу и сохраняет своё состояние", "zh": "节点正在关闭并保存其状态",
|
||||
"ja": "ノードを終了し、状態を保存しています", "ko": "노드가 종료 중이며 상태를 저장하고 있습니다"
|
||||
},
|
||||
"shutdown_stop_cpu_suffix": {
|
||||
"de": " · CPU %d%%", "es": " · CPU %d%%", "fr": " · CPU %d%%", "pt": " · CPU %d%%",
|
||||
"ru": " · ЦП %d%%", "zh": " · CPU %d%%", "ja": " · CPU %d%%", "ko": " · CPU %d%%"
|
||||
},
|
||||
"shutdown_stop_idle": {
|
||||
"de": "Seit %d Min. keine CPU- oder Festplattenaktivität – der Node hängt möglicherweise",
|
||||
"es": "Sin actividad de CPU ni de disco desde hace %d min; puede que el nodo esté bloqueado",
|
||||
"fr": "Aucune activité processeur ni disque depuis %d min — le nœud est peut-être bloqué",
|
||||
"pt": "Sem atividade de CPU ou disco há %d min; o nó pode estar travado",
|
||||
"ru": "Нет активности процессора и диска уже %d мин — возможно, узел завис",
|
||||
"zh": "已 %d 分钟没有 CPU 或磁盘活动——节点可能已卡住",
|
||||
"ja": "%d 分間 CPU やディスクの活動がありません — ノードが停止している可能性があります",
|
||||
"ko": "%d분 동안 CPU나 디스크 활동이 없습니다 — 노드가 멈췄을 수 있습니다"
|
||||
},
|
||||
# --- The node is busy: overlay, banner, status bar ---
|
||||
"node_busy_rebuild_title": {
|
||||
"de": "Node beschäftigt: Note-Witnesses werden neu aufgebaut",
|
||||
"es": "Nodo ocupado: reconstruyendo testigos de notas",
|
||||
"fr": "Nœud occupé : reconstruction des témoins de notes",
|
||||
"pt": "Nó ocupado: reconstruindo testemunhas de notas",
|
||||
"ru": "Узел занят: перестройка свидетелей заметок",
|
||||
"zh": "节点繁忙:正在重建票据见证",
|
||||
"ja": "ノード処理中:ノートウィットネスを再構築しています",
|
||||
"ko": "노드 작업 중: 노트 위트니스 재구성 중",
|
||||
},
|
||||
"node_busy_running": {
|
||||
"de": "Läuft seit %s",
|
||||
"es": "En curso desde hace %s",
|
||||
"fr": "En cours depuis %s",
|
||||
"pt": "Em andamento há %s",
|
||||
"ru": "Выполняется %s",
|
||||
"zh": "已运行 %s",
|
||||
"ja": "経過時間 %s",
|
||||
"ko": "%s 동안 진행 중",
|
||||
},
|
||||
"node_busy_rebuild_desc": {
|
||||
"de": "Läuft seit %s. Bei großen Wallets kann das etwa eine Stunde dauern, und der Node kann der Wallet erst danach antworten.",
|
||||
"es": "En curso desde hace %s. En carteras grandes puede tardar alrededor de una hora, y el nodo no puede responder a la cartera hasta que termine.",
|
||||
"fr": "En cours depuis %s. Pour un gros portefeuille, cela peut prendre environ une heure, et le nœud ne peut pas répondre au portefeuille avant la fin.",
|
||||
"pt": "Em andamento há %s. Em carteiras grandes pode levar cerca de uma hora, e o nó não consegue responder à carteira até terminar.",
|
||||
"ru": "Выполняется %s. Для больших кошельков это может занять около часа, и до окончания узел не может отвечать кошельку.",
|
||||
"zh": "已运行 %s。大型钱包可能需要约一小时,完成前节点无法响应钱包。",
|
||||
"ja": "経過時間 %s。大きなウォレットでは約 1 時間かかることがあり、完了するまでノードはウォレットに応答できません。",
|
||||
"ko": "%s 동안 진행 중입니다. 큰 지갑은 약 1시간이 걸릴 수 있으며, 끝날 때까지 노드가 지갑에 응답할 수 없습니다."
|
||||
},
|
||||
"node_busy_rebuild_reading": {
|
||||
"de": "Blöcke werden gelesen: %ld / %ld", "es": "Leyendo bloques: %ld / %ld", "fr": "Lecture des blocs : %ld / %ld",
|
||||
"pt": "Lendo blocos: %ld / %ld", "ru": "Чтение блоков: %ld / %ld", "zh": "正在读取区块:%ld / %ld",
|
||||
"ja": "ブロックを読み込み中:%ld / %ld", "ko": "블록 읽는 중: %ld / %ld"
|
||||
},
|
||||
"node_busy_rebuild_extending": {
|
||||
"de": "Witnesses werden erweitert (der Node meldet für diesen Schritt keinen Fortschritt).",
|
||||
"es": "Ampliando testigos (el nodo no informa del progreso de este paso).",
|
||||
"fr": "Extension des témoins (le nœud ne signale aucune progression pour cette étape).",
|
||||
"pt": "Estendendo testemunhas (o nó não informa o progresso desta etapa).",
|
||||
"ru": "Расширение свидетелей (узел не сообщает о ходе этого этапа).",
|
||||
"zh": "正在扩展见证(此步骤节点不报告进度)。",
|
||||
"ja": "ウィットネスを拡張しています(この段階ではノードは進捗を報告しません)。",
|
||||
"ko": "위트니스 확장 중(이 단계에서는 노드가 진행 상황을 보고하지 않습니다)."
|
||||
},
|
||||
"node_busy_replay_title": {
|
||||
"de": "Node beschäftigt: Blöcke werden nachgeholt", "es": "Nodo ocupado: poniéndose al día con los bloques",
|
||||
"fr": "Nœud occupé : rattrapage des blocs", "pt": "Nó ocupado: recuperando blocos",
|
||||
"ru": "Узел занят: догоняет блоки", "zh": "节点繁忙:正在追赶区块",
|
||||
"ja": "ノード処理中:ブロックを追いかけています", "ko": "노드 작업 중: 블록 따라잡는 중"
|
||||
},
|
||||
"node_busy_replay_desc": {
|
||||
"de": "Läuft seit %s. Der Node wendet Blöcke erneut an, die er vor dem letzten Beenden empfangen hat.",
|
||||
"es": "En curso desde hace %s. El nodo está volviendo a aplicar bloques que recibió antes de detenerse por última vez.",
|
||||
"fr": "En cours depuis %s. Le nœud réapplique les blocs reçus avant son dernier arrêt.",
|
||||
"pt": "Em andamento há %s. O nó está reaplicando blocos que recebeu antes da última parada.",
|
||||
"ru": "Выполняется %s. Узел повторно применяет блоки, полученные до последней остановки.",
|
||||
"zh": "已运行 %s。节点正在重新应用上次停止前收到的区块。",
|
||||
"ja": "経過時間 %s。ノードは前回停止する前に受信したブロックを再適用しています。",
|
||||
"ko": "%s 동안 진행 중입니다. 노드가 마지막으로 멈추기 전에 받은 블록을 다시 적용하고 있습니다."
|
||||
},
|
||||
"node_busy_rpc_title": {
|
||||
"de": "Node beschäftigt: antwortet noch nicht", "es": "Nodo ocupado: aún no responde",
|
||||
"fr": "Nœud occupé : ne répond pas encore", "pt": "Nó ocupado: ainda não responde",
|
||||
"ru": "Узел занят: пока не отвечает", "zh": "节点繁忙:暂未响应",
|
||||
"ja": "ノード処理中:まだ応答していません", "ko": "노드 작업 중: 아직 응답하지 않음"
|
||||
},
|
||||
"node_busy_rpc_desc": {
|
||||
"de": "Der Node läuft, ist aber seit %s zu beschäftigt, um der Wallet zu antworten – meist wegen eines langen Vorgangs wie dem Neuaufbau der Witnesses.",
|
||||
"es": "El nodo está en marcha, pero lleva %s demasiado ocupado para responder a la cartera, normalmente por una operación larga como la reconstrucción de testigos.",
|
||||
"fr": "Le nœud fonctionne mais est trop occupé pour répondre au portefeuille depuis %s, généralement à cause d'une longue opération comme la reconstruction des témoins.",
|
||||
"pt": "O nó está em execução, mas está ocupado demais para responder à carteira há %s, geralmente por causa de uma operação longa como a reconstrução de testemunhas.",
|
||||
"ru": "Узел работает, но уже %s слишком занят, чтобы отвечать кошельку, обычно из-за долгой операции, например перестройки свидетелей.",
|
||||
"zh": "节点正在运行,但已有 %s 忙于其他任务而无法响应钱包,通常是因为见证重建等耗时操作。",
|
||||
"ja": "ノードは実行中ですが、%s の間ウォレットに応答できないほど処理中です。通常はウィットネスの再構築などの長時間の処理が原因です。",
|
||||
"ko": "노드는 실행 중이지만 %s 동안 지갑에 응답할 수 없을 만큼 바쁩니다. 보통 위트니스 재구성 같은 긴 작업 때문입니다."
|
||||
},
|
||||
"node_starting_title": {
|
||||
"de": "DragonX-Node wird gestartet…", "es": "Iniciando el nodo DragonX…", "fr": "Démarrage du nœud DragonX…",
|
||||
"pt": "Iniciando o nó DragonX…", "ru": "Запуск узла DragonX…", "zh": "正在启动 DragonX 节点…",
|
||||
"ja": "DragonX ノードを起動しています…", "ko": "DragonX 노드 시작 중…"
|
||||
},
|
||||
"node_starting_busy_desc": {
|
||||
"de": "Der Node ist erreichbar, aber beschäftigt und antwortet noch nicht. Das ist nach einem Update oder beim ersten Start normal und kann einige Minuten dauern.",
|
||||
"es": "El nodo está accesible pero ocupado y aún no responde. Es normal tras una actualización o en el primer inicio; puede tardar unos minutos.",
|
||||
"fr": "Le nœud est joignable mais occupé et ne répond pas encore. C'est normal après une mise à jour ou au premier lancement ; cela peut prendre quelques minutes.",
|
||||
"pt": "O nó está acessível, mas ocupado, e ainda não responde. Isso é normal após uma atualização ou na primeira execução; pode levar alguns minutos.",
|
||||
"ru": "Узел доступен, но занят и пока не отвечает. Это нормально после обновления или при первом запуске; может занять несколько минут.",
|
||||
"zh": "节点可以访问,但正忙,暂未响应。更新后或首次启动时属正常现象,可能需要几分钟。",
|
||||
"ja": "ノードには接続できますが処理中のため、まだ応答していません。更新後や初回起動時には正常な状態で、数分かかることがあります。",
|
||||
"ko": "노드에 연결할 수 있지만 바빠서 아직 응답하지 않습니다. 업데이트 후나 처음 실행할 때는 정상이며, 몇 분 걸릴 수 있습니다."
|
||||
},
|
||||
"node_starting_launch_desc": {
|
||||
"de": "dragonxd wird gestartet, warte auf Verbindung…", "es": "Iniciando dragonxd y esperando a que esté en línea…",
|
||||
"fr": "Lancement de dragonxd, en attente de sa disponibilité…", "pt": "Iniciando o dragonxd e aguardando ficar online…",
|
||||
"ru": "Запуск dragonxd и ожидание его готовности…", "zh": "正在启动 dragonxd 并等待其上线…",
|
||||
"ja": "dragonxd を起動し、オンラインになるのを待っています…", "ko": "dragonxd를 시작하고 온라인 상태가 되기를 기다리는 중…"
|
||||
},
|
||||
"sb_node_busy": {
|
||||
"de": "Node beschäftigt", "es": "Nodo ocupado", "fr": "Nœud occupé", "pt": "Nó ocupado",
|
||||
"ru": "Узел занят", "zh": "节点繁忙", "ja": "ノード処理中", "ko": "노드 작업 중"
|
||||
},
|
||||
# --- Quitting while the node is busy ---
|
||||
"stopconfirm_rebuild_title": {
|
||||
"de": "Der Node baut die Note-Witnesses neu auf", "es": "El nodo está reconstruyendo los testigos de notas",
|
||||
"fr": "Le nœud reconstruit les témoins de notes", "pt": "O nó está reconstruindo as testemunhas de notas",
|
||||
"ru": "Узел перестраивает свидетелей заметок", "zh": "节点正在重建票据见证",
|
||||
"ja": "ノードはノートウィットネスを再構築しています", "ko": "노드가 노트 위트니스를 재구성하고 있습니다"
|
||||
},
|
||||
"stopconfirm_rebuild_body": {
|
||||
"de": "Er läuft seit %s, und bei großen Wallets kann das etwa eine Stunde dauern. Wenn Sie den Node jetzt stoppen, wird entweder bis zum Ende des Neuaufbaus gewartet, oder der nächste Start muss den Neuaufbau samt Nachholen wiederholen.\n\nEmpfohlen: Wallet schließen und den Node weiterlaufen lassen. Er beendet die Arbeit selbstständig.",
|
||||
"es": "Lleva %s en curso, y en carteras grandes puede tardar alrededor de una hora. Detener el nodo ahora o bien espera a que termine la reconstrucción, o bien hace que el próximo inicio la repita junto con cualquier puesta al día.\n\nRecomendado: cierra la cartera y deja el nodo en marcha. Terminará por su cuenta.",
|
||||
"fr": "Elle est en cours depuis %s, et pour un gros portefeuille elle peut prendre environ une heure. Arrêter le nœud maintenant attend la fin de la reconstruction, ou oblige son prochain démarrage à la refaire, rattrapage compris.\n\nRecommandé : fermez le portefeuille et laissez le nœud actif. Il terminera seul.",
|
||||
"pt": "Está em andamento há %s, e em carteiras grandes pode levar cerca de uma hora. Parar o nó agora ou espera a reconstrução terminar, ou faz o próximo início refazê-la junto com qualquer recuperação.\n\nRecomendado: feche a carteira e deixe o nó em execução. Ele termina sozinho.",
|
||||
"ru": "Она выполняется уже %s, а для больших кошельков может занять около часа. Если остановить узел сейчас, он либо дождётся окончания перестройки, либо при следующем запуске выполнит её заново вместе с догонянием блоков.\n\nРекомендуется: закройте кошелёк и оставьте узел работать. Он завершит всё сам.",
|
||||
"zh": "已运行 %s,大型钱包可能需要约一小时。现在停止节点,要么会等待重建完成,要么下次启动时需要重新进行重建以及区块追赶。\n\n建议:关闭钱包并保持节点运行,它会自行完成。",
|
||||
"ja": "経過時間は %s で、大きなウォレットでは約 1 時間かかることがあります。今ノードを停止すると、再構築の完了まで待つか、次回の起動時に再構築とブロックの追いつきをやり直すことになります。\n\n推奨:ウォレットを閉じ、ノードは実行したままにしてください。ノードは自動的に完了します。",
|
||||
"ko": "%s 동안 진행 중이며, 큰 지갑은 약 1시간이 걸릴 수 있습니다. 지금 노드를 중지하면 재구성이 끝날 때까지 기다리거나, 다음 시작 시 재구성과 블록 따라잡기를 다시 해야 합니다.\n\n권장: 지갑을 닫고 노드는 계속 실행하세요. 노드가 스스로 마칩니다."
|
||||
},
|
||||
"stopconfirm_busy_title": {
|
||||
"de": "Der Node ist beschäftigt", "es": "El nodo está ocupado", "fr": "Le nœud est occupé",
|
||||
"pt": "O nó está ocupado", "ru": "Узел занят", "zh": "节点正忙", "ja": "ノードは処理中です",
|
||||
"ko": "노드가 작업 중입니다"
|
||||
},
|
||||
"stopconfirm_busy_body": {
|
||||
"de": "Er ist seit %s zu beschäftigt, um der Wallet zu antworten – vermutlich wegen eines langen Vorgangs wie dem Neuaufbau der Witnesses. Wenn Sie ihn jetzt stoppen, muss der nächste Start diese Arbeit eventuell wiederholen.\n\nEmpfohlen: Wallet schließen und den Node weiterlaufen lassen. Er beendet die Arbeit selbstständig.",
|
||||
"es": "Lleva %s demasiado ocupado para responder a la cartera, probablemente por una operación larga como la reconstrucción de testigos. Detenerlo ahora puede hacer que el próximo inicio repita ese trabajo.\n\nRecomendado: cierra la cartera y deja el nodo en marcha. Terminará por su cuenta.",
|
||||
"fr": "Il est trop occupé pour répondre au portefeuille depuis %s, probablement à cause d'une longue opération comme la reconstruction des témoins. L'arrêter maintenant peut obliger son prochain démarrage à refaire ce travail.\n\nRecommandé : fermez le portefeuille et laissez le nœud actif. Il terminera seul.",
|
||||
"pt": "Está ocupado demais para responder à carteira há %s, provavelmente por causa de uma operação longa como a reconstrução de testemunhas. Pará-lo agora pode fazer o próximo início refazer esse trabalho.\n\nRecomendado: feche a carteira e deixe o nó em execução. Ele termina sozinho.",
|
||||
"ru": "Уже %s он слишком занят, чтобы отвечать кошельку, вероятно, из-за долгой операции, например перестройки свидетелей. Если остановить его сейчас, при следующем запуске эту работу, возможно, придётся выполнить заново.\n\nРекомендуется: закройте кошелёк и оставьте узел работать. Он завершит всё сам.",
|
||||
"zh": "节点已有 %s 忙于其他任务而无法响应钱包,可能是因为见证重建等耗时操作。现在停止它,下次启动时可能需要重做这些工作。\n\n建议:关闭钱包并保持节点运行,它会自行完成。",
|
||||
"ja": "%s の間、ウォレットに応答できないほど処理中です。ウィットネスの再構築などの長時間の処理が原因と考えられます。今停止すると、次回の起動時にその処理をやり直すことがあります。\n\n推奨:ウォレットを閉じ、ノードは実行したままにしてください。ノードは自動的に完了します。",
|
||||
"ko": "%s 동안 지갑에 응답할 수 없을 만큼 바빴습니다. 위트니스 재구성 같은 긴 작업 때문일 가능성이 큽니다. 지금 중지하면 다음 시작 시 그 작업을 다시 해야 할 수 있습니다.\n\n권장: 지갑을 닫고 노드는 계속 실행하세요. 노드가 스스로 마칩니다."
|
||||
},
|
||||
"stopconfirm_stop_wait": {
|
||||
"de": "Node stoppen & warten", "es": "Detener el nodo y esperar", "fr": "Arrêter le nœud et attendre",
|
||||
"pt": "Parar o nó e aguardar", "ru": "Остановить узел и подождать", "zh": "停止节点并等待",
|
||||
"ja": "ノードを停止して待つ", "ko": "노드 중지 후 대기"
|
||||
},
|
||||
"appx_daemon_reinstall_node_busy": {
|
||||
"de": "Der Node läuft noch, daher wurde der Daemon nicht neu installiert. Versuchen Sie es erneut, sobald er beendet ist.",
|
||||
"es": "El nodo sigue en marcha, así que no se reinstaló el daemon. Vuelve a intentarlo cuando se haya detenido.",
|
||||
"fr": "Le nœud est toujours actif, le démon n'a donc pas été réinstallé. Réessayez une fois qu'il sera arrêté.",
|
||||
"pt": "O nó ainda está em execução, por isso o daemon não foi reinstalado. Tente novamente quando ele tiver parado.",
|
||||
"ru": "Узел всё ещё работает, поэтому демон не был переустановлен. Повторите попытку, когда он остановится.",
|
||||
"zh": "节点仍在运行,因此未重新安装守护进程。请在它停止后重试。",
|
||||
"ja": "ノードがまだ実行中のため、デーモンは再インストールされませんでした。停止してからもう一度お試しください。",
|
||||
"ko": "노드가 아직 실행 중이라 데몬을 다시 설치하지 않았습니다. 노드가 멈춘 뒤 다시 시도하세요."
|
||||
},
|
||||
# --- Balance tab ---
|
||||
"hide_zero_balances": {
|
||||
"es": "Ocultar saldos 0", "de": "Nullsalden ausblenden", "fr": "Masquer les soldes à 0",
|
||||
|
||||
+114
-10
@@ -946,6 +946,18 @@ void App::update()
|
||||
pumpRpcBusyCanary();
|
||||
const bool rpcBusy = rpc_busy_gate_->busy();
|
||||
|
||||
// Keep the "node starting / warming up / busy" overlay current between connect attempts and polls,
|
||||
// unless something else has replaced the status (see init_status_title_, applyWarmupText).
|
||||
if (ImGui::GetTime() >= status_refresh_at_) {
|
||||
status_refresh_at_ = ImGui::GetTime() + 1.0;
|
||||
if (state_.warming_up && !warmup_rpc_message_.empty() && connection_status_ == state_.warmup_status) {
|
||||
applyWarmupText(warmup_rpc_message_);
|
||||
} else if (state_.daemon_initializing && !state_.connected && !init_status_title_.empty() &&
|
||||
connection_status_ == init_status_title_) {
|
||||
applyDaemonInitStatus(init_status_busy_);
|
||||
}
|
||||
}
|
||||
|
||||
// Fast refresh (mining stats + daemon memory) every second
|
||||
// Skip when wallet is locked — no need to poll, and queued tasks
|
||||
// would delay the PIN unlock worker task.
|
||||
@@ -1629,6 +1641,8 @@ void App::render()
|
||||
snprintf(deletedMsg, sizeof(deletedMsg), TR("appx_blockchain_data_deleted"), deletedN);
|
||||
ui::Notifications::instance().success(deletedMsg);
|
||||
}
|
||||
if (pending_reinstall_node_busy_.exchange(false, std::memory_order_relaxed))
|
||||
ui::Notifications::instance().warning(TR("appx_daemon_reinstall_node_busy"), 12.0f);
|
||||
}
|
||||
|
||||
|
||||
@@ -2315,6 +2329,9 @@ void App::renderNodeStatusBanner()
|
||||
in.lite_open_error = lite_open_error_;
|
||||
in.tip_known = state_.sync.tip_known;
|
||||
in.blocks = state_.sync.blocks;
|
||||
const NodeBusyText busy = nodeBusyText();
|
||||
in.node_busy = busy.busy;
|
||||
in.node_busy_detail = busy.compact; // one line; the overlay and the quit prompt explain more
|
||||
|
||||
const ui::NodeBannerState banner = ui::evaluateNodeStatusBanner(in);
|
||||
if (!banner.show) return;
|
||||
@@ -2349,6 +2366,8 @@ void App::renderNodeStatusBanner()
|
||||
title = TR("node_banner_lite_open_failed"); icon = ICON_MD_ERROR; break;
|
||||
case ui::NodeBannerReason::NoPeers:
|
||||
title = TR("node_banner_no_peers_title"); icon = ICON_MD_CLOUD_OFF; break;
|
||||
case ui::NodeBannerReason::NodeBusy:
|
||||
title = busy.title.c_str(); icon = ICON_MD_HOURGLASS_EMPTY; break;
|
||||
case ui::NodeBannerReason::FullNodeOffline:
|
||||
default:
|
||||
title = TR("node_banner_offline_title"); icon = ICON_MD_CLOUD_OFF; break;
|
||||
@@ -2672,6 +2691,9 @@ void App::renderStatusBar()
|
||||
const char* dotStr = (dots == 0) ? "." : (dots == 1) ? ".." : (dots == 2) ? "..." : "";
|
||||
ImGui::TextColored(ImVec4(0.6f, 0.8f, 1.0f, 1.0f), "%s%s", TR("sb_rescanning"), dotStr);
|
||||
}
|
||||
} else if (rpc_busy_gate_->busy()) {
|
||||
// The node holds back our requests (a long operation holds its cs_main): data may be stale.
|
||||
ImGui::TextColored(ImGui::ColorConvertU32ToFloat4(ui::material::Warning()), "%s", TR("sb_node_busy"));
|
||||
} else if (state_.sync.syncing) {
|
||||
int chainTip = state_.longestchain > 0 ? state_.longestchain : state_.sync.headers;
|
||||
int blocksLeft = chainTip - state_.sync.blocks;
|
||||
@@ -2803,7 +2825,11 @@ void App::renderStatusBar()
|
||||
// with a small gap.
|
||||
float gap = sbSectionGap;
|
||||
float occupiedX = versionX; // leftmost X used by the version + connection status so far
|
||||
if (!connection_status_.empty() && connection_status_ != "Connected") {
|
||||
// The left of the bar already shows the warmup / "node busy" status; don't print it twice.
|
||||
const bool shownOnLeft = (state_.warming_up || state_.daemon_initializing) &&
|
||||
connection_status_ == state_.warmup_status;
|
||||
if (!connection_status_.empty() && connection_status_ != "Connected" &&
|
||||
connection_status_ != TR("connected") && !shownOnLeft) {
|
||||
// During a post-repair rescan the raw status is a scary "RPC request failed: Timeout" — show a
|
||||
// calm line instead (the rescan legitimately can't answer RPC yet).
|
||||
const std::string statusBase = post_recovery_rescan_ ? std::string(TR("sb_finishing_repair"))
|
||||
@@ -5833,6 +5859,7 @@ void App::reinstallBundledDaemon()
|
||||
if (stillUp()) {
|
||||
DEBUG_LOGF("[App] Reinstall bundled daemon: aborted — a dragonxd process is still running; "
|
||||
"binaries left untouched and no new node started\n");
|
||||
pending_reinstall_node_busy_.store(true, std::memory_order_relaxed); // told on the UI thread
|
||||
return;
|
||||
}
|
||||
// Overwrite the installed dragonx binaries (dragonxd/cli/tx) with the bundled ones.
|
||||
@@ -6084,6 +6111,70 @@ void App::feedDaemonBusy(const std::string& chunk)
|
||||
if (daemon_busy_reset_pending_.exchange(false)) daemon_busy_.reset();
|
||||
daemon_busy_.feed(chunk);
|
||||
node_rebuilding_ = daemon_busy_.rebuilding();
|
||||
if (!daemon_busy_.busy()) busy_first_seen_ = {};
|
||||
else if (busy_first_seen_ == std::chrono::steady_clock::time_point{}) busy_first_seen_ = std::chrono::steady_clock::now();
|
||||
}
|
||||
|
||||
static std::string formatBusyDuration(double secs)
|
||||
{
|
||||
const long s = secs > 0 ? static_cast<long>(secs) : 0;
|
||||
char buf[32];
|
||||
if (s >= 3600) snprintf(buf, sizeof(buf), "%ld:%02ld:%02ld", s / 3600, (s / 60) % 60, s % 60);
|
||||
else snprintf(buf, sizeof(buf), "%ld:%02ld", s / 60, s % 60);
|
||||
return buf;
|
||||
}
|
||||
|
||||
App::NodeBusyText App::nodeBusyText() const
|
||||
{
|
||||
NodeBusyText out;
|
||||
// The tracker reads OUR node's output; once that process is gone its last state means nothing.
|
||||
const bool ours = daemon_controller_ && daemon_controller_->isRunning();
|
||||
const bool rebuilding = ours && daemon_busy_.rebuilding();
|
||||
const bool replaying = ours && daemon_busy_.replaying() && !rebuilding;
|
||||
const bool rpcBusy = rpc_busy_gate_->busy();
|
||||
if (!rebuilding && !replaying && !rpcBusy) return out;
|
||||
out.busy = true;
|
||||
out.rebuilding = rebuilding;
|
||||
|
||||
// Running time: from the node's own (UTC) log timestamp when there is one, else since we first saw it.
|
||||
double secs = rpc_busy_gate_->busySeconds();
|
||||
if (rebuilding || replaying) {
|
||||
const std::int64_t startUtc = rebuilding ? daemon_busy_.rebuildStartUtc() : daemon_busy_.replayStartUtc();
|
||||
if (startUtc > 0) {
|
||||
secs = static_cast<double>(static_cast<std::int64_t>(std::time(nullptr)) - startUtc);
|
||||
} else if (busy_first_seen_ != std::chrono::steady_clock::time_point{}) {
|
||||
secs = std::chrono::duration<double>(std::chrono::steady_clock::now() - busy_first_seen_).count();
|
||||
}
|
||||
}
|
||||
out.elapsed = formatBusyDuration(secs);
|
||||
|
||||
char buf[512];
|
||||
std::string progress;
|
||||
if (rebuilding) {
|
||||
out.title = TR("node_busy_rebuild_title");
|
||||
snprintf(buf, sizeof(buf), TR("node_busy_rebuild_desc"), out.elapsed.c_str());
|
||||
out.detail = buf;
|
||||
// Phase 1 logs a line per 5000 blocks read; Phase 2 (extending the witnesses) logs nothing.
|
||||
const long done = daemon_busy_.readDone(), total = daemon_busy_.readTotal();
|
||||
const bool reading = total > 0 && done + 5000 < total;
|
||||
if (reading) snprintf(buf, sizeof(buf), TR("node_busy_rebuild_reading"), done, total);
|
||||
else snprintf(buf, sizeof(buf), "%s", TR("node_busy_rebuild_extending"));
|
||||
out.detail += " ";
|
||||
out.detail += buf;
|
||||
if (reading) progress = buf;
|
||||
} else if (replaying) {
|
||||
out.title = TR("node_busy_replay_title");
|
||||
snprintf(buf, sizeof(buf), TR("node_busy_replay_desc"), out.elapsed.c_str());
|
||||
out.detail = buf;
|
||||
} else {
|
||||
out.title = TR("node_busy_rpc_title");
|
||||
snprintf(buf, sizeof(buf), TR("node_busy_rpc_desc"), out.elapsed.c_str());
|
||||
out.detail = buf;
|
||||
}
|
||||
snprintf(buf, sizeof(buf), TR("node_busy_running"), out.elapsed.c_str());
|
||||
out.compact = buf;
|
||||
if (!progress.empty()) out.compact += " · " + progress;
|
||||
return out;
|
||||
}
|
||||
|
||||
void App::resetDaemonBusy()
|
||||
@@ -6142,17 +6233,35 @@ void App::renderDaemonStopConfirm()
|
||||
bool proceed = false;
|
||||
if (ImGui::BeginPopupModal("##DaemonStopConfirm", nullptr,
|
||||
ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoTitleBar)) {
|
||||
// Honest about what each choice does now that the wallet never kills the node: stopping waits for
|
||||
// it to finish or abort the rebuild (Phase 1 aborts and is redone on the next start; Phase 2 can't
|
||||
// be interrupted). Keeping it running loses nothing, so it is the recommended, focused default.
|
||||
const NodeBusyText busy = nodeBusyText();
|
||||
std::string elapsed = busy.elapsed;
|
||||
if (!busy.busy && rpc_busy_since_ != std::chrono::steady_clock::time_point{})
|
||||
elapsed = formatBusyDuration(std::chrono::duration<double>(
|
||||
std::chrono::steady_clock::now() - rpc_busy_since_).count());
|
||||
const bool rebuilding = busy.rebuilding;
|
||||
if (Type().subtitle1()) ImGui::PushFont(Type().subtitle1());
|
||||
ImGui::TextUnformatted(TR("appx_node_rebuilding_witness_cache"));
|
||||
ImGui::TextUnformatted(TR(rebuilding ? "stopconfirm_rebuild_title" : "stopconfirm_busy_title"));
|
||||
if (Type().subtitle1()) ImGui::PopFont();
|
||||
ImGui::Spacing();
|
||||
char body[1024];
|
||||
snprintf(body, sizeof(body), TR(rebuilding ? "stopconfirm_rebuild_body" : "stopconfirm_busy_body"),
|
||||
elapsed.empty() ? "0:00" : elapsed.c_str());
|
||||
ImGui::PushTextWrapPos(ImGui::GetFontSize() * 26.0f);
|
||||
ImGui::TextUnformatted(TR("appx_stopping_node_discards_rebuild"));
|
||||
ImGui::TextUnformatted(body);
|
||||
ImGui::PopTextWrapPos();
|
||||
ImGui::Spacing();
|
||||
ImGui::Spacing();
|
||||
|
||||
if (TactileButton(TR("appx_keep_node_running_and_quit"), ImVec2(0, 0))) {
|
||||
ImGui::PushStyleColor(ImGuiCol_Button, ImGui::ColorConvertU32ToFloat4(WithAlpha(Primary(), 210)));
|
||||
ImGui::PushStyleColor(ImGuiCol_ButtonHovered, ImGui::ColorConvertU32ToFloat4(Primary()));
|
||||
ImGui::PushStyleColor(ImGuiCol_ButtonActive, ImGui::ColorConvertU32ToFloat4(WithAlpha(Primary(), 160)));
|
||||
const bool keep = TactileButton(TR("appx_keep_node_running_and_quit"), ImVec2(0, 0));
|
||||
ImGui::PopStyleColor(3);
|
||||
ImGui::SetItemDefaultFocus();
|
||||
if (keep) {
|
||||
shutdown_keep_daemon_override_ = true;
|
||||
shutdown_confirmed_ = true;
|
||||
daemon_stop_confirm_open_ = false;
|
||||
@@ -6160,12 +6269,7 @@ void App::renderDaemonStopConfirm()
|
||||
ImGui::CloseCurrentPopup();
|
||||
}
|
||||
ImGui::SameLine();
|
||||
ImGui::PushStyleColor(ImGuiCol_Button, ImGui::ColorConvertU32ToFloat4(WithAlpha(Error(), 210)));
|
||||
ImGui::PushStyleColor(ImGuiCol_ButtonHovered, ImGui::ColorConvertU32ToFloat4(Error()));
|
||||
ImGui::PushStyleColor(ImGuiCol_ButtonActive, ImGui::ColorConvertU32ToFloat4(WithAlpha(Error(), 160)));
|
||||
const bool stopAnyway = TactileButton(TR("appx_stop_anyway_and_quit"), ImVec2(0, 0));
|
||||
ImGui::PopStyleColor(3);
|
||||
if (stopAnyway) {
|
||||
if (TactileButton(TR("stopconfirm_stop_wait"), ImVec2(0, 0))) {
|
||||
shutdown_confirmed_ = true;
|
||||
daemon_stop_confirm_open_ = false;
|
||||
proceed = true;
|
||||
|
||||
@@ -1077,6 +1077,7 @@ private:
|
||||
// Set by the deleteBlockchainData worker (item count); the main loop surfaces a completion toast
|
||||
// and resets it to -1. Atomic because the worker thread writes it and the UI thread reads/clears it.
|
||||
std::atomic<int> pending_delete_result_{-1};
|
||||
std::atomic<bool> pending_reinstall_node_busy_{false}; // reinstall gave up: the old node never exited
|
||||
|
||||
// Encryption state check timeout
|
||||
float encryption_check_timer_ = 0.0f;
|
||||
@@ -1186,6 +1187,17 @@ private:
|
||||
void abortRpcBusyCanary();
|
||||
void feedDaemonBusy(const std::string& chunk);
|
||||
void resetDaemonBusy();
|
||||
std::chrono::steady_clock::time_point busy_first_seen_{}; // when the tracker last turned busy (UI thread)
|
||||
// What to tell the user while the node is busy (overlay, banner, quit prompt). busy=false: it isn't.
|
||||
struct NodeBusyText {
|
||||
bool busy = false;
|
||||
bool rebuilding = false;
|
||||
std::string title; // e.g. "Node busy: rebuilding note witnesses — do not close"
|
||||
std::string detail; // running time, what it's doing, progress when the node reports any
|
||||
std::string elapsed; // "12:03"
|
||||
std::string compact; // one line for the banner: "Running for 12:03 · Reading blocks: 45438 / 62583"
|
||||
};
|
||||
NodeBusyText nodeBusyText() const;
|
||||
|
||||
// Export/Import state
|
||||
char export_result_[256] = {0}; // SECRET exported key — fixed buffer so it can be sodium_memzero'd
|
||||
@@ -1574,6 +1586,17 @@ private:
|
||||
// `reachableButBusy` is true when the probe connected but got no RPC reply (a timeout),
|
||||
// false when the daemon is merely launching (not bound yet). Returns the status title.
|
||||
std::string applyDaemonInitStatus(bool reachableButBusy);
|
||||
// The overlay text applyDaemonInitStatus last produced. It runs only on a connect failure, which a busy
|
||||
// node backs off to every 30s, so update() re-applies it once a second (the elapsed time and the
|
||||
// node's own progress tick) for as long as nothing else has replaced the status.
|
||||
std::string init_status_title_;
|
||||
bool init_status_busy_ = false;
|
||||
double status_refresh_at_ = 0.0;
|
||||
// The warm-up overlay text, from the node's last -28 message — unless its own log says it is rebuilding
|
||||
// witnesses: a startup rebuild runs under "Activating best chain...", which hides the step users must
|
||||
// not interrupt. update() re-applies it once a second too (see init_status_title_).
|
||||
void applyWarmupText(const std::string& rpcMessage);
|
||||
std::string warmup_rpc_message_;
|
||||
// Tear down a connection that died mid-session (daemon crash / restart / dropped
|
||||
// socket) so update()'s reconnect branch re-enters tryConnect(). Unlike onDisconnected
|
||||
// alone, this also rpc_->disconnect()s so rpc_->isConnected() actually flips to false.
|
||||
|
||||
+51
-31
@@ -533,16 +533,7 @@ void App::tryConnect()
|
||||
// the UI shows status instead of a blocking overlay.
|
||||
state_.warming_up = true;
|
||||
if (connect_stall_since_ <= 0.0) connect_stall_since_ = ImGui::GetTime(); // start the "taking too long" clock
|
||||
auto wt = translateWarmup(warmupStatus);
|
||||
state_.warmup_status = wt.title;
|
||||
state_.warmup_description = wt.description;
|
||||
// Append current block height from daemon output
|
||||
if (daemon_controller_) {
|
||||
int h = daemon_controller_->lastBlockHeight();
|
||||
if (h > 0)
|
||||
state_.warmup_status += " (Block " + std::to_string(h) + ")";
|
||||
}
|
||||
connection_status_ = state_.warmup_status;
|
||||
applyWarmupText(warmupStatus);
|
||||
}
|
||||
} else {
|
||||
// HTTP 401 = authentication failure. The daemon is running
|
||||
@@ -594,7 +585,9 @@ void App::tryConnect()
|
||||
// a connect refusal means it hasn't bound the RPC port yet. Either way, show a
|
||||
// clear "node initializing" overlay (status + phase + block height from the
|
||||
// daemon's own console output) instead of a bare technical error.
|
||||
const bool reachableButBusy = rpc::isRpcTimeout(connectKind);
|
||||
// Reached the node but no answer (reply timeout / full queue / held back): up but busy.
|
||||
// A refusal or connect timeout means it hasn't bound (or has already unbound) RPC.
|
||||
const bool reachableButBusy = rpc::rpcKindMeansBusy(connectKind);
|
||||
applyDaemonInitStatus(reachableButBusy);
|
||||
const float retryIn = connect_backoff_.next(connectKind);
|
||||
VERBOSE_LOGF("[connect #%d] RPC connection failed (%s) — daemon still starting, retry in %.0fs\n",
|
||||
@@ -605,7 +598,7 @@ void App::tryConnect()
|
||||
// An external daemon is on the RPC port but not answering. A timeout means it's
|
||||
// up and busy initializing; surface that as the init overlay (we can't read its
|
||||
// console since we didn't launch it, so no phase line — just a clear message).
|
||||
if (rpc::isRpcTimeout(connectKind)) {
|
||||
if (rpc::rpcKindMeansBusy(connectKind)) {
|
||||
applyDaemonInitStatus(/*reachableButBusy=*/true);
|
||||
} else if (!connectErr.empty()) {
|
||||
char buf[256]; snprintf(buf, sizeof(buf), TR("sb_connecting_err"), connectErr.c_str());
|
||||
@@ -699,6 +692,7 @@ void App::onConnected()
|
||||
wallet_switch_phase_.store(static_cast<int>(WalletSwitchPhase::None));
|
||||
}
|
||||
state_.daemon_initializing = false; // RPC is answering now; clear the "initializing" overlay
|
||||
init_status_title_.clear();
|
||||
daemon_wait_attempts_ = 0; // re-arm the port-busy / start-failure notifications
|
||||
connect_stall_since_ = 0.0; // connected — clear the "taking too long" clock
|
||||
// A repair's rescan finished and connected — retire the recovery session so its crash-toast/error-card
|
||||
@@ -870,19 +864,33 @@ std::string App::applyDaemonInitStatus(bool reachableButBusy)
|
||||
}
|
||||
}
|
||||
|
||||
// Most specific first: the node's own log says it is rebuilding witnesses or replaying blocks (then
|
||||
// "Launching dragonxd…" over a node that has been busy for an hour invited closing it), else an init
|
||||
// phase line, else "reachable but busy", else not bound yet.
|
||||
const auto kind = daemon::chooseDaemonStatus(!phaseLine.empty(), reachableButBusy, daemon_busy_);
|
||||
std::string busyTitle, busyDetail;
|
||||
WarmupText wt;
|
||||
if (!phaseLine.empty()) {
|
||||
switch (kind) {
|
||||
case daemon::DaemonStatusKind::Rebuilding:
|
||||
case daemon::DaemonStatusKind::Replaying: {
|
||||
const NodeBusyText busy = nodeBusyText();
|
||||
busyTitle = busy.title;
|
||||
busyDetail = busy.detail;
|
||||
wt = {busyTitle.c_str(), busyDetail.c_str()};
|
||||
break;
|
||||
}
|
||||
case daemon::DaemonStatusKind::InitPhase:
|
||||
wt = translateWarmup(phaseLine);
|
||||
} else if (reachableButBusy) {
|
||||
// The probe connected but got no RPC reply within the timeout: the node is up but busy
|
||||
// initializing (it isn't printing a recognizable phase, or we didn't launch it).
|
||||
wt = {"Starting DragonX node…",
|
||||
"The node is reachable but still initializing and isn't answering yet. "
|
||||
"This is normal after an update or on first launch — it can take a few minutes."};
|
||||
} else {
|
||||
break;
|
||||
case daemon::DaemonStatusKind::Busy:
|
||||
// The probe reached the node but got no answer (a reply timeout or a full queue): it is up but
|
||||
// too busy to answer (it isn't printing a recognizable phase, or we didn't launch it).
|
||||
wt = {TR("node_starting_title"), TR("node_starting_busy_desc")};
|
||||
break;
|
||||
case daemon::DaemonStatusKind::Launching:
|
||||
// The daemon is launching but hasn't bound its RPC port yet.
|
||||
wt = {"Starting DragonX node…",
|
||||
"Launching dragonxd and waiting for it to come online…"};
|
||||
wt = {TR("node_starting_title"), TR("node_starting_launch_desc")};
|
||||
break;
|
||||
}
|
||||
|
||||
std::string title = wt.title;
|
||||
@@ -892,9 +900,29 @@ std::string App::applyDaemonInitStatus(bool reachableButBusy)
|
||||
state_.warmup_status = title;
|
||||
state_.warmup_description = wt.description ? wt.description : "";
|
||||
connection_status_ = title;
|
||||
init_status_title_ = title;
|
||||
init_status_busy_ = reachableButBusy;
|
||||
return title;
|
||||
}
|
||||
|
||||
void App::applyWarmupText(const std::string& rpcMessage)
|
||||
{
|
||||
warmup_rpc_message_ = rpcMessage;
|
||||
if (daemon_busy_.rebuilding()) {
|
||||
const NodeBusyText busy = nodeBusyText();
|
||||
state_.warmup_status = busy.title;
|
||||
state_.warmup_description = busy.detail;
|
||||
} else {
|
||||
const WarmupText wt = translateWarmup(rpcMessage);
|
||||
state_.warmup_status = wt.title;
|
||||
state_.warmup_description = wt.description;
|
||||
}
|
||||
// Append current block height from daemon output
|
||||
const int h = daemon_controller_ ? daemon_controller_->lastBlockHeight() : -1;
|
||||
if (h > 0) state_.warmup_status += " (Block " + std::to_string(h) + ")";
|
||||
connection_status_ = state_.warmup_status;
|
||||
}
|
||||
|
||||
void App::handleLostConnection(const std::string& reason)
|
||||
{
|
||||
DEBUG_LOGF("[Connection] %s — tearing down for reconnect\n", reason.c_str());
|
||||
@@ -1799,15 +1827,7 @@ void App::refreshCoreData()
|
||||
refreshData();
|
||||
} else {
|
||||
// Still warming up — update status
|
||||
auto wt = translateWarmup(result.errorMessage);
|
||||
state_.warmup_status = wt.title;
|
||||
state_.warmup_description = wt.description;
|
||||
if (daemon_controller_) {
|
||||
int h = daemon_controller_->lastBlockHeight();
|
||||
if (h > 0)
|
||||
state_.warmup_status += " (Block " + std::to_string(h) + ")";
|
||||
}
|
||||
connection_status_ = state_.warmup_status;
|
||||
applyWarmupText(result.errorMessage);
|
||||
VERBOSE_LOGF("[warmup] Still warming up: %s\n", result.errorMessage.c_str());
|
||||
}
|
||||
};
|
||||
|
||||
@@ -141,5 +141,24 @@ inline bool shouldConfirmStop(bool stopsDaemon, const DaemonBusyTracker& tracker
|
||||
return stopsDaemon && (tracker.rebuilding() || rpcBusyWhileAlive);
|
||||
}
|
||||
|
||||
// What the "node is starting / not answering" overlay should say, most specific first.
|
||||
enum class DaemonStatusKind {
|
||||
Rebuilding, // its own log says it's rebuilding note witnesses
|
||||
Replaying, // its own log says it's catching up on blocks it saved before (startup replay)
|
||||
InitPhase, // a recognisable init phase line (loading the block index, verifying, ...)
|
||||
Busy, // it answers the connection but not the request (reply timeout / queue full)
|
||||
Launching, // nothing bound to the RPC port yet
|
||||
};
|
||||
|
||||
inline DaemonStatusKind chooseDaemonStatus(bool hasInitPhaseLine, bool reachableButBusy,
|
||||
const DaemonBusyTracker& tracker)
|
||||
{
|
||||
if (tracker.rebuilding()) return DaemonStatusKind::Rebuilding;
|
||||
if (tracker.replaying()) return DaemonStatusKind::Replaying;
|
||||
if (hasInitPhaseLine) return DaemonStatusKind::InitPhase;
|
||||
if (reachableButBusy) return DaemonStatusKind::Busy;
|
||||
return DaemonStatusKind::Launching;
|
||||
}
|
||||
|
||||
} // namespace daemon
|
||||
} // namespace dragonx
|
||||
|
||||
@@ -32,6 +32,7 @@ enum class NodeBannerReason {
|
||||
DaemonCrashed, // the embedded daemon crashed repeatedly and auto-restart stopped
|
||||
LiteOpenFailed, // lite build: the wallet failed to open
|
||||
NoPeers, // connected to the daemon but no peer-derived tip (0 peers) — stalled, stale
|
||||
NodeBusy, // the node is up but busy (rebuilding witnesses / catching up / not answering)
|
||||
};
|
||||
|
||||
struct NodeBannerState {
|
||||
@@ -64,6 +65,12 @@ struct NodeBannerInputs {
|
||||
bool daemon_running = false;
|
||||
int daemon_crash_count = 0;
|
||||
|
||||
// The node is running but busy with something it can't be interrupted out of (a witness rebuild, the
|
||||
// startup replay) or too busy to answer RPC. Wallet data may be stale; a reconnect would only add
|
||||
// requests, so the banner offers no action. node_busy_detail is the live, translated description.
|
||||
bool node_busy = false;
|
||||
std::string node_busy_detail;
|
||||
|
||||
std::string connection_status; // human-readable status line (already translated)
|
||||
std::string daemon_last_error; // DaemonController::lastError() (may be empty)
|
||||
std::string lite_open_error; // lite: last wallet-open failure reason
|
||||
@@ -89,6 +96,18 @@ inline NodeBannerState evaluateNodeStatusBanner(const NodeBannerInputs& in) {
|
||||
return s;
|
||||
}
|
||||
|
||||
// Full node, busy. Before the startup-phase returns below: the overlay sets daemon_initializing while
|
||||
// the node is busy too, and the banner must still say why the wallet isn't updating. No action: a
|
||||
// "Reconnect" would only queue more requests behind the busy node.
|
||||
if (in.node_busy) {
|
||||
s.show = true;
|
||||
s.severity = NodeBannerSeverity::Warning;
|
||||
s.reason = NodeBannerReason::NodeBusy;
|
||||
s.action = NodeBannerAction::None;
|
||||
s.detail = in.node_busy_detail;
|
||||
return s;
|
||||
}
|
||||
|
||||
// Full node. In an expected startup phase → the loading/warmup overlay owns the screen, so no
|
||||
// banner. An active connect attempt likewise shows progress, not an error — don't flicker a
|
||||
// banner over it. (These return even if `connected` has flipped early, matching prior behavior.)
|
||||
|
||||
+23
-12
@@ -582,14 +582,9 @@ void I18n::loadBuiltinEnglish()
|
||||
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";
|
||||
// Stopping the node on quit: deliver stop, wait, never kill unasked (translations: S10 batch)
|
||||
// Stopping the node on quit: deliver stop, wait, never kill unasked
|
||||
strings_["shutdown_leave_running"] = "Close wallet — leave node running";
|
||||
strings_["shutdown_leave_running_tip"] = "Closes the wallet now. The node keeps running and finishes shutting down on its own; nothing is lost.";
|
||||
strings_["shutdown_leave_running_tip"] = "Closes the wallet now. The node keeps running on its own and finishes what it is doing; nothing is lost.";
|
||||
strings_["shutdown_kill_node"] = "Kill node (unsafe)";
|
||||
strings_["shutdown_kill_node_tip"] = "Ends the node at once. Anything it has not saved is lost, and its next start replays the blocks since its last save.";
|
||||
strings_["shutdown_kill_confirm_title"] = "Kill the node?";
|
||||
@@ -600,6 +595,27 @@ void I18n::loadBuiltinEnglish()
|
||||
strings_["shutdown_stop_delivered"] = "The node is shutting down and saving its state";
|
||||
strings_["shutdown_stop_cpu_suffix"] = " · CPU %d%%";
|
||||
strings_["shutdown_stop_idle"] = "No CPU or disk activity for %d min — the node may be stuck";
|
||||
// The node is busy (S9): overlay, banner, status bar
|
||||
strings_["node_busy_rebuild_title"] = "Node busy: rebuilding note witnesses";
|
||||
strings_["node_busy_running"] = "Running for %s";
|
||||
strings_["node_busy_rebuild_desc"] = "Running for %s. Large wallets can take about an hour, and the node can't answer the wallet until it finishes.";
|
||||
strings_["node_busy_rebuild_reading"] = "Reading blocks: %ld / %ld";
|
||||
strings_["node_busy_rebuild_extending"] = "Extending witnesses (the node reports no progress for this step).";
|
||||
strings_["node_busy_replay_title"] = "Node busy: catching up on blocks";
|
||||
strings_["node_busy_replay_desc"] = "Running for %s. The node is re-applying blocks it received before it last stopped.";
|
||||
strings_["node_busy_rpc_title"] = "Node busy: not answering yet";
|
||||
strings_["node_busy_rpc_desc"] = "The node is running but has been too busy to answer the wallet for %s, usually because of a long operation such as a witness rebuild.";
|
||||
strings_["node_starting_title"] = "Starting DragonX node…";
|
||||
strings_["node_starting_busy_desc"] = "The node is reachable but busy and isn't answering yet. This is normal after an update or on first launch; it can take a few minutes.";
|
||||
strings_["node_starting_launch_desc"] = "Launching dragonxd and waiting for it to come online…";
|
||||
strings_["sb_node_busy"] = "Node busy";
|
||||
// Quit while the node is busy (S10)
|
||||
strings_["stopconfirm_rebuild_title"] = "The node is rebuilding note witnesses";
|
||||
strings_["stopconfirm_rebuild_body"] = "It has been running for %s, and large wallets can take about an hour. Stopping the node now either waits for the rebuild to finish or makes its next start redo the rebuild and any catch-up.\n\nRecommended: close the wallet and leave the node running. It finishes on its own.";
|
||||
strings_["stopconfirm_busy_title"] = "The node is busy";
|
||||
strings_["stopconfirm_busy_body"] = "It has been too busy to answer the wallet for %s, probably because of a long operation such as a witness rebuild. Stopping it now can make its next start redo that work.\n\nRecommended: close the wallet and leave the node running. It finishes on its own.";
|
||||
strings_["stopconfirm_stop_wait"] = "Stop node & wait";
|
||||
strings_["appx_daemon_reinstall_node_busy"] = "The node is still running, so the daemon was not reinstalled. Try again once it has stopped.";
|
||||
strings_["reduce_motion"] = "Reduce Motion";
|
||||
strings_["tt_reduce_motion"] = "Disable animated transitions and balance lerp for accessibility";
|
||||
strings_["ago"] = "ago";
|
||||
@@ -2638,10 +2654,7 @@ void I18n::loadBuiltinEnglish()
|
||||
strings_["appx_restoring_your_wallet"] = "Restoring your wallet…";
|
||||
strings_["appx_recovery_phrase_word_count"] = "Recovery phrase should be 24 words — you have %d.";
|
||||
strings_["appx_could_not_start_restore"] = "Could not start restore";
|
||||
strings_["appx_node_rebuilding_witness_cache"] = "Node is rebuilding its witness cache";
|
||||
strings_["appx_stopping_node_discards_rebuild"] = "Stopping the node now discards the in-progress rebuild and restarts it (several minutes) the next time you open the wallet. You can keep the node running instead.";
|
||||
strings_["appx_keep_node_running_and_quit"] = "Keep node running & quit";
|
||||
strings_["appx_stop_anyway_and_quit"] = "Stop anyway & quit";
|
||||
strings_["appx_cancel"] = "Cancel";
|
||||
strings_["appx_last_used_wallet_not_found_prefix"] = "Your last-used wallet file (";
|
||||
strings_["appx_last_used_wallet_not_found_suffix"] = ") was not found — opened the default wallet instead. If you moved it, restore it and switch back from the wallet list.";
|
||||
@@ -2671,8 +2684,6 @@ void I18n::loadBuiltinEnglish()
|
||||
strings_["appx_shutdown_complete"] = "Shutdown complete";
|
||||
strings_["appx_n_seconds"] = "%d seconds";
|
||||
strings_["appx_n_min_n_sec"] = "%d min %d sec";
|
||||
strings_["appx_still_status_prefix"] = "Still \"";
|
||||
strings_["appx_still_status_suffix"] = "\" — force quitting now may corrupt chain data.";
|
||||
strings_["appx_rebuilding_witness_cache_blocks_left"] = "Rebuilding witness cache %.0f%% — %d blocks left";
|
||||
strings_["appx_rebuilding_witness_cache_pct"] = "Rebuilding witness cache %.0f%%";
|
||||
strings_["appx_setting_initial_sapling_witnesses"] = "Setting initial Sapling witnesses %.0f%%";
|
||||
|
||||
@@ -54,6 +54,7 @@
|
||||
#include "util/amount_format.h"
|
||||
#include "util/payment_uri.h"
|
||||
#include "util/platform.h"
|
||||
#include "util/i18n.h"
|
||||
#include "util/xmrig_updater.h"
|
||||
#include "util/pool_registry.h"
|
||||
#include "util/daemon_updater.h"
|
||||
@@ -83,6 +84,7 @@
|
||||
#include <fstream>
|
||||
#include <iostream>
|
||||
#include <algorithm>
|
||||
#include <cstring>
|
||||
#include <functional>
|
||||
#include <memory>
|
||||
#include <new>
|
||||
@@ -2987,6 +2989,31 @@ void testNodeStatusBanner()
|
||||
{
|
||||
using namespace dragonx::ui;
|
||||
|
||||
// S9: a busy node gets its own banner, ahead of every other full-node state. It must show even while
|
||||
// daemon_initializing is set (the busy overlay sets it), and offers no action (a reconnect would only
|
||||
// queue more requests behind the busy node).
|
||||
{
|
||||
NodeBannerInputs in;
|
||||
in.daemon_initializing = true;
|
||||
in.node_busy = true;
|
||||
in.node_busy_detail = "Running for 12:03.";
|
||||
NodeBannerState s = evaluateNodeStatusBanner(in);
|
||||
EXPECT_TRUE(s.show);
|
||||
EXPECT_TRUE(s.reason == NodeBannerReason::NodeBusy);
|
||||
EXPECT_TRUE(s.action == NodeBannerAction::None);
|
||||
EXPECT_TRUE(s.severity == NodeBannerSeverity::Warning);
|
||||
EXPECT_EQ(s.detail, std::string("Running for 12:03."));
|
||||
}
|
||||
{ // ...over "no peers" while connected, and over "offline" when not.
|
||||
NodeBannerInputs connected; connected.connected = true; connected.tip_known = false; connected.blocks = 5;
|
||||
connected.node_busy = true;
|
||||
EXPECT_TRUE(evaluateNodeStatusBanner(connected).reason == NodeBannerReason::NodeBusy);
|
||||
NodeBannerInputs offline; offline.node_busy = true;
|
||||
EXPECT_TRUE(evaluateNodeStatusBanner(offline).reason == NodeBannerReason::NodeBusy);
|
||||
NodeBannerInputs lite; lite.lite = true; lite.node_busy = true; // lite has no node to be busy
|
||||
EXPECT_FALSE(evaluateNodeStatusBanner(lite).show);
|
||||
}
|
||||
|
||||
// Connected full node → no banner.
|
||||
{
|
||||
NodeBannerInputs in; in.connected = true;
|
||||
@@ -4321,6 +4348,64 @@ void testConnectRetryBackoff()
|
||||
EXPECT_TRUE(attempts <= 6);
|
||||
}
|
||||
|
||||
// S9: the startup overlay says what the node is really doing, most specific first.
|
||||
void testChooseDaemonStatus()
|
||||
{
|
||||
using dragonx::daemon::DaemonBusyTracker;
|
||||
using dragonx::daemon::DaemonStatusKind;
|
||||
using dragonx::daemon::chooseDaemonStatus;
|
||||
DaemonBusyTracker idle, rebuilding, replaying;
|
||||
rebuilding.feedLine("Reading blocks for witness rebuild: 60000 / 62583");
|
||||
replaying.feedLine("init message: Activating best chain...");
|
||||
// The incident: a full queue during a rebuild showed "Launching dragonxd…".
|
||||
EXPECT_TRUE(chooseDaemonStatus(false, true, rebuilding) == DaemonStatusKind::Rebuilding);
|
||||
EXPECT_TRUE(chooseDaemonStatus(true, true, rebuilding) == DaemonStatusKind::Rebuilding);
|
||||
EXPECT_TRUE(chooseDaemonStatus(true, false, replaying) == DaemonStatusKind::Replaying);
|
||||
EXPECT_TRUE(chooseDaemonStatus(true, true, idle) == DaemonStatusKind::InitPhase); // "Loading block index"
|
||||
EXPECT_TRUE(chooseDaemonStatus(false, true, idle) == DaemonStatusKind::Busy); // reachable, no answer
|
||||
EXPECT_TRUE(chooseDaemonStatus(false, false, idle) == DaemonStatusKind::Launching); // not bound yet
|
||||
}
|
||||
|
||||
// S10: every string added by the daemon-stop work exists in English and in all 8 languages, with the same
|
||||
// printf arguments (a mismatch is rejected at runtime and would fall back to English, or worse).
|
||||
void testDaemonStopStringsTranslated()
|
||||
{
|
||||
const char* keys[] = {
|
||||
"shutdown_leave_running", "shutdown_leave_running_tip", "shutdown_kill_node", "shutdown_kill_node_tip",
|
||||
"shutdown_kill_confirm_title", "shutdown_kill_confirm_msg", "shutdown_kill_confirm_yes",
|
||||
"shutdown_stop_asking", "shutdown_stop_queued", "shutdown_stop_delivered", "shutdown_stop_cpu_suffix",
|
||||
"shutdown_stop_idle", "node_busy_rebuild_title", "node_busy_rebuild_desc", "node_busy_rebuild_reading",
|
||||
"node_busy_rebuild_extending", "node_busy_replay_title", "node_busy_replay_desc", "node_busy_rpc_title",
|
||||
"node_busy_rpc_desc", "node_starting_title", "node_starting_busy_desc", "node_starting_launch_desc",
|
||||
"sb_node_busy", "stopconfirm_rebuild_title", "stopconfirm_rebuild_body", "stopconfirm_busy_title",
|
||||
"stopconfirm_busy_body", "stopconfirm_stop_wait", "appx_daemon_reinstall_node_busy", "node_busy_running",
|
||||
};
|
||||
// printf conversions in order, "%%" excluded: what must survive translation.
|
||||
auto conversions = [](const std::string& s) {
|
||||
std::string sig;
|
||||
for (size_t i = 0; i < s.size(); ++i) {
|
||||
if (s[i] != '%' || ++i >= s.size()) continue;
|
||||
if (s[i] == '%') continue;
|
||||
while (i < s.size() && std::strchr("-+ #0123456789.*lhLzjtq", s[i])) ++i;
|
||||
if (i < s.size()) sig.push_back(s[i]);
|
||||
}
|
||||
return sig;
|
||||
};
|
||||
const fs::path langDir = fs::path(fixtureDir()) / ".." / ".." / "res" / "lang";
|
||||
for (const char* key : keys) {
|
||||
const std::string english = dragonx::util::I18n::instance().translate(key);
|
||||
EXPECT_TRUE(english != key); // present in the built-in English table
|
||||
for (const char* lang : {"de", "es", "fr", "pt", "ru", "zh", "ja", "ko"}) {
|
||||
std::ifstream in(langDir / (std::string(lang) + ".json"));
|
||||
const auto j = nlohmann::json::parse(in, nullptr, false);
|
||||
const bool has = !j.is_discarded() && j.contains(key) && j[key].is_string();
|
||||
if (!has) std::cerr << "missing translation: " << lang << "." << key << "\n";
|
||||
EXPECT_TRUE(has);
|
||||
if (has) EXPECT_EQ(conversions(j[key].get<std::string>()), conversions(english));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// S3: on Linux a node in its final shutdown phase reads comm "hush-shutoff"; its executable still says
|
||||
// dragonxd, so it must still count as running (it holds the datadir lock until it exits).
|
||||
void testDaemonProcessIdentity()
|
||||
@@ -8917,6 +9002,8 @@ int main()
|
||||
testDaemonBusyTracker();
|
||||
testShouldConfirmStop();
|
||||
testOutputSinceAcrossTrim();
|
||||
testChooseDaemonStatus();
|
||||
testDaemonStopStringsTranslated();
|
||||
#ifdef _WIN32
|
||||
testWindowsStopNeverKillsForeignDaemon();
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user