#!/usr/bin/env python3 # © 2021-2026 TechnoLibre (http://www.technolibre.ca) # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl) import os import re ENV_VAR_FILE = "./env_var.sh" _current_lang = None TRANSLATIONS = { # Main menu "Importation success!": { "fr": "L'importation est un succès!", "en": "Importation success!", }, "Opening TODO ...": { "fr": "Ouverture de TODO en cours ...", "en": "Opening TODO ...", }, "=> Enter your choice by number and press Enter!": { "fr": "=> Entre tes directives par son chiffre et fait Entrée!", "en": "=> Enter your choice by number and press Enter!", }, "Command:": { "fr": "Commande :", "en": "Command:", }, "Execute": { "fr": "🧰 Exécution", "en": "🧰 Execute", }, "Install": { "fr": "📦 Installation", "en": "📦 Install", }, "Assistant": { "fr": "🤖 Assistant", "en": "🤖 Assistant", }, "Fork - Open TODO in a new tab": { "fr": "🔀 Fork - Ouvre TODO dans une nouvelle tabulation", "en": "🔀 Fork - Open TODO in a new tab", }, "Quit": { "fr": "Quitter", "en": "Quit", }, "Command not found !": { "fr": "Commande non trouvée !", "en": "Command not found !", }, "Back": { "fr": "🔙 Retour", "en": "🔙 Back", }, # Execute submenu "Run - Execute and install an instance": { "fr": "🏃 Run - Exécuter et installer une instance", "en": "🏃 Run - Execute and install an instance", }, "Automation - Demonstration of developed features": { "fr": "🦾 Automatisation - Demonstration des fonctions développées", "en": "🦾 Automation - Demonstration of developed features", }, "Update - Update all developed staging source code": { "fr": "🔃 Mise à jour - Update all developed staging source code", "en": "🔃 Update - Update all developed staging source code", }, "Code - Developer tools": { "fr": "💻 Code - Outil pour développeur", "en": "💻 Code - Developer tools", }, "Doc - Documentation search": { "fr": "📖 Doc - Recherche de documentation", "en": "📖 Doc - Documentation search", }, "Database - Database tools": { "fr": "💾 Database - Outils sur les bases de données", "en": "💾 Database - Database tools", }, "Process - Execution tools": { "fr": "📟 Process - Outils sur les executions", "en": "📟 Process - Execution tools", }, "Config - Configuration file management": { "fr": "🔧 Config - Traitement du fichier de configuration", "en": "🔧 Config - Configuration file management", }, "Network - Network tools": { "fr": "📡 Réseau - Outil réseautique", "en": "📡 Network - Network tools", }, "Security - Dependency security audit": { "fr": "🔒 Sécurité - Audit de sécurité des dépendances", "en": "🔒 Security - Dependency security audit", }, "RTK - CLI proxy to reduce LLM token consumption": { "fr": "🪙 RTK - Proxy CLI pour réduire la consommation de tokens LLM", "en": "🪙 RTK - CLI proxy to reduce LLM token consumption", }, # Deploy section "Deploy - Deploy ERPLibre locally": { "fr": "🚀 Déploiement - Déployer ERPLibre localement", "en": "🚀 Deploy - Deploy ERPLibre locally", }, "Deploy ERPLibre to a local directory!": { "fr": "Déployer ERPLibre dans un répertoire local!", "en": "Deploy ERPLibre to a local directory!", }, "Clone ERPLibre locally (git clone)": { "fr": "📥 Cloner ERPLibre localement (git clone)", "en": "📥 Clone ERPLibre locally (git clone)", }, "Target directory path (default: ~/erplibre): ": { "fr": "Chemin du répertoire cible (défaut: ~/erplibre) : ", "en": "Target directory path (default: ~/erplibre): ", }, "Directory already exists: ": { "fr": "Le répertoire existe déjà : ", "en": "Directory already exists: ", }, "Cloning ERPLibre...": { "fr": "Clonage d'ERPLibre en cours...", "en": "Cloning ERPLibre...", }, "ERPLibre cloned successfully to: ": { "fr": "ERPLibre cloné avec succès dans : ", "en": "ERPLibre cloned successfully to: ", }, "Error cloning ERPLibre: ": { "fr": "Erreur lors du clonage d'ERPLibre : ", "en": "Error cloning ERPLibre: ", }, "Configure sshfs": { "fr": "📁 Configurer sshfs", "en": "📁 Configure sshfs", }, "Local": { "fr": "💻 Local", "en": "💻 Local", }, "SSH (remote host)": { "fr": "SSH (hôte distant)", "en": "SSH (remote host)", }, "Remote & services": { "fr": "🌐 Distant & services", "en": "🌐 Remote & services", }, "SSH (remote host)...": { "fr": "🔐 SSH (hôte distant)…", "en": "🔐 SSH (remote host)...", }, "Deploy ERPLibre to a remote host over SSH!": { "fr": "Déployer ERPLibre sur un hôte distant via SSH !", "en": "Deploy ERPLibre to a remote host over SSH!", }, "Virtualization & notifications": { "fr": "Virtualisation & notifications", "en": "Virtualization & notifications", }, "Development": { "fr": "🧰 Développement", "en": "🧰 Development", }, "Data": { "fr": "📊 Données", "en": "📊 Data", }, "Sources & documentation": { "fr": "📚 Sources & documentation", "en": "📚 Sources & documentation", }, "AI & automation": { "fr": "🧠 IA & automatisation", "en": "🧠 AI & automation", }, "Deployment, network & security": { "fr": "🌐 Déploiement, réseau & sécurité", "en": "🌐 Deployment, network & security", }, "Deployment": { "fr": "🚀 Déploiement", "en": "🚀 Deployment", }, "Manage": { "fr": "🛠 Gérer", "en": "🛠 Manage", }, "Catalog": { "fr": "📚 Catalogue", "en": "📚 Catalog", }, "Open the console on a VM": { "fr": "🖥 Ouvrir la console d'une VM", "en": "🖥 Open the console on a VM", }, "Backup": { "fr": "Sauvegarde", "en": "Backup", }, "Restore": { "fr": "Restauration", "en": "Restore", }, "Danger zone": { "fr": "Zone dangereuse", "en": "Danger zone", }, "Setup": { "fr": "Installation", "en": "Setup", }, "Status": { "fr": "Statut", "en": "Status", }, "Optimize": { "fr": "Optimisation", "en": "Optimize", }, "Generate": { "fr": "Génération", "en": "Generate", }, "Advanced": { "fr": "Avancé", "en": "Advanced", }, "To leave the console, press Ctrl+] (then Enter).": { "fr": "Pour quitter la console, appuyez sur Ctrl+] (puis Entrée).", "en": "To leave the console, press Ctrl+] (then Enter).", }, "Default login (if set at deploy): erplibre / erplibre": { "fr": "Login par défaut (si défini au déploiement) : " "erplibre / erplibre", "en": "Default login (if set at deploy): erplibre / erplibre", }, "Console password for 'erplibre' (default: erplibre): ": { "fr": "Mot de passe console pour « erplibre » (défaut : erplibre) : ", "en": "Console password for 'erplibre' (default: erplibre): ", }, "Console/SSH login:": { "fr": "Connexion console/SSH :", "en": "Console/SSH login:", }, "Default login:": { "fr": "Login par défaut :", "en": "Default login:", }, "Add this VM to ~/.ssh/config? (y/N): ": { "fr": "Ajouter cette VM à ~/.ssh/config ? (o/N, défaut : non) : ", "en": "Add this VM to ~/.ssh/config? (y/N, default: no): ", }, "Add each VM to ~/.ssh/config? (Y/n): ": { "fr": "Ajouter chaque VM à ~/.ssh/config ? (O/n, défaut : oui) : ", "en": "Add each VM to ~/.ssh/config? (Y/n, default: yes): ", }, "Waiting for the VM IP (DHCP lease)...": { "fr": "Attente de l'IP de la VM (bail DHCP)...", "en": "Waiting for the VM IP (DHCP lease)...", }, "No IP yet; add it later once the VM has booted.": { "fr": "Pas encore d'IP ; à ajouter plus tard une fois la VM démarrée.", "en": "No IP yet; add it later once the VM has booted.", }, "Added to ~/.ssh/config:": { "fr": "Ajouté à ~/.ssh/config :", "en": "Added to ~/.ssh/config:", }, "Removed from ~/.ssh/config:": { "fr": "Retiré de ~/.ssh/config :", "en": "Removed from ~/.ssh/config:", }, "SSH address input method": { "fr": "Méthode de saisie de l'adresse SSH", "en": "SSH address input method", }, # Proxy SOCKS sur SSH (menu Déploiement › Local) "Configure a SOCKS proxy over SSH": { "fr": "🧦 Configurer Proxy vers SSH", "en": "🧦 Configure a SOCKS proxy over SSH", }, "SOCKS proxy over SSH": { "fr": "Proxy SOCKS par SSH", "en": "SOCKS proxy over SSH", }, "SOCKS port (default:": { "fr": "Port SOCKS (défaut :", "en": "SOCKS port (default:", }, "Firefox configuration": { "fr": "Configuration dans Firefox", "en": "Firefox configuration", }, "Settings, then Network Settings and Settings...,": { "fr": "Paramètres, puis Paramètres réseau et Paramètres…,", "en": "Settings, then Network Settings and Settings...,", }, 'then choose "Manual proxy configuration":': { "fr": "puis choisir « Configuration manuelle du proxy » :", "en": 'then choose "Manual proxy configuration":', }, "SOCKS host:": { "fr": "Hôte SOCKS :", "en": "SOCKS host:", }, "Tick SOCKS v5": { "fr": "Cocher SOCKS v5", "en": "Tick SOCKS v5", }, 'Tick "Proxy DNS when using SOCKS v5"': { "fr": "Cocher « Utiliser un DNS distant lorsque SOCKS v5 est actif »", "en": 'Tick "Proxy DNS when using SOCKS v5"', }, "Domain names are then resolved on the remote side,": { "fr": "Les noms de domaine sont alors résolus côté machine distante,", "en": "Domain names are then resolved on the remote side,", }, "which reaches internal names such as localhost, or": { "fr": "ce qui atteint des noms internes comme localhost, ou des", "en": "which reaches internal names such as localhost, or", }, "hosts of the remote network.": { "fr": "hôtes du réseau de cette machine.", "en": "hosts of the remote network.", }, "Manual entry": { "fr": "Saisie manuelle", "en": "Manual entry", }, "From ~/.ssh/config": { "fr": "Depuis ~/.ssh/config", "en": "From ~/.ssh/config", }, "Your choice (1/2): ": { "fr": "Votre choix (1/2) : ", "en": "Your choice (1/2): ", }, "No SSH hosts found in ~/.ssh/config": { "fr": "Aucun hôte SSH trouvé dans ~/.ssh/config", "en": "No SSH hosts found in ~/.ssh/config", }, "Select SSH host number: ": { "fr": "Numéro de l'hôte SSH à sélectionner : ", "en": "Select SSH host number: ", }, "Invalid selection!": { "fr": "Sélection invalide!", "en": "Invalid selection!", }, "SSH host (e.g.: user@192.168.1.100): ": { "fr": "Hôte SSH (ex: user@192.168.1.100) : ", "en": "SSH host (e.g.: user@192.168.1.100): ", }, "Mounting sshfs on: ": { "fr": "Montage sshfs sur : ", "en": "Mounting sshfs on: ", }, "Mounted on: ": { "fr": "Monté sur : ", "en": "Mounted on: ", }, "To unmount: ": { "fr": "Pour démonter : ", "en": "To unmount: ", }, "Error mounting sshfs: ": { "fr": "Erreur lors du montage sshfs : ", "en": "Error mounting sshfs: ", }, # RTK (Rust Token Killer) "Manage RTK (Rust Token Killer) for token optimization!": { "fr": "Gérer RTK (Rust Token Killer) pour optimiser les tokens!", "en": "Manage RTK (Rust Token Killer) for token optimization!", }, "Install RTK": { "fr": "📦 Installer RTK", "en": "📦 Install RTK", }, "Check RTK version": { "fr": "🔢 Vérifier la version de RTK", "en": "🔢 Check RTK version", }, "Show cumulative token savings": { "fr": "📊 Afficher les économies de tokens cumulées", "en": "📊 Show cumulative token savings", }, "Discover optimization opportunities": { "fr": "🔍 Identifier les opportunités d'optimisation", "en": "🔍 Discover optimization opportunities", }, "Initialize global auto-rewrite hook": { "fr": "🪝 Initialiser le hook auto-rewrite global", "en": "🪝 Initialize global auto-rewrite hook", }, "Check RTK status": { "fr": "🔬 Vérifier le statut de RTK", "en": "🔬 Check RTK status", }, "RTK is not installed. Use option 1 to install it.": { "fr": "RTK n'est pas installé. Utilisez l'option 1 pour l'installer.", "en": "RTK is not installed. Use option 1 to install it.", }, "RTK is installed, version: ": { "fr": "RTK est installé, version : ", "en": "RTK is installed, version: ", }, "RTK installation failed, see the output above.": { "fr": "L'installation de RTK a échoué, voir la sortie ci-dessus.", "en": "RTK installation failed, see the output above.", }, "Installation ended without error, but no rtk binary was found.": { "fr": ( "L'installation s'est terminée sans erreur, mais aucun binaire" " rtk n'a été trouvé." ), "en": "Installation ended without error, but no rtk binary was found.", }, "rtk is not in the PATH of this process, restart TODO.": { "fr": "rtk n'est pas dans le PATH de ce processus, relancer TODO.", "en": "rtk is not in the PATH of this process, restart TODO.", }, "To make it permanent, add to your shell profile:": { "fr": "Pour que ce soit permanent, ajouter au profil du shell :", "en": "To make it permanent, add to your shell profile:", }, "Global auto-rewrite hook: active": { "fr": "Hook auto-rewrite global : actif", "en": "Global auto-rewrite hook: active", }, "Global auto-rewrite hook: inactive": { "fr": "Hook auto-rewrite global : inactif", "en": "Global auto-rewrite hook: inactive", }, "Installation method:": { "fr": "Méthode d'installation :", "en": "Installation method:", }, "curl - Automatic install script": { "fr": "curl - Script d'installation automatique", "en": "curl - Automatic install script", }, "brew - Homebrew (macOS/Linux)": { "fr": "brew - Homebrew (macOS/Linux)", "en": "brew - Homebrew (macOS/Linux)", }, "cargo - Build from source (Rust required)": { "fr": "cargo - Compilation depuis les sources (Rust requis)", "en": "cargo - Build from source (Rust required)", }, # Prompts and messages "Enter your password: ": { "fr": "Entrez votre mot de passe : ", "en": "Enter your password: ", }, "Write your question ": { "fr": "Écrit moi ta question ", "en": "Write your question ", }, "Do you want a new instance?": { "fr": "Voulez-vous une nouvelle instance?", "en": "Do you want a new instance?", }, "SSH port-forwarding": { "fr": "🚇 SSH port-forwarding", "en": "🚇 SSH port-forwarding", }, "Network performance request per second": { "fr": "📶 Performance réseau en requêtes par seconde", "en": "📶 Network performance request per second", }, "Setup queue job for parallelism": { "fr": "⚡ Configurer la file d'attente pour l'exécution parallèle", "en": "⚡ Setup queue job for parallelism", }, "Choose your database": { "fr": "🗃 Choisir sa base de données", "en": "🗃 Choose your database", }, "Development update": { "fr": "Mise à jour du développement", "en": "Development update", }, "What do you need for development?": { "fr": "Qu'avez-vous de besoin pour développer?", "en": "What do you need for development?", }, "Looking for documentation?": { "fr": "Vous cherchez de la documentation?", "en": "Looking for documentation?", }, "Make changes to databases!": { "fr": "Faites des modifications sur les bases de données!", "en": "Make changes to databases!", }, # Database drop / erase "Erase a database": { "fr": "🗑 Effacer une base de données", "en": "🗑 Erase a database", }, "Erase a database — irreversible operation!": { "fr": "Effacer une base de données — opération irréversible !", "en": "Erase a database — irreversible operation!", }, "Erase ALL databases (make db_drop_all)": { "fr": "Effacer TOUTES les bases de données (make db_drop_all)", "en": "Erase ALL databases (make db_drop_all)", }, "Erase a single database": { "fr": "Effacer une seule base de données", "en": "Erase a single database", }, "You are about to erase ALL databases. This cannot be undone.": { "fr": ( "Tu es sur le point d'effacer TOUTES les bases de données." " C'est irréversible." ), "en": "You are about to erase ALL databases. This cannot be undone.", }, "You are about to erase the database '{database}'. This cannot be undone.": { "fr": ( "Tu es sur le point d'effacer la base de données « {database} »." " C'est irréversible." ), "en": ( "You are about to erase the database '{database}'." " This cannot be undone." ), }, "Type 'oui' to confirm (default: no): ": { "fr": "Tape « oui » pour confirmer (défaut : non) : ", "en": "Type 'oui'/'yes' to confirm (default: no): ", }, "Database deletion cancelled.": { "fr": "Effacement de la base de données annulé.", "en": "Database deletion cancelled.", }, "No database selected.": { "fr": "Aucune base de données sélectionnée.", "en": "No database selected.", }, "Cannot list the databases (exit code): ": { "fr": "Impossible de lister les bases (code de retour) : ", "en": "Cannot list the databases (exit code): ", }, "Is PostgreSQL running?": { "fr": "PostgreSQL est-il démarré ?", "en": "Is PostgreSQL running?", }, "No database on this PostgreSQL server.": { "fr": "Aucune base sur ce serveur PostgreSQL.", "en": "No database on this PostgreSQL server.", }, "Manage execution processes!": { "fr": "Manipuler les processus d'exécution!", "en": "Manage execution processes!", }, "Manage ERPLibre and Odoo configuration!": { "fr": "Manipuler la configuration ERPLibre et Odoo!", "en": "Manage ERPLibre and Odoo configuration!", }, "Network tools!": { "fr": "Outil réseautique!", "en": "Network tools!", }, "Dependency security audit!": { "fr": "Audit de securite des dépendances!", "en": "Dependency security audit!", }, "The Bash script failed with return code": { "fr": "Le script Bash a échoué avec le code de retour", "en": "The Bash script failed with return code", }, "No installed environment found. Install an Odoo version first.": { "fr": "Aucun environnement installe trouve. Installez d'abord une version d'Odoo.", "en": "No installed environment found. Install an Odoo version first.", }, "Choose an environment for the audit:": { "fr": "Choisir un environnement pour l'audit :", "en": "Choose an environment for the audit:", }, "Select: ": { "fr": "Sélection : ", "en": "Select: ", }, "Error, cannot understand value": { "fr": "Erreur, impossible de comprendre la valeur", "en": "Error, cannot understand value", }, "Dependencies file not found: ": { "fr": "Fichier de dépendances introuvable : ", "en": "Dependencies file not found: ", }, "Execution: ": { "fr": "Execution : ", "en": "Execution: ", }, "Current": { "fr": "Actuel", "en": "Current", }, "Default": { "fr": "Défaut", "en": "Default", }, "Reboot TODO ...": { "fr": "Reboot TODO ...", "en": "Reboot TODO ...", }, "pip-audit - Check vulnerabilities on Python environments": { "fr": "pip-audit - Verifier les vulnérabilités sur les environnements Python", "en": "pip-audit - Check vulnerabilities on Python environments", }, "Will execute:": { "fr": "Va exécuter :", "en": "Will execute:", }, "Choose a version:": { "fr": "Choisir une version :", "en": "Choose a version:", }, "Install type:": { "fr": "Type d'installation :", "en": "Install type:", }, "Standard install (without extra modules)": { "fr": "Installation standard (sans modules extra)", "en": "Standard install (without extra modules)", }, "Install with extra modules (CybroOdoo - large, slow)": { "fr": "Installation avec modules extra (CybroOdoo - gros, lent)", "en": "Install with extra modules (CybroOdoo - large, slow)", }, # todo.json translatable prompt_descriptions "Test - Minimal base instance": { "fr": "🧪 Test - Instance de base minimale", "en": "🧪 Test - Minimal base instance", }, "Open RobotLibre 🤖 minimal": { "fr": "▶ Ouvrir RobotLibre 🤖 minimal", "en": "▶ Open RobotLibre 🤖 minimal", }, "Open RobotLibre 🤖 with search enabled": { "fr": "▶ Ouvrir RobotLibre 🤖 en activant la recherche", "en": "▶ Open RobotLibre 🤖 with search enabled", }, "Open ERPLibre with TODO 🤖": { "fr": "Ouvrir ERPLibre avec TODO 🤖", "en": "Open ERPLibre with TODO 🤖", }, "Update all erplibre_base on database test": { "fr": "🔄 Mise à jour de tous les erplibre_base sur la base de données test", "en": "🔄 Update all erplibre_base on database test", }, "Show code status": { "fr": "🔍 Afficher le statut du code", "en": "🔍 Show code status", }, "Stash all code": { "fr": "📦 Remiser tout le code", "en": "📦 Stash all code", }, "Format modified code": { "fr": "🎨 Formater le code modifié", "en": "🎨 Format modified code", }, # todo.py hardcoded prompt_descriptions "Mobile - Compile and run software": { "fr": "Mobile - Compiler et exécuter le logiciel", "en": "Mobile - Compile and run software", }, "Upgrade Odoo - Migration Database": { "fr": "🚚 Mise à jour Odoo - Migration de base de données", "en": "🚚 Upgrade Odoo - Migration Database", }, "Upgrade Poetry - Dependency of Odoo": { "fr": "📦 Mise à jour Poetry - Dépendances d'Odoo", "en": "📦 Upgrade Poetry - Dependency of Odoo", }, "Open SHELL": { "fr": "🐚 Ouvrir le SHELL", "en": "🐚 Open SHELL", }, "Upgrade Module": { "fr": "🧩 Mise à jour de module", "en": "🧩 Upgrade Module", }, "Debug": { "fr": "🐛 Débogage", "en": "🐛 Debug", }, "Migration module coverage": { "fr": "📈 Couverture de migration des modules", "en": "📈 Migration module coverage", }, "What change between version": { "fr": "🆕 Quels changements entre les versions", "en": "🆕 What change between version", }, "OCA guidelines": { "fr": "📖 Directives OCA", "en": "📖 OCA guidelines", }, "OCA migration Odoo 19 milestone": { "fr": "🎯 Migration OCA Odoo 19 - Jalons", "en": "🎯 OCA migration Odoo 19 milestone", }, "Download database to create backup (.zip)": { "fr": ( "⬇ Télécharger une base de données pour créer une" " sauvegarde (.zip)" ), "en": "⬇ Download database to create backup (.zip)", }, "Restore from backup (.zip)": { "fr": "♻ Restaurer a partir d'une sauvegarde (.zip)", "en": "♻ Restore from backup (.zip)", }, "Create backup (.zip)": { "fr": "💾 Créer une sauvegarde (.zip)", "en": "💾 Create backup (.zip)", }, "Kill Odoo process from actual port": { "fr": "🛑 Terminer le processus Odoo du port actuel", "en": "🛑 Kill Odoo process from actual port", }, "Kill git daemon server process": { "fr": "🛑 Terminer le processus du serveur git daemon", "en": "🛑 Kill git daemon server process", }, "Git daemon process killed.": { "fr": "Processus git daemon terminé.", "en": "Git daemon process killed.", }, "Generate all configuration": { "fr": "🧱 Générer toute la configuration", "en": "🧱 Generate all configuration", }, "Generate from pre-configuration": { "fr": "📋 Générer a partir de la pre-configuration", "en": "📋 Generate from pre-configuration", }, "Generate from backup file": { "fr": "💾 Générer a partir d'un fichier de sauvegarde", "en": "💾 Generate from backup file", }, "Generate from database": { "fr": "🗄 Générer a partir de la base de données", "en": "🗄 Generate from database", }, "base": { "fr": "base", "en": "base", }, "base + code_generator": { "fr": "base + code_generator", "en": "base + code_generator", }, "base + image_db": { "fr": "base + image_db", "en": "base + image_db", }, "all": { "fr": "tout", "en": "all", }, "Debug todo.py": { "fr": "Débogage todo.py", "en": "Debug todo.py", }, # Test section "Test - Test an Odoo module": { "fr": "🧪 Test - Tester un module Odoo", "en": "🧪 Test - Test an Odoo module", }, "Test an Odoo module on a temporary database!": { "fr": "Tester un module Odoo sur une base de données temporaire!", "en": "Test an Odoo module on a temporary database!", }, "Test a module": { "fr": "🧪 Tester un module", "en": "🧪 Test a module", }, "Test a module with code coverage": { "fr": "📊 Tester un module avec couverture de code", "en": "📊 Test a module with code coverage", }, "ERPLibre unit tests": { "fr": "⚗ Tests unitaires ERPLibre", "en": "⚗ ERPLibre unit tests", }, "Mail unit tests": { "fr": "📧 Tests unitaires courriel", "en": "📧 Mail unit tests", }, "Analyse unit tests": { "fr": "🔍 Tests unitaires analyse", "en": "🔍 Analyse unit tests", }, "Running unit tests": { "fr": "Exécution des tests unitaires", "en": "Running unit tests", }, "All unit tests passed": { "fr": "Tous les tests unitaires ont réussi", "en": "All unit tests passed", }, "Some unit tests failed, exit code": { "fr": "Des tests unitaires ont échoué, code de sortie", "en": "Some unit tests failed, exit code", }, "Module name to test: ": { "fr": "Nom du module à tester : ", "en": "Module name to test: ", }, "Temporary database name (default: test_todo_tmp): ": { "fr": "Nom de la base de données temporaire (défaut: test_todo_tmp) : ", "en": "Temporary database name (default: test_todo_tmp): ", }, "Extra modules to install (comma-separated, empty for none): ": { "fr": "Modules supplémentaires à installer (séparés par des virgules, vide pour aucun) : ", "en": "Extra modules to install (comma-separated, empty for none): ", }, "Log level (default: test): ": { "fr": "Niveau de log (défaut: test) : ", "en": "Log level (default: test): ", }, "Creating temporary database": { "fr": "Création de la base de données temporaire", "en": "Creating temporary database", }, "Installing modules": { "fr": "Installation des modules", "en": "Installing modules", }, "Running tests": { "fr": "Exécution des tests", "en": "Running tests", }, "Cleaning up temporary database": { "fr": "Suppression de la base de données temporaire", "en": "Cleaning up temporary database", }, "Keep the temporary database? (y/N): ": { "fr": "Conserver la base de données temporaire? (o/N, défaut : non) : ", "en": "Keep the temporary database? (y/N, default: no): ", }, "Database kept": { "fr": "Base de données conservée", "en": "Database kept", }, "Tests completed successfully!": { "fr": "Tests terminés avec succès!", "en": "Tests completed successfully!", }, "Tests failed with return code": { "fr": "Les tests ont échoué avec le code de retour", "en": "Tests failed with return code", }, "Module name is required!": { "fr": "Le nom du module est requis!", "en": "Module name is required!", }, # Git section "Git - Git and shell tools": { "fr": "🌿 Git - Outils Git et Shell", "en": "🌿 Git - Git and shell tools", }, "Git and shell management tools!": { "fr": "Outils de gestion Git et Shell!", "en": "Git and shell management tools!", }, "Local git server": { "fr": "🗄 Serveur git local", "en": "🗄 Local git server", }, "Manage local git repository server!": { "fr": "Gérer le serveur de dépôts git local!", "en": "Manage local git repository server!", }, "Deploy a local git server (~/.git-server)": { "fr": "Déployer un serveur git local (~/.git-server)", "en": "Deploy a local git server (~/.git-server)", }, "Deploy a production git server (/srv/git, root required)": { "fr": "Déployer un serveur git production (/srv/git, root requis)", "en": "Deploy a production git server (/srv/git, root required)", }, "Starting git server deployment...": { "fr": "Démarrage du déploiement du serveur git...", "en": "Starting git server deployment...", }, "Local mode (~/.git-server)": { "fr": "Mode local (~/.git-server)", "en": "Local mode (~/.git-server)", }, "Production mode (/srv/git, root required)": { "fr": "Mode production (/srv/git, root requis)", "en": "Production mode (/srv/git, root required)", }, "Run all (init + remote + push + serve)": { "fr": "Tout exécuter (init + remote + push + serve)", "en": "Run all (init + remote + push + serve)", }, "Init - Create bare repos": { "fr": "Init - Créer les bare repos", "en": "Init - Create bare repos", }, "Remote - Add local remotes": { "fr": "Remote - Ajouter les remotes locaux", "en": "Remote - Add local remotes", }, "Push - Push to local server": { "fr": "Push - Pousser vers le serveur local", "en": "Push - Push to local server", }, "Serve - Start git daemon": { "fr": "Serve - Démarrer le daemon git", "en": "Serve - Start git daemon", }, # Git remote add "Add a remote to a local repository": { "fr": "🔗 Ajouter un remote vers un dépôt local", "en": "🔗 Add a remote to a local repository", }, "Remote name (default: localhost): ": { "fr": "Nom du remote (défaut: localhost) : ", "en": "Remote name (default: localhost): ", }, "Repository address (e.g.: git://192.168.1.100/my-repo.git): ": { "fr": "Adresse du dépôt (ex: git://192.168.1.100/mon-repo.git) : ", "en": "Repository address (e.g.: git://192.168.1.100/my-repo.git): ", }, "Repository address is required!": { "fr": "L'adresse du dépôt est requise!", "en": "Repository address is required!", }, "Remote added successfully!": { "fr": "Remote ajouté avec succès!", "en": "Remote added successfully!", }, "Error adding remote: ": { "fr": "Erreur lors de l'ajout du remote : ", "en": "Error adding remote: ", }, # Git hooks # Starship "Install Starship on Shell": { "fr": "🚀 Installer Starship sur le shell", "en": "🚀 Install Starship on Shell", }, "Install Claude Code": { "fr": "🤖 Installer Claude Code", "en": "🤖 Install Claude Code", }, "Install opencode": { "fr": "🧠 Installer opencode", "en": "🧠 Install opencode", }, "Installation failed, see the output above.": { "fr": "L'installation a échoué, voir la sortie ci-dessus.", "en": "Installation failed, see the output above.", }, "Already on the PATH: ": { "fr": "Déjà dans le PATH : ", "en": "Already on the PATH: ", }, "PATH line added to: ": { "fr": "Ligne de PATH ajoutée à : ", "en": "PATH line added to: ", }, "Binary not found at: ": { "fr": "Binaire introuvable à : ", "en": "Binary not found at: ", }, "Install starship? (y/N): ": { "fr": "Installer starship ? (o/N) : ", "en": "Install starship? (y/N): ", }, "No starship package here, falling back upstream.": { "fr": "Aucun paquet starship ici, recours à l'installateur amont.", "en": "No starship package here, falling back upstream.", }, "Run the upstream installer? (y/N): ": { "fr": "Lancer l'installateur amont ? (o/N) : ", "en": "Run the upstream installer? (y/N): ", }, "starship is not installed, shell left untouched.": { "fr": "starship n'est pas installé, le shell reste intact.", "en": "starship is not installed, shell left untouched.", }, "Which shell configuration?": { "fr": "Quel fichier de configuration de shell ?", "en": "Which shell configuration?", }, "starship is already hooked into: ": { "fr": "starship est déjà accroché à : ", "en": "starship is already hooked into: ", }, "starship hooked into: ": { "fr": "starship accroché à : ", "en": "starship hooked into: ", }, "Open a new shell to see it.": { "fr": "Ouvrir un nouveau shell pour le voir.", "en": "Open a new shell to see it.", }, "Set merge.conflictStyle to zdiff3 (global)": { "fr": "🔀 Configurer merge.conflictStyle en zdiff3 (global)", "en": "🔀 Set merge.conflictStyle to zdiff3 (global)", }, "Failed to set merge.conflictStyle, see the output above.": { "fr": ( "Échec du réglage de merge.conflictStyle, voir la sortie" " ci-dessus." ), "en": "Failed to set merge.conflictStyle, see the output above.", }, "Install git hooks (commit-msg, pre-commit)": { "fr": "🪝 Installer les hooks git (commit-msg, pre-commit)", "en": "🪝 Install git hooks (commit-msg, pre-commit)", }, "Hooks directory is missing: ": { "fr": "Le répertoire des hooks est absent : ", "en": "Hooks directory is missing: ", }, "Another hooks path is already set: ": { "fr": "Un autre chemin de hooks est déjà configuré : ", "en": "Another hooks path is already set: ", }, "Replace it? (y/Y): ": { "fr": "Le remplacer? (y/Y) : ", "en": "Replace it? (y/Y): ", }, "Execution bit added: ": { "fr": "Bit d'exécution ajouté : ", "en": "Execution bit added: ", }, "Git hooks installed!": { "fr": "Hooks git installés!", "en": "Git hooks installed!", }, "Error installing hooks: ": { "fr": "Erreur lors de l'installation des hooks : ", "en": "Error installing hooks: ", }, # Git config vim "Configure git local editor to vim": { "fr": "📝 Configuration git local par vim", "en": "📝 Configure git local editor to vim", }, "Generate git patch to /tmp": { "fr": "🩹 Générer une patch git dans /tmp", "en": "🩹 Generate git patch to /tmp", }, "Git editor configured to vim successfully!": { "fr": "Éditeur git configuré sur vim avec succès!", "en": "Git editor configured to vim successfully!", }, "Error during configuration: ": { "fr": "Erreur lors de la configuration : ", "en": "Error during configuration: ", }, # GPT code - Claude automation "Add an automation with Claude in todo.py": { "fr": "🤖 Ajouter une automatisation avec Claude dans todo.py", "en": "🤖 Add an automation with Claude in todo.py", }, "Description of the command to add: ": { "fr": "Description de la commande à ajouter : ", "en": "Description of the command to add: ", }, "Bash command to execute: ": { "fr": "Commande bash à exécuter : ", "en": "Bash command to execute: ", }, "Menu section (git/code/config/network/process): ": { "fr": "Section du menu (git/code/config/network/process) : ", "en": "Menu section (git/code/config/network/process): ", }, "Automation added successfully in todo.json!": { "fr": "Automatisation ajoutée avec succès dans todo.json!", "en": "Automation added successfully in todo.json!", }, "Error adding automation: ": { "fr": "Erreur lors de l'ajout de l'automatisation : ", "en": "Error adding automation: ", }, # SSH Deploy section "Deploy - Deploy ERPLibre via SSH": { "fr": "Déploiement - Déployer ERPLibre via SSH", "en": "Deploy - Deploy ERPLibre via SSH", }, "SSH deployment tools!": { "fr": "Outils de déploiement SSH!", "en": "SSH deployment tools!", }, "SSH - Check connection": { "fr": "🔌 SSH - Vérifier la connexion", "en": "🔌 SSH - Check connection", }, "SSH - Sync files (rsync)": { "fr": "🔄 SSH - Synchroniser les fichiers (rsync)", "en": "🔄 SSH - Sync files (rsync)", }, "SSH - Install ERPLibre": { "fr": "📦 SSH - Installer ERPLibre", "en": "📦 SSH - Install ERPLibre", }, "SSH - Start Odoo": { "fr": "🟢 SSH - Démarrer Odoo", "en": "🟢 SSH - Start Odoo", }, "SSH - Stop Odoo": { "fr": "🔴 SSH - Arrêter Odoo", "en": "🔴 SSH - Stop Odoo", }, "SSH - Restart Odoo": { "fr": "🔁 SSH - Redémarrer Odoo", "en": "🔁 SSH - Restart Odoo", }, "SSH - Service status": { "fr": "📊 SSH - Statut du service", "en": "📊 SSH - Service status", }, "SSH - View logs": { "fr": "📜 SSH - Voir les logs", "en": "📜 SSH - View logs", }, "SSH - Run make target": { "fr": "🧰 SSH - Exécuter une cible make", "en": "🧰 SSH - Run make target", }, "SSH - Install systemd service": { "fr": "🧩 SSH - Installer le service systemd", "en": "🧩 SSH - Install systemd service", }, "SSH - Configure nginx + SSL": { "fr": "🔒 SSH - Configurer nginx + SSL", "en": "🔒 SSH - Configure nginx + SSL", }, "Remote host (user@hostname or hostname): ": { "fr": "Hôte distant (user@hostname ou hostname) : ", "en": "Remote host (user@hostname or hostname): ", }, "SSH user (default: erplibre): ": { "fr": "Utilisateur SSH (défaut: erplibre) : ", "en": "SSH user (default: erplibre): ", }, "SSH port (default: 22): ": { "fr": "Port SSH (défaut: 22) : ", "en": "SSH port (default: 22): ", }, "SSH key path (default: ~/.ssh/id_rsa, empty for none): ": { "fr": "Chemin de la clé SSH (défaut: ~/.ssh/id_rsa, vide pour aucune) : ", "en": "SSH key path (default: ~/.ssh/id_rsa, empty for none): ", }, "Remote path (default: ~/erplibre_deploy_2): ": { "fr": "Chemin distant (défaut: ~/erplibre_deploy_2) : ", "en": "Remote path (default: ~/erplibre_deploy_2): ", }, "Make target to run remotely: ": { "fr": "Cible make à exécuter à distance : ", "en": "Make target to run remotely: ", }, "Domain name (e.g.: example.com): ": { "fr": "Nom de domaine (ex: example.com) : ", "en": "Domain name (e.g.: example.com): ", }, "Admin email for SSL certificate: ": { "fr": "Email administrateur pour le certificat SSL : ", "en": "Admin email for SSL certificate: ", }, "SSH host is required!": { "fr": "L'hôte SSH est requis!", "en": "SSH host is required!", }, # Language selection "Choose language / Choisir la langue": { "fr": "Choisir la langue / Choose language", "en": "Choose language / Choisir la langue", }, "French": { "fr": "Français", "en": "French", }, "English": { "fr": "Anglais", "en": "English", }, "Language changed to: English": { "fr": "Langue changée pour : Francais", "en": "Language changed to: English", }, "TODO execution time": { "fr": "Temps d'exécution TODO", "en": "TODO execution time", }, "Keyboard interrupt": { "fr": "Interruption clavier", "en": "Keyboard interrupt", }, # GPT code section "GPT code - AI assistant tools": { "fr": "🤖 GPT code - Outils d'assistant IA", "en": "🤖 GPT code - AI assistant tools", }, "AI assistant tools for development!": { "fr": "Outils d'assistant IA pour le développement!", "en": "AI assistant tools for development!", }, "Configure Claude Code configurations": { "fr": "🛠 Configurer les configurations Claude Code", "en": "🛠 Configure Claude Code configurations", }, "Commit - OCA/Odoo commit command": { "fr": "💬 Commit - Commande de commit OCA/Odoo", "en": "💬 Commit - OCA/Odoo commit command", }, "Git prepare merge - Git merge preparation command": { "fr": "🤝 Git prepare merge - Commande de préparation merge git", "en": "🤝 Git prepare merge - Git merge preparation command", }, "Todo Add Command + Plan Max - Plan and add a todo.py command": { "fr": ( "🧭 Todo Add Command + Plan Max - Planifier et ajouter une" " commande au menu todo.py" ), "en": ( "🧭 Todo Add Command + Plan Max - Plan and add a todo.py command" ), }, "Todo Generate Code - Code by the OCA rules at high effort": { "fr": ( "🏭 Todo Generate Code - Coder selon les règles OCA, effort élevé" ), "en": "🏭 Todo Generate Code - Code by the OCA rules at high effort", }, "Enter your full name: ": { "fr": "Entrez votre nom complet : ", "en": "Enter your full name: ", }, "Enter your email: ": { "fr": "Entrez votre courriel : ", "en": "Enter your email: ", }, "Deploy Claude Code commands!": { "fr": "Déployer les commandes Claude Code!", "en": "Deploy Claude Code commands!", }, # Claude Code plugins "Claude Code plugins - marketplaces and ERPLibre list": { "fr": "🧩 Plugins Claude Code - marketplaces et liste ERPLibre", "en": "🧩 Claude Code plugins - marketplaces and ERPLibre list", }, "Manage Claude Code plugins and marketplaces!": { "fr": "Gérer les plugins et les marketplaces de Claude Code!", "en": "Manage Claude Code plugins and marketplaces!", }, "Inventory": { "fr": "Inventaire", "en": "Inventory", }, "List installed plugins": { "fr": "Lister les plugins installés", "en": "List installed plugins", }, "List configured marketplaces": { "fr": "Lister les marketplaces configurés", "en": "List configured marketplaces", }, "Search a plugin in the marketplaces": { "fr": "Chercher un plugin dans les marketplaces", "en": "Search a plugin in the marketplaces", }, "Show a plugin detail and its token cost": { "fr": "Afficher le détail d'un plugin et son coût en tokens", "en": "Show a plugin detail and its token cost", }, "Install plugins": { "fr": "Installer des plugins", "en": "Install plugins", }, "Install the ERPLibre preferred list": { "fr": "Installer la liste préférée d'ERPLibre", "en": "Install the ERPLibre preferred list", }, "Install a plugin by name": { "fr": "Installer un plugin par son nom", "en": "Install a plugin by name", }, "Add a marketplace": { "fr": "Ajouter un marketplace", "en": "Add a marketplace", }, # Sert la section « Maintenance » des deux menus qui en portent une : # la traduction est la même, et une clé répétée écrase la précédente en # silence. "Maintenance": { "fr": "Maintenance", "en": "Maintenance", }, "Update the marketplaces and the plugins": { "fr": "Mettre à jour les marketplaces et les plugins", "en": "Update the marketplaces and the plugins", }, "Uninstall a plugin": { "fr": "Désinstaller un plugin", "en": "Uninstall a plugin", }, "The claude command is not in the PATH.": { "fr": "La commande claude n'est pas dans le PATH.", "en": "The claude command is not in the PATH.", }, "ERPLibre preferred plugins:": { "fr": "Plugins préférés d'ERPLibre :", "en": "ERPLibre preferred plugins:", }, "brainstorming, subagent-driven development, TDD": { "fr": ("brainstorming, développement piloté par sous-agents, TDD"), "en": "brainstorming, subagent-driven development, TDD", }, "Python type checking and code intelligence": { "fr": "typage Python et intelligence de code", "en": "Python type checking and code intelligence", }, "vulnerability scan run entirely in session": { "fr": "analyse de vulnérabilités entièrement en session", "en": "vulnerability scan run entirely in session", }, "write, improve and evaluate the repository skills": { "fr": "écrire, améliorer et évaluer les skills du dépôt", "en": "write, improve and evaluate the repository skills", }, "Install these plugins? (y/Y): ": { "fr": "Installer ces plugins ? (o/O) : ", "en": "Install these plugins? (y/Y): ", }, "Already installed, skipped.": { "fr": "Déjà installé, ignoré.", "en": "Already installed, skipped.", }, "Plugin name: ": { "fr": "Nom du plugin : ", "en": "Plugin name: ", }, "Marketplace source (URL, path or owner/repo): ": { "fr": "Source du marketplace (URL, chemin ou propriétaire/dépôt) : ", "en": "Marketplace source (URL, path or owner/repo): ", }, "Keyword to search: ": { "fr": "Mot-clé à chercher : ", "en": "Keyword to search: ", }, "No marketplace is configured.": { "fr": "Aucun marketplace n'est configuré.", "en": "No marketplace is configured.", }, "No plugin matches this keyword.": { "fr": "Aucun plugin ne correspond à ce mot-clé.", "en": "No plugin matches this keyword.", }, "Uninstall this plugin? (y/Y): ": { "fr": "Désinstaller ce plugin ? (o/O) : ", "en": "Uninstall this plugin? (y/Y): ", }, "A restart of Claude Code applies the change.": { "fr": "Un redémarrage de Claude Code applique le changement.", "en": "A restart of Claude Code applies the change.", }, "Show installed custom commands": { "fr": "📇 Afficher les commandes personnalisées installées", "en": "📇 Show installed custom commands", }, "No custom commands found in ~/.claude/commands/": { "fr": "Aucune commande personnalisée trouvée dans ~/.claude/commands/", "en": "No custom commands found in ~/.claude/commands/", }, "command not installed": { "fr": "non installée", "en": "not installed", }, "not from ERPLibre": { "fr": "hors ERPLibre", "en": "not from ERPLibre", }, "installed copy": { "fr": "copie installée", "en": "installed copy", }, "template": { "fr": "gabarit", "en": "template", }, "Total: %s installed, %s to redeploy, %s not installed": { "fr": "Total : %s installées, %s à redéployer, %s non installées", "en": "Total: %s installed, %s to redeploy, %s not installed", }, "A command not installed is deployed from this menu.": { "fr": "Une commande non installée se déploie depuis ce menu.", "en": "A command not installed is deployed from this menu.", }, "Show the differences? [o/N] ": { "fr": "Afficher les différences ? [o/N] ", "en": "Show the differences? [y/N] ", }, "Redeploy the %s outdated command(s)? [o/N] ": { "fr": "Redéployer les %s commande(s) périmée(s) ? [o/N] ", "en": "Redeploy the %s outdated command(s)? [y/N] ", }, "Claude Code custom commands:": { "fr": "Commandes personnalisées Claude Code :", "en": "Claude Code custom commands:", }, "File already exists: ": { "fr": "Le fichier existe déjà : ", "en": "File already exists: ", }, "Do you want to overwrite the file? (y/Y): ": { "fr": "Voulez-vous écraser le fichier? (y/Y) : ", "en": "Do you want to overwrite the file? (y/Y): ", }, "Nothing to do.": { "fr": "Rien à faire.", "en": "Nothing to do.", }, "File created successfully: ": { "fr": "Fichier créé avec succès : ", "en": "File created successfully: ", }, "Error creating file: ": { "fr": "Erreur lors de la création du fichier : ", "en": "Error creating file: ", }, # NTFY section "Deploy - Install NTFY notification server": { "fr": "🔔 Déployer - Installer le serveur de notifications NTFY", "en": "🔔 Deploy - Install NTFY notification server", }, "Deploy a local NTFY push notification server (Ubuntu/Arch)": { "fr": "Déployer un serveur local de notifications NTFY (Ubuntu/Arch)", "en": "Deploy a local NTFY push notification server (Ubuntu/Arch)", }, "NTFY server port (default: 8080): ": { "fr": "Port du serveur NTFY (défaut : 8080) : ", "en": "NTFY server port (default: 8080): ", }, "NTFY base URL": { "fr": "URL de base NTFY", "en": "NTFY base URL", }, "Installing NTFY server (requires sudo)...": { "fr": "Installation du serveur NTFY (sudo requis)...", "en": "Installing NTFY server (requires sudo)...", }, "NTFY server installed and started successfully!": { "fr": "Serveur NTFY installé et démarré avec succès!", "en": "NTFY server installed and started successfully!", }, "Error installing NTFY server: ": { "fr": "Erreur lors de l'installation du serveur NTFY : ", "en": "Error installing NTFY server: ", }, "NTFY install script not found: ": { "fr": "Script d'installation NTFY introuvable : ", "en": "NTFY install script not found: ", }, # Cache de téléchargement des VM QEMU (erplibre_go_qemu_cache) "QEMU cache - Download mirror for local VMs": { "fr": "📦 Cache QEMU - Miroir de téléchargement des VM locales", "en": "📦 QEMU cache - Download mirror for local VMs", }, "QEMU download cache for local VMs": { "fr": "Cache de téléchargement QEMU pour les VM locales", "en": "QEMU download cache for local VMs", }, "Cache - Install or reinstall": { "fr": "📥 Cache - Installer ou réinstaller", "en": "📥 Cache - Install or reinstall", }, "Cache - Diagnose: does it serve?": { "fr": "🔍 Cache - Diagnostic : sert-il vraiment ?", "en": "🔍 Cache - Diagnose: does it serve?", }, " or entry 3 of this menu, which does it for you.": { "fr": " ou l'entrée 3 de ce menu, qui le fait pour vous.", "en": " or entry 3 of this menu, which does it for you.", }, "Cache - Service state": { "fr": "⚙ Cache - État du service", "en": "⚙ Cache - Service state", }, "State of the cache service": { "fr": "État du service du cache", "en": "State of the cache service", }, "Stopping it removes the rules: no VM is redirected.": { "fr": "L'arrêter retire les règles : plus aucune VM n'est détournée.", "en": "Stopping it removes the rules: no VM is redirected.", }, "starts at boot": {"fr": "démarre au boot", "en": "starts at boot"}, "not at boot": {"fr": "pas au boot", "en": "not at boot"}, "Service - Start (start)": { "fr": "▶ Service - Démarrer (start)", "en": "▶ Service - Start (start)", }, "Service - Start at boot (enable)": { "fr": "🔗 Service - Démarrer au boot (enable)", "en": "🔗 Service - Start at boot (enable)", }, "Service - Do not start at boot (disable)": { "fr": "🚫 Service - Ne plus démarrer au boot (disable)", "en": "🚫 Service - Do not start at boot (disable)", }, "Service - Stop (stop)": { "fr": "⏹ Service - Arrêter (stop)", "en": "⏹ Service - Stop (stop)", }, "Service - Detailed state (status)": { "fr": "📋 Service - État détaillé (status)", "en": "📋 Service - Detailed state (status)", }, "Service - Logs (log)": { "fr": "📜 Service - Journal (log)", "en": "📜 Service - Logs (log)", }, "Access log, last requests:": { "fr": "Journal d'accès, dernières requêtes :", "en": "Access log, last requests:", }, " Interception is transparent and covers the whole bridge:": { "fr": " Le détournement est transparent et vaut pour tout le pont :", "en": " Interception is transparent and covers the whole bridge:", }, " a VM cannot opt out from the inside. Omitting the authority": { "fr": " une VM ne peut pas s'y soustraire de l'intérieur. Retirer l'autorité", "en": " a VM cannot opt out from the inside. Omitting the authority", }, " does not bypass anything — the VM is redirected all the same": { "fr": " ne contourne rien — la VM est détournée quand même et échoue", "en": " does not bypass anything — the VM is redirected all the same", }, " and fails on « self-signed certificate in chain ».": { "fr": " sur « self-signed certificate in certificate chain ».", "en": " and fails on « self-signed certificate in chain ».", }, " For ONE VM: tick « keep this VM out of the cache » when": { "fr": " Pour UNE VM : cocher « soustraire cette VM au cache » au", "en": " For ONE VM: tick « keep this VM out of the cache » when", }, " deploying, or pass --cache-bypass. Its MAC address is fixed": { "fr": " déploiement, ou passer --cache-bypass. Son adresse MAC est fixée", "en": " deploying, or pass --cache-bypass. Its MAC address is fixed", }, " before creation and an exception is posted on the host, so": { "fr": " avant la création et une exception est posée sur l'hôte : plus", "en": " before creation and an exception is posted on the host, so", }, " nothing redirects it. Entry 4 lists them; an exception whose": { "fr": " rien ne la détourne. L'entrée 4 les liste ; une exception dont", "en": " nothing redirects it. Entry 4 lists them; an exception whose", }, " VM is gone must be removed, a freed MAC being reused.": { "fr": " la VM n'existe plus est à retirer, une MAC libérée se réattribuant.", "en": " VM is gone must be removed, a freed MAC being reused.", }, " For EVERY VM: stop the service, entry 3 or": { "fr": " Pour TOUTES les VM : arrêter le service, entrée 3 ou", "en": " For EVERY VM: stop the service, entry 3 or", }, "Cache - VMs kept out of the cache": { "fr": "🎫 Cache - Les VM soustraites au cache", "en": "🎫 Cache - VMs kept out of the cache", }, "Exceptions - Remove the stale ones": { "fr": "🧹 Exceptions - Retirer celles dont la VM n'existe plus", "en": "🧹 Exceptions - Remove the stale ones", }, "Exceptions - Remove one by its MAC": { "fr": "✂ Exceptions - En retirer une par sa MAC", "en": "✂ Exceptions - Remove one by its MAC", }, "VMs kept out of the download cache": { "fr": "Les VM soustraites au cache de téléchargement", "en": "VMs kept out of the download cache", }, "VM gone": { "fr": "VM disparue", "en": "VM gone", }, "No exception: every VM goes through the cache.": { "fr": "Aucune exception : toutes les VM passent par le cache.", "en": "No exception: every VM goes through the cache.", }, "Tick the box when deploying to add one.": { "fr": "Cocher la case au déploiement pour en poser une.", "en": "Tick the box when deploying to add one.", }, "A freed MAC gets reused: such an entry would": { "fr": "Une MAC libérée se réattribue : une telle entrée soustrairait", "en": "A freed MAC gets reused: such an entry would", }, "quietly keep a NEW VM out of the cache.": { "fr": "au cache une VM NEUVE, sans que rien ne le dise.", "en": "quietly keep a NEW VM out of the cache.", }, "Nothing is stale.": { "fr": "Rien n'est orphelin.", "en": "Nothing is stale.", }, "MAC to give back to the cache": { "fr": "MAC à rendre au cache", "en": "MAC to give back to the cache", }, "Keep this VM out of the download cache? (y/N): ": { "fr": "Soustraire cette VM au cache de téléchargement ? (o/N) : ", "en": "Keep this VM out of the download cache? (y/N): ", }, "Keep this VM out of the download cache": { "fr": "Soustraire cette VM au cache de téléchargement", "en": "Keep this VM out of the download cache", }, "Cache exceptions removed:": { "fr": "Exceptions du cache retirées :", "en": "Cache exceptions removed:", }, "Exceptions:": {"fr": "Exceptions :", "en": "Exceptions:"}, "with no VM left": { "fr": "sans VM", "en": "with no VM left", }, "Remove them from entry 4 of this menu.": { "fr": "Les retirer depuis l'entrée 4 de ce menu.", "en": "Remove them from entry 4 of this menu.", }, "This destroys the machines of this test and their disks.": { "fr": "Cela détruit les machines de ce test et leurs disques.", "en": "This destroys the machines of this test and their disks.", }, "Destroy the machines of this test?": { "fr": "Détruire les machines de ce test ?", "en": "Destroy the machines of this test?", }, "Machines created:": { "fr": "Machines créées :", "en": "Machines created:", }, "Test - Choose and run": { "fr": "🧭 Test - Choisir et lancer", "en": "🧭 Test - Choose and run", }, "Which test?": { "fr": "Quel essai ?", "en": "Which test?", }, "The cache: two VMs, measure the gain": { "fr": "⚡ Le cache : deux VM, mesurer le gain", "en": "⚡ The cache: two VMs, measure the gain", }, "The offline counter-proof": { "fr": "📴 La contre-épreuve hors ligne", "en": "📴 The offline counter-proof", }, "The control: two VMs WITHOUT the cache": { "fr": "⚖ Le témoin : deux VM SANS le cache", "en": "⚖ The control: two VMs WITHOUT the cache", }, "All three, one after another": { "fr": "🔁 Les trois, l'un après l'autre", "en": "🔁 All three, one after another", }, "Which load?": { "fr": "Quelle charge ?", "en": "Which load?", }, "Minimum: a batch of packages, minutes": { "fr": "🪶 Minimum : un lot de paquets, quelques minutes", "en": "🪶 Minimum: a batch of packages, minutes", }, "ERPLibre + Odoo 18: the real thing, hours": { "fr": "🏗 ERPLibre + Odoo 18 : l'installation réelle, des heures", "en": "🏗 ERPLibre + Odoo 18: the real thing, hours", }, "Which system?": { "fr": "Quel système ?", "en": "Which system?", }, "About to run, one after another:": { "fr": "Va exécuter, l'un après l'autre :", "en": "About to run, one after another:", }, "The real load takes hours per VM, not minutes.": { "fr": "La charge réelle prend des heures par VM, pas des minutes.", "en": "The real load takes hours per VM, not minutes.", }, "Run these long tests?": { "fr": "Lancer ces tests longs ?", "en": "Run these long tests?", }, "Git mirrors:": { "fr": "Miroirs git :", "en": "Git mirrors:", }, "Git is mirrored, not cached": { "fr": "Git est mis en miroir, pas caché", "en": "Git is mirrored, not cached", }, " Git's protocol is a negotiation: the server computes its": { "fr": " Le protocole git est une négociation : le serveur calcule sa", "en": " Git's protocol is a negotiation: the server computes its", }, " answer from what the client already holds, so no answer is": { "fr": " réponse d'après ce que le client détient déjà, si bien qu'aucune", "en": " answer from what the client already holds, so no answer is", }, " reusable. A bare mirror per upstream repo is kept instead,": { "fr": " réponse ne se réutilise. Un miroir nu par dépôt amont est tenu à la", "en": " reusable. A bare mirror per upstream repo is kept instead,", }, " and served locally — which also works with no network.": { "fr": " place, et servi localement — ce qui marche aussi sans réseau.", "en": " and served locally — which also works with no network.", }, " A mirror is COMPLETE: it weighs what the upstream repo": { "fr": " Un miroir est COMPLET : il pèse ce que pèse le dépôt amont,", "en": " A mirror is COMPLETE: it weighs what the upstream repo", }, " weighs, history included.": { "fr": " historique compris.", "en": " weighs, history included.", }, " Neither the objects nor the mirrors shrink by themselves,": { "fr": " Ni les objets ni les miroirs ne diminuent d'eux-mêmes, et les deux", "en": " Neither the objects nor the mirrors shrink by themselves,", }, " and both live on the orchestrator's disk. The diagnosis": { "fr": " vivent sur le disque de l'orchestrateur. Le diagnostic dit ce", "en": " and both live on the orchestrator's disk. The diagnosis", }, " entry says what each of the two occupies.": { "fr": " qu'occupe chacun des deux.", "en": " entry says what each of the two occupies.", }, "Cache - Git mirrors: fill them ahead": { "fr": "🪞 Cache - Miroirs git : prendre l'avance", "en": "🪞 Cache - Git mirrors: fill them ahead", }, "Git mirrors of the ERPLibre manifests": { "fr": "Miroirs git des manifestes ERPLibre", "en": "Git mirrors of the ERPLibre manifests", }, "Already mirrored:": { "fr": "Déjà en miroir :", "en": "Already mirrored:", }, "No repository found in manifest/": { "fr": "Aucun dépôt trouvé dans manifest/", "en": "No repository found in manifest/", }, "A mirror is complete: this can take tens of GiB": { "fr": "Un miroir est complet : cela peut prendre des dizaines de Gio", "en": "A mirror is complete: this can take tens of GiB", }, "and hours on the first run. Nothing erases it.": { "fr": "et des heures au premier passage. Rien ne l'efface.", "en": "and hours on the first run. Nothing erases it.", }, "Free space:": { "fr": "Place libre :", "en": "Free space:", }, "Fill the git mirrors now?": { "fr": "Remplir les miroirs git maintenant ?", "en": "Fill the git mirrors now?", }, "Mirrors - Fill the base of the active Odoo version": { "fr": "📥 Miroirs - Remplir la base de la version d'Odoo active", "en": "📥 Mirrors - Fill the base of the active Odoo version", }, "Mirrors - Fill the extra of the active Odoo version": { "fr": "🧩 Miroirs - Remplir l'extra de la version d'Odoo active", "en": "🧩 Mirrors - Fill the extra of the active Odoo version", }, "Mirrors - Fill every manifest, all versions": { "fr": "📚 Miroirs - Remplir tous les manifestes, toutes versions", "en": "📚 Mirrors - Fill every manifest, all versions", }, "Base of Odoo": { "fr": "Base d'Odoo", "en": "Base of Odoo", }, "Extra of Odoo": { "fr": "Extra d'Odoo", "en": "Extra of Odoo", }, "Every manifest, all versions": { "fr": "Tous les manifestes, toutes versions", "en": "Every manifest, all versions", }, "repositories declared": { "fr": "dépôts déclarés", "en": "repositories declared", }, "without a mirror": { "fr": "sans miroir", "en": "without a mirror", }, "No .odoo-version: no active version to fill.": { "fr": "Aucun .odoo-version : pas de version active à remplir.", "en": "No .odoo-version: no active version to fill.", }, "Nothing declared for this version.": { "fr": "Rien n'est déclaré pour cette version.", "en": "Nothing declared for this version.", }, "Extra modules install only with --with_extra.": { "fr": "Les modules extra ne s'installent qu'avec --with_extra.", "en": "Extra modules install only with --with_extra.", }, "Mirrors - List them, heaviest first": { "fr": "📋 Miroirs - Les lister, du plus lourd au plus léger", "en": "📋 Mirrors - List them, heaviest first", }, "Mirrors - Remove one": { "fr": "🧹 Miroirs - En effacer un", "en": "🧹 Mirrors - Remove one", }, "Repository to remove (as listed)": { "fr": "Dépôt à effacer (tel qu'affiché)", "en": "Repository to remove (as listed)", }, "It will be mirrored again when a VM needs it.": { "fr": "Il sera remis en miroir dès qu'une VM en aura besoin.", "en": "It will be mirrored again when a VM needs it.", }, "Remove this mirror?": { "fr": "Effacer ce miroir ?", "en": "Remove this mirror?", }, " weighs, history included, and a few repositories make": { "fr": " historique compris, et quelques dépôts font l'essentiel du", "en": " weighs, history included, and a few repositories make", }, " most of the total. Entry 5 lists them heaviest first and": { "fr": " total. L'entrée 5 les liste du plus lourd au plus léger et en", "en": " most of the total. Entry 5 lists them heaviest first and", }, " removes one — it comes back at the next need.": { "fr": " efface un — il revient au prochain besoin.", "en": " removes one — it comes back at the next need.", }, " and served locally. A mirror already held serves with no": { "fr": " place, et servi localement. Un miroir déjà détenu sert sans", "en": " and served locally. A mirror already held serves with no", }, " network at all — but NOT what the cache may not decrypt:": { "fr": " aucun réseau — mais PAS ce que le cache n'a pas le droit de", "en": " network at all — but NOT what the cache may not decrypt:", }, " npm and poetry carry their own trust store, so they are": { "fr": " déchiffrer : npm et poetry portent leur propre magasin, passent", "en": " npm and poetry carry their own trust store, so they are", }, " tunnelled, and a tunnel carries nothing once cut.": { "fr": " en tunnel, et un tunnel ne porte rien une fois coupé.", "en": " tunnelled, and a tunnel carries nothing once cut.", }, "Cache - Age and cleanup": { "fr": "🧭 Cache - Âge et nettoyage", "en": "🧭 Cache - Age and cleanup", }, "Age of the cache, and cleanup": { "fr": "Âge du cache, et nettoyage", "en": "Age of the cache, and cleanup", }, "Age - By day": { "fr": "📅 Âge - Par jour", "en": "📅 Age - By day", }, "Age - By week": { "fr": "🗓 Âge - Par semaine", "en": "🗓 Age - By week", }, "Age - By month": { "fr": "📆 Âge - Par mois", "en": "📆 Age - By month", }, "Clean - What has not served for a while": { "fr": "🧹 Nettoyer - Ce qui n'a plus servi depuis un temps", "en": "🧹 Clean - What has not served for a while", }, "Clean - Everything": { "fr": "🔥 Nettoyer - Tout", "en": "🔥 Clean - Everything", }, "Not served since (e.g. 30j, 12h)": { "fr": "Plus servi depuis (ex. 30j, 12h)", "en": "Not served since (e.g. 30j, 12h)", }, "Erase what is listed above?": { "fr": "Effacer ce qui est listé ci-dessus ?", "en": "Erase what is listed above?", }, "This empties the objects AND the git mirrors.": { "fr": "Cela vide les objets ET les miroirs git.", "en": "This empties the objects AND the git mirrors.", }, "Refilling the mirrors takes minutes to hours.": { "fr": "Remplir de nouveau les miroirs prend des minutes à des heures.", "en": "Refilling the mirrors takes minutes to hours.", }, "Erase the whole cache?": { "fr": "Effacer tout le cache ?", "en": "Erase the whole cache?", }, " Entry 6 groups them by AGE OF LAST USE — an object served": { "fr": " L'entrée 6 les groupe par ÂGE DU DERNIER USAGE — un objet servi", "en": " Entry 6 groups them by AGE OF LAST USE — an object served", }, " has its date renewed, so « old » means « no longer used »": { "fr": " voit sa date remise à jour, « vieux » veut donc dire « n'a plus", "en": " has its date renewed, so « old » means « no longer used »", }, " — and gives back what has not served for a while, or all.": { "fr": " servi » — et rend ce qui ne sert plus, ou tout.", "en": " — and gives back what has not served for a while, or all.", }, "What each VM pulled:": { "fr": "Ce que chaque VM a tiré :", "en": "What each VM pulled:", }, "from disk": { "fr": "du disque", "en": "from disk", }, "upstream": { "fr": "de l'amont", "en": "upstream", }, "Cache - Guide: how it works": { "fr": "📖 Cache - Guide : comment il fonctionne", "en": "📖 Cache - Guide: how it works", }, "Cache - Tests and performance report": { "fr": "🧪 Cache - Tests et rapport de performance", "en": "🧪 Cache - Tests and performance report", }, "Diagnosis of the QEMU download cache": { "fr": "Diagnostic du cache de téléchargement QEMU", "en": "Diagnosis of the QEMU download cache", }, "Service:": {"fr": "Service :", "en": "Service:"}, "Service is running": {"fr": "actif", "en": "running"}, "Service is stopped": {"fr": "arrêté", "en": "stopped"}, "Not installed:": {"fr": "Non installé :", "en": "Not installed:"}, "Install it from entry 1 of this menu.": { "fr": "L'installer depuis l'entrée 1 de ce menu.", "en": "Install it from entry 1 of this menu.", }, "Redirection:": {"fr": "Détournement :", "en": "Redirection:"}, "the cache": {"fr": "le cache", "en": "the cache"}, "No redirection rule is posted": { "fr": "Aucune règle de détournement n'est posée", "en": "No redirection rule is posted", }, "Cannot tell where the rules point: reading nft needs a sudo password here.": { "fr": "Impossible de savoir où pointent les règles : lire nft exige un mot de passe sudo ici.", "en": "Cannot tell where the rules point: reading nft needs a sudo password here.", }, "MISMATCH — rules on": { "fr": "DÉSACCORD — règles sur", "en": "MISMATCH — rules on", }, "libvirt serves": {"fr": "libvirt sert", "en": "libvirt serves"}, "Reinstall: the cache reads libvirt by itself.": { "fr": "Réinstaller : le cache lit libvirt tout seul.", "en": "Reinstall: the cache reads libvirt by itself.", }, "Authority:": {"fr": "Autorité :", "en": "Authority:"}, "What the cache has done:": { "fr": "Ce que le cache a fait :", "en": "What the cache has done:", }, "The access log is empty: nothing has gone through the cache.": { "fr": "Le journal d'accès est vide : rien n'a traversé le cache.", "en": "The access log is empty: nothing has gone through the cache.", }, "A VM that installs while this stays at zero does not use it.": { "fr": "Une VM qui installe pendant que cela reste à zéro ne l'utilise pas.", "en": "A VM that installs while this stays at zero does not use it.", }, "How the QEMU download cache works": { "fr": "Comment fonctionne le cache de téléchargement QEMU", "en": "How the QEMU download cache works", }, " Two VMs of the same distribution pull the same packages.": { "fr": " Deux VM de la même distribution tirent les mêmes paquets.", "en": " Two VMs of the same distribution pull the same packages.", }, " The cache keeps what comes down and serves the copy to the next.": { "fr": " Le cache garde ce qui descend et sert la copie à la suivante.", "en": " The cache keeps what comes down and serves the copy to the next.", }, "What is served from disk": { "fr": "Ce qui est servi du disque", "en": "What is served from disk", }, " A package file: its name carries its version, so it never changes.": { "fr": " Un fichier de paquet : son nom porte sa version, il ne change jamais.", "en": " A package file: its name carries its version, so it never changes.", }, " The host name is ignored: a rotating mirror list still hits.": { "fr": " Le nom d'hôte est ignoré : une liste de miroirs qui tourne sert quand même.", "en": " The host name is ignored: a rotating mirror list still hits.", }, "What is always taken from upstream": { "fr": "Ce qui est toujours repris à l'amont", "en": "What is always taken from upstream", }, " A repository index: it names the versions that exist right now.": { "fr": " Un index de dépôt : il nomme les versions qui existent en ce moment.", "en": " A repository index: it names the versions that exist right now.", }, " Serving a stale one makes an install fail on a withdrawn package.": { "fr": " En servir un périmé fait échouer une installation sur un paquet retiré.", "en": " Serving a stale one makes an install fail on a withdrawn package.", }, " It is stored anyway, and only comes back out when upstream is mute.": { "fr": " Il est stocké quand même, et ne ressort que si l'amont est muet.", "en": " It is stored anyway, and only comes back out when upstream is mute.", }, "Where things live": { "fr": "Où vivent les choses", "en": "Where things live", }, "Objects:": {"fr": "Objets :", "en": "Objects:"}, "Settings:": {"fr": "Réglages :", "en": "Settings:"}, "Access log:": {"fr": "Journal d'accès :", "en": "Access log:"}, "No eviction is written": { "fr": "Aucune éviction n'est écrite", "en": "No eviction is written", }, " This cache never shrinks by itself, and it lives on the": { "fr": " Ce cache ne diminue jamais de lui-même, et il vit sur le", "en": " This cache never shrinks by itself, and it lives on the", }, " orchestrator's disk. Watch it with the diagnosis entry.": { "fr": " disque de l'orchestrateur. Le surveiller par le diagnostic.", "en": " orchestrator's disk. Watch it with the diagnosis entry.", }, "Turning it off": {"fr": "Le désactiver", "en": "Turning it off"}, " Interception is transparent and covers the whole bridge: a VM": { "fr": " L'interception est transparente et couvre tout le pont : une VM", "en": " Interception is transparent and covers the whole bridge: a VM", }, " cannot opt out of it. Omitting the authority does not bypass": { "fr": " ne peut pas s'y soustraire. Omettre l'autorité ne contourne pas", "en": " cannot opt out of it. Omitting the authority does not bypass", }, " the cache — the VM is redirected all the same, and fails on": { "fr": " le cache — la VM est détournée quand même, et échoue sur", "en": " the cache — the VM is redirected all the same, and fails on", }, " « self-signed certificate in certificate chain ».": { "fr": " « self-signed certificate in certificate chain ».", "en": " « self-signed certificate in certificate chain ».", }, " The only true bypass stops the service:": { "fr": " Le seul contournement vrai arrête le service :", "en": " The only true bypass stops the service:", }, " The rules leave with it, so no VM stays redirected.": { "fr": " Les règles partent avec lui : aucune VM ne reste détournée.", "en": " The rules leave with it, so no VM stays redirected.", }, "Proxmox": {"fr": "Proxmox", "en": "Proxmox"}, " A Proxmox host that is itself a VM of this orchestrator crosses": { "fr": " Un hôte Proxmox qui est lui-même une VM d'ici traverse ce pont :", "en": " A Proxmox host that is itself a VM of this orchestrator crosses", }, " this bridge: the machines it carries come out behind its address,": { "fr": " les machines qu'il porte sortent derrière son adresse, le cache", "en": " this bridge: the machines it carries come out behind its address,", }, " so the cache serves them, and the deployment poses the authority": { "fr": " les sert donc, et le déploiement pose l'autorité dans chacune.", "en": " so the cache serves them, and the deployment poses the authority", }, " in each of them. A host that lives elsewhere is not concerned —": { "fr": " Un hôte qui vit ailleurs n'est pas concerné — y installer le", "en": " in each of them. A host that lives elsewhere is not concerned —", }, " install the cache ON it, the script being generic and Proxmox a": { "fr": " cache, le script étant générique et Proxmox un Debian. Réserve :", "en": " install the cache ON it, the script being generic and Proxmox a", }, " Debian. Reserve: a bridge switched onto the LAN is only seen by": { "fr": " un pont basculé sur le LAN n'est vu par les règles que si", "en": " Debian. Reserve: a bridge switched onto the LAN is only seen by", }, " the rules when br_netfilter is enabled.": { "fr": " br_netfilter est activé.", "en": " the rules when br_netfilter is enabled.", }, "Cache tests: real VMs, several minutes": { "fr": "Tests du cache : de vraies VM, quelques minutes", "en": "Cache tests: real VMs, several minutes", }, "Test - The plan only (dry-run)": { "fr": "📋 Test - Le plan seul (à blanc)", "en": "📋 Test - The plan only (dry-run)", }, "Test - Two VMs, measure the gain": { "fr": "📊 Test - Deux VM, mesurer le gain", "en": "📊 Test - Two VMs, measure the gain", }, "Test - Add the offline counter-proof": { "fr": "🔌 Test - Ajouter la contre-épreuve hors ligne", "en": "🔌 Test - Add the offline counter-proof", }, "Test - Control run: two VMs WITHOUT the cache": { "fr": "⚖ Test - Témoin : deux VM SANS le cache", "en": "⚖ Test - Control run: two VMs WITHOUT the cache", }, "Test - Performance report": { "fr": "📈 Test - Rapport de performance", "en": "📈 Test - Performance report", }, "Test - Undo the machines created": { "fr": "🧹 Test - Défaire les machines créées", "en": "🧹 Test - Undo the machines created", }, "The control run measures what NOT caching costs.": { "fr": "Le témoin mesure ce que coûte l'ABSENCE de cache.", "en": "The control run measures what NOT caching costs.", }, "This creates real VMs and takes a while.": { "fr": "Cela crée de vraies VM et prend du temps.", "en": "This creates real VMs and takes a while.", }, "Run this long test?": { "fr": "Lancer ce test long ?", "en": "Run this long test?", }, "Install the download cache shared by the QEMU VMs of this host": { "fr": "Installer le cache de téléchargement partagé par les VM QEMU de cet hôte", "en": "Install the download cache shared by the QEMU VMs of this host", }, "HTTP port of the cache (default: 8898): ": { "fr": "Port HTTP du cache (défaut : 8898) : ", "en": "HTTP port of the cache (default: 8898): ", }, "TLS port of the cache (default: 8899): ": { "fr": "Port TLS du cache (défaut : 8899) : ", "en": "TLS port of the cache (default: 8899): ", }, "Cache directory (default: /var/cache/erplibre_go_qemu_cache): ": { "fr": "Répertoire du cache (défaut : /var/cache/erplibre_go_qemu_cache) : ", "en": "Cache directory (default: /var/cache/erplibre_go_qemu_cache): ", }, "Will write network rules on the host bridge:": { "fr": "Va écrire des règles réseau sur le pont de l'hôte :", "en": "Will write network rules on the host bridge:", }, "Only what leaves the VM subnet is redirected": { "fr": "Seul ce qui sort du sous-réseau des VM est détourné", "en": "Only what leaves the VM subnet is redirected", }, "The rules exist only while the service runs": { "fr": "Les règles n'existent que pendant que le service tourne", "en": "The rules exist only while the service runs", }, "Go is absent; the installer lays it down": { "fr": "Go est absent ; l'installateur le pose", "en": "Go is absent; the installer lays it down", }, "Install the QEMU download cache?": { "fr": "Installer le cache de téléchargement QEMU ?", "en": "Install the QEMU download cache?", }, "Installing the QEMU download cache (requires sudo)...": { "fr": "Installation du cache de téléchargement QEMU (sudo requis)...", "en": "Installing the QEMU download cache (requires sudo)...", }, "QEMU download cache installed and started": { "fr": "Cache de téléchargement QEMU installé et démarré", "en": "QEMU download cache installed and started", }, "Certificate authority a VM must trust: ": { "fr": "Autorité de certification qu'une VM doit approuver : ", "en": "Certificate authority a VM must trust: ", }, "The cache install failed, nothing is started": { "fr": "L'installation du cache a échoué, rien n'est démarré", "en": "The cache install failed, nothing is started", }, "QEMU cache install script not found: ": { "fr": "Script d'installation du cache QEMU introuvable : ", "en": "QEMU cache install script not found: ", }, "No eviction is written: this cache never shrinks by itself": { "fr": "Aucune éviction n'est écrite : ce cache ne diminue jamais de lui-même", "en": "No eviction is written: this cache never shrinks by itself", }, "Download cache: plan only (dry-run)": { "fr": "📦 Cache de téléchargement : le plan seul (à blanc)", "en": "📦 Download cache: plan only (dry-run)", }, "Download cache: two VMs, measure": { "fr": "📦 Cache de téléchargement : deux VM, et la mesure", "en": "📦 Download cache: two VMs, measure", }, "Download cache: measure, then cut the upstream": { "fr": "📦 Cache de téléchargement : mesurer, puis couper l'amont", "en": "📦 Download cache: measure, then cut the upstream", }, # QEMU / KVM (libvirt) VM deployment "QEMU/KVM - Deploy an Ubuntu VM (libvirt)": { "fr": "💻 QEMU/KVM - Déployer une VM Ubuntu (libvirt)", "en": "💻 QEMU/KVM - Deploy an Ubuntu VM (libvirt)", }, "Deploy a QEMU/KVM virtual machine (libvirt)!": { "fr": "Déployer une machine virtuelle QEMU/KVM (libvirt) !", "en": "Deploy a QEMU/KVM virtual machine (libvirt)!", }, "QEMU deploy script not found: ": { "fr": "Script de déploiement QEMU introuvable : ", "en": "QEMU deploy script not found: ", }, "Deploy a new VM": { "fr": "Déployer une nouvelle VM", "en": "Deploy a new VM", }, "Preview a deployment (dry-run, no sudo)": { "fr": "🔍 Prévisualiser un déploiement (dry-run, sans sudo)", "en": "🔍 Preview a deployment (dry-run, no sudo)", }, "Download a cloud image only": { "fr": "⬇ Télécharger seulement une image cloud", "en": "⬇ Download a cloud image only", }, "List VMs (virsh list --all)": { "fr": "📋 Lister les VM (virsh list --all)", "en": "📋 List VMs (virsh list --all)", }, "Show a VM IP address": { "fr": "🌐 Afficher l'adresse IP d'une VM", "en": "🌐 Show a VM IP address", }, "List available images and specs": { "fr": "🗂 Lister les images disponibles et leurs specs", "en": "🗂 List available images and specs", }, "Distribution:": { "fr": "Distribution :", "en": "Distribution:", }, "Choice (number or name, default: ubuntu): ": { "fr": "Choix (numéro ou nom, défaut : ubuntu) : ", "en": "Choice (number or name, default: ubuntu): ", }, "Invalid selection, using ubuntu": { "fr": "Sélection invalide, utilisation d'ubuntu", "en": "Invalid selection, using ubuntu", }, "Version for": { "fr": "Version des", "en": "Version for", }, "Versions for": { "fr": "Versions des", "en": "Versions of", }, "Architecture:": { "fr": "Architecture :", "en": "Architecture:", }, "native": { "fr": "native", "en": "native", }, "IBM Z — emulated, slow on x86; Ubuntu only": { "fr": "IBM Z — émulé, lent sur x86 ; Ubuntu uniquement", "en": "IBM Z — emulated, slow on x86; Ubuntu only", }, "IBM Z — emulated, slow; Ubuntu only": { "fr": "IBM Z — émulé, lent ; Ubuntu uniquement", "en": "IBM Z — emulated, slow; Ubuntu only", }, "ARM 64-bit — emulated, slow": { "fr": "ARM 64 bits — émulé, lent", "en": "ARM 64-bit — emulated, slow", }, "emulated, slow": { "fr": "émulé, lent", "en": "emulated, slow", }, "This architecture is emulated (TCG): boot and install are" " much slower than the native one.": { "fr": "Cette architecture est émulée (TCG) : le boot et l'installation" " sont bien plus lents que l'architecture native.", "en": "This architecture is emulated (TCG): boot and install are" " much slower than the native one.", }, "images for this arch only exist for:": { "fr": "images pour cette architecture disponibles seulement pour :", "en": "images for this arch only exist for:", }, "All supported architectures": { "fr": "Toutes les architectures supportées", "en": "All supported architectures", }, "installation": { "fr": "installation", "en": "installation", }, "Resources per VM (x1 = catalog minimum):": { "fr": "Ressources par VM (x1 = minimum catalogue) :", "en": "Resources per VM (x1 = catalog minimum):", }, "Host:": { "fr": "Hôte :", "en": "Host:", }, "free": { "fr": "libres", "en": "free", }, "free RAM unknown": { "fr": "RAM libre inconnue", "en": "free RAM unknown", }, "> host free RAM": { "fr": "> RAM libre de l'hôte", "en": "> host free RAM", }, "> host free disk": { "fr": "> disque libre de l'hôte", "en": "> host free disk", }, "free of": { "fr": "libres sur", "en": "free of", }, "total RAM": { "fr": "RAM totale", "en": "total RAM", }, "Choice (1-4, default 1):": { "fr": "Choix (1-4, défaut 1) :", "en": "Choice (1-4, default 1):", }, "Choice (1-5, default 1):": { "fr": "Choix (1-5, défaut 1) :", "en": "Choice (1-5, default 1):", }, "Custom - set vCPU, RAM and disk": { "fr": "Personnalisé — choisir vCPU, RAM et disque", "en": "Custom — set vCPU, RAM and disk", }, "custom": { "fr": "personnalisé", "en": "custom", }, "varies": { "fr": "varié", "en": "varies", }, "vCPU per VM, blank = keep": { "fr": "vCPU par VM, vide = garder", "en": "vCPU per VM, blank = keep", }, "New vCPU count, blank = keep": { "fr": "Nouveau nombre de vCPU, vide = garder", "en": "New vCPU count, blank = keep", }, "Invalid vCPU count.": { "fr": "Nombre de vCPU invalide.", "en": "Invalid vCPU count.", }, "More vCPU than host cores": { "fr": "Plus de vCPU que de cœurs sur l'hôte", "en": "More vCPU than host cores", }, "> host cores": { "fr": "> cœurs de l'hôte", "en": "> host cores", }, "Total vCPU (all running):": { "fr": "vCPU total (toutes démarrées) :", "en": "Total vCPU (all running):", }, "Deploy VM(s) (one or many)": { "fr": "🚀 Déployer une ou plusieurs VM", "en": "🚀 Deploy VM(s) (one or many)", }, "Deploy ERPLibre VM(s)!": { "fr": "Déployer une ou plusieurs VM ERPLibre !", "en": "Deploy ERPLibre VM(s)!", }, "VM names (default = auto):": { "fr": "Noms des VM (défaut = auto) :", "en": "VM names (default = auto):", }, "Rename which VMs? (numbers, comma-separated; blank = none): ": { "fr": "Renommer quelles VM ? (numéros séparés par des virgules ; " "vide = aucune) : ", "en": "Rename which VMs? (numbers, comma-separated; blank = none): ", }, "->": { "fr": "->", "en": "->", }, "VMs (default = no change):": { "fr": "VM (défaut = aucune modification) :", "en": "VMs (default = no change):", }, "Modify which VMs? (numbers, comma-separated; blank = none): ": { "fr": "Modifier quelles VM ? (numéros séparés par des virgules ; " "vide = aucune) : ", "en": "Modify which VMs? (numbers, comma-separated; blank = none): ", }, "new name (blank = keep):": { "fr": "nouveau nom (vide = garder) :", "en": "new name (blank = keep):", }, "New disk size in G, blank = keep": { "fr": "Nouvelle taille disque en G, vide = garder", "en": "New disk size in G, blank = keep", }, "New RAM in MB, blank = keep": { "fr": "Nouvelle RAM en Mo, vide = garder", "en": "New RAM in MB, blank = keep", }, "Duplicate names detected; keeping as entered.": { "fr": "Noms en double détectés ; conservés tels quels.", "en": "Duplicate names detected; keeping as entered.", }, "Preview (dry-run):": { "fr": "Aperçu (dry-run) :", "en": "Preview (dry-run):", }, "(includes emulated architectures — some VMs are slow)": { "fr": "(inclut des architectures émulées — certaines VM sont lentes)", "en": "(includes emulated architectures — some VMs are slow)", }, "install monitoring": { "fr": "suivi d'installation", "en": "install monitoring", }, "Navigation telemetry (TUI)": { "fr": "📊 Télémétrie de navigation (TUI)", "en": "📊 Navigation telemetry (TUI)", }, "Configuration": { "fr": "🔩 Configuration", "en": "🔩 Configuration", }, "Interface": { "fr": "Interface", "en": "Interface", }, "Language / Langue": { "fr": "🌐 Langue / Language", "en": "🌐 Language / Langue", }, "QEMU deployment interface": { "fr": "🖥 Interface de déploiement QEMU", "en": "🖥 QEMU deployment interface", }, "Display while deploying": { "fr": "📜 Affichage pendant le déploiement", "en": "📜 Display while deploying", }, "Ask every time": { "fr": "Demander à chaque fois", "en": "Ask every time", }, "TUI form": { "fr": "📋 Formulaire TUI", "en": "📋 TUI form", }, "Classic questions (line by line)": { "fr": "💬 Questions classiques (ligne par ligne)", "en": "💬 Classic questions (line by line)", }, "CLI output (easy to copy)": { "fr": "Sortie CLI (facile à copier)", "en": "CLI output (easy to copy)", }, "TUI, collapsible blocks per VM": { "fr": "TUI, blocs repliables par VM", "en": "TUI, collapsible blocks per VM", }, "Choice (number, blank = keep):": { "fr": "Choix (numéro, vide = garder) :", "en": "Choice (number, blank = keep):", }, "SSH port forwarding (open Odoo in the browser)": { "fr": "🔌 Redirection de port SSH (ouvrir Odoo dans le navigateur)", "en": "🔌 SSH port forwarding (open Odoo in the browser)", }, "SSH port forwarding": { "fr": "Redirection de port SSH", "en": "SSH port forwarding", }, "Host (number or name):": { "fr": "Hôte (numéro ou nom) :", "en": "Host (number or name):", }, "Remote port (default:": { "fr": "Port distant (défaut :", "en": "Remote port (default:", }, "Local port (default:": { "fr": "Port local (défaut :", "en": "Local port (default:", }, "virsh is missing: libvirt is not installed here.": { "fr": "virsh est absent : libvirt n'est pas installé ici.", "en": "virsh is missing: libvirt is not installed here.", }, "Every VM command will fail until it is.": { "fr": "Toutes les commandes VM échoueront tant que ce sera le cas.", "en": "Every VM command will fail until it is.", }, "Install the QEMU/libvirt tools now? (Y/n): ": { "fr": "Installer les outils QEMU/libvirt maintenant ? " "(O/n, défaut : oui) : ", "en": "Install the QEMU/libvirt tools now? (Y/n, default: yes): ", }, "libvirt is available.": { "fr": "libvirt est disponible.", "en": "libvirt is available.", }, "virsh still missing; a reboot may be required.": { "fr": "virsh toujours absent ; un redémarrage est peut-être requis.", "en": "virsh still missing; a reboot may be required.", }, "No SSH public key found in ~/.ssh.": { "fr": "Aucune clé publique SSH trouvée dans ~/.ssh.", "en": "No SSH public key found in ~/.ssh.", }, "Without one the VMs start with no SSH access.": { "fr": "Sans elle, les VM démarrent sans accès SSH.", "en": "Without one the VMs start with no SSH access.", }, "Generate one now? (Y/n): ": { "fr": "En générer une maintenant ? (O/n, défaut : oui) : ", "en": "Generate one now? (Y/n, default: yes): ", }, "Checking the remote port...": { "fr": "Vérification du port distant...", "en": "Checking the remote port...", }, "Nothing is listening on port": { "fr": "Rien n'écoute sur le port", "en": "Nothing is listening on port", }, "of": { "fr": "de", "en": "of", }, "Start the service there, or continue anyway.": { "fr": "Démarrer le service là-bas, ou continuer quand même.", "en": "Start the service there, or continue anyway.", }, "Continue anyway? (y/N): ": { "fr": "Continuer quand même ? (o/N, défaut : non) : ", "en": "Continue anyway? (y/N, default: no): ", }, "Could not probe the remote port; going on.": { "fr": "Impossible de sonder le port distant ; on continue.", "en": "Could not probe the remote port; going on.", }, "Local port already in use:": { "fr": "Port local déjà occupé :", "en": "Local port already in use:", }, "Try anyway? (y/N): ": { "fr": "Essayer quand même ? (o/N, défaut : non) : ", "en": "Try anyway? (y/N, default: no): ", }, "Local port differs from the remote one.": { "fr": "Le port local diffère du port distant.", "en": "Local port differs from the remote one.", }, "Odoo redirects using web.base.url; check it": { "fr": "Odoo redirige d'après web.base.url ; vérifier qu'il", "en": "Odoo redirects using web.base.url; check it", }, "matches http://localhost:": { "fr": "vaut bien http://localhost:", "en": "matches http://localhost:", }, "Ctrl+C closes the tunnel.": { "fr": "Ctrl+C referme le tunnel.", "en": "Ctrl+C closes the tunnel.", }, "Tunnel closed.": { "fr": "Tunnel refermé.", "en": "Tunnel closed.", }, "SSH configuration (~/.ssh/config, ProxyJump)": { "fr": "🔑 Configuration SSH (~/.ssh/config, ProxyJump)", "en": "🔑 SSH configuration (~/.ssh/config, ProxyJump)", }, "SSH configuration for QEMU VMs": { "fr": "Configuration SSH des VM QEMU", "en": "SSH configuration for QEMU VMs", }, "Where should the machines come from?": { "fr": "D'où viennent les machines à configurer ?", "en": "Where should the machines come from?", }, "Local QEMU VMs (virsh)": { "fr": "VM QEMU locales (virsh)", "en": "Local QEMU VMs (virsh)", }, "Hosts from ~/.ssh/config": { "fr": "Hôtes de ~/.ssh/config", "en": "Hosts from ~/.ssh/config", }, "Type a host or an IP": { "fr": "Saisir un hôte ou une IP", "en": "Type a host or an IP", }, "~/.ssh/config holds no host.": { "fr": "~/.ssh/config ne contient aucun hôte.", "en": "~/.ssh/config holds no host.", }, "Which hosts? (numbers, comma-separated; blank = all): ": { "fr": "Quels hôtes ? (numéros séparés par des virgules ; " "vide = tous) : ", "en": "Which hosts? (numbers, comma-separated; blank = all): ", }, "Host or IP:": { "fr": "Hôte ou IP :", "en": "Host or IP:", }, "User": { "fr": "Utilisateur", "en": "User", }, "Name for ~/.ssh/config": { "fr": "Nom pour ~/.ssh/config", "en": "Name for ~/.ssh/config", }, "Depth (1 = these machines only, default:": { "fr": "Profondeur (1 = ces machines seulement, défaut :", "en": "Depth (1 = these machines only, default:", }, "Which VMs? (numbers, comma-separated; blank = all): ": { "fr": "Quelles VM ? (numéros séparés par des virgules ; " "vide = toutes) : ", "en": "Which VMs? (numbers, comma-separated; blank = all): ", }, "Depth (default:": { "fr": "Profondeur (défaut :", "en": "Depth (default:", }, "entry": { "fr": "entrée", "en": "entry", }, "written": { "fr": "écrite(s)", "en": "written", }, "skipped": { "fr": "ignorée(s)", "en": "skipped", }, "Level": { "fr": "Niveau", "en": "Level", }, "machines to probe": { "fr": "machines à sonder", "en": "machines to probe", }, "SSH refused the identity.": { "fr": "SSH a refusé l'identité.", "en": "SSH refused the identity.", }, "Existing key:": { "fr": "Clé existante :", "en": "Existing key:", }, "Deploy it on this host (ssh-copy-id)? (Y/n): ": { "fr": "La déployer sur cet hôte (ssh-copy-id) ? " "(O/n, défaut : oui) : ", "en": "Deploy it on this host (ssh-copy-id)? (Y/n, default: yes): ", }, "No SSH key in ~/.ssh.": { "fr": "Aucune clé SSH dans ~/.ssh.", "en": "No SSH key in ~/.ssh.", }, "Create one and deploy it? (Y/n): ": { "fr": "En créer une et la déployer ? (O/n, défaut : oui) : ", "en": "Create one and deploy it? (Y/n, default: yes): ", }, "access refused": { "fr": "accès refusé", "en": "access refused", }, "timed out": { "fr": "délai dépassé", "en": "timed out", }, "unreachable": { "fr": "injoignable", "en": "unreachable", }, "no QEMU/libvirt here": { "fr": "pas de QEMU/libvirt ici", "en": "no QEMU/libvirt here", }, "virsh present but not accessible": { "fr": "virsh présent mais inaccessible (droits)", "en": "virsh present but not accessible (permissions)", }, "Add the user to the libvirt group there:": { "fr": "Ajoutez l'utilisateur au groupe libvirt là-bas :", "en": "Add the user to the libvirt group there:", }, "QEMU present, no VM": { "fr": "QEMU présent, aucune VM", "en": "QEMU present, no VM", }, "Create the SSH key if missing and deploy it? (Y/n): ": { "fr": "Créer la clé SSH si absente et la déployer ? " "(O/n, défaut : oui) : ", "en": "Create the SSH key if missing and deploy it? " "(Y/n, default: yes): ", }, "Generating an ed25519 SSH key": { "fr": "Génération d'une clé SSH ed25519", "en": "Generating an ed25519 SSH key", }, "Cannot generate the key": { "fr": "Impossible de générer la clé", "en": "Cannot generate the key", }, "Deploying the key on": { "fr": "Déploiement de la clé sur", "en": "Deploying the key on", }, "host": { "fr": "hôte", "en": "host", }, "key already accepted": { "fr": "clé déjà acceptée", "en": "key already accepted", }, "deployed": { "fr": "déployée(s)", "en": "deployed", }, "already there": { "fr": "déjà en place", "en": "already there", }, "virt-manager detected": { "fr": "virt-manager détecté", "en": "virt-manager detected", }, "virt-manager: every connection already there": { "fr": "virt-manager : toutes les connexions sont déjà là", "en": "virt-manager: every connection already there", }, "Add the missing connections to virt-manager? (Y/n): ": { "fr": "Ajouter les connexions manquantes à virt-manager ? " "(O/n, défaut : oui) : ", "en": "Add the missing connections to virt-manager? " "(Y/n, default: yes): ", }, "Restart virt-manager to see the new connections": { "fr": "Redémarrer virt-manager pour voir les nouvelles connexions", "en": "Restart virt-manager to see the new connections", }, "the names apply live": { "fr": "les noms s'appliquent à chaud", "en": "the names apply live", }, "SSH hosts written": { "fr": "Hôtes SSH écrits", "en": "SSH hosts written", }, "via": { "fr": "via", "en": "via", }, "Odoo migration interface": { "fr": "🚚 Interface de la migration Odoo", "en": "🚚 Odoo migration interface", }, "modules of the list have no code in the active Odoo:": { "fr": "modules de la liste n'ont plus de code dans l'Odoo actif :", "en": "modules of the list have no code in the active Odoo:", }, "Odoo cannot uninstall a module whose code is gone;": { "fr": "Odoo ne peut pas désinstaller un module dont le code a" " disparu ;", "en": "Odoo cannot uninstall a module whose code is gone;", }, "one of them fails the whole uninstall command.": { "fr": "un seul d'entre eux fait échouer toute la désinstallation.", "en": "one of them fails the whole uninstall command.", }, "are present and can be uninstalled:": { "fr": "sont présents et peuvent être désinstallés :", "en": "are present and can be uninstalled:", }, "No module of the list is present.": { "fr": "Aucun module de la liste n'est présent.", "en": "No module of the list is present.", }, "Uninstall the present ones, skip the missing": { "fr": "Désinstaller les présents, ignorer les manquants", "en": "Uninstall the present ones, skip the missing", }, "Try the whole list anyway (it will fail)": { "fr": "Tout tenter quand même (ça échouera)", "en": "Try the whole list anyway (it will fail)", }, "Uninstall nothing, continue": { "fr": "Ne rien désinstaller, continuer", "en": "Uninstall nothing, continue", }, "Nothing uninstalled.": { "fr": "Rien de désinstallé.", "en": "Nothing uninstalled.", }, "Retrying alone:": { "fr": "Reprise seul :", "en": "Retrying alone:", }, "The uninstall did not take:": { "fr": "La désinstallation n'a pas pris :", "en": "The uninstall did not take:", }, "Odoo exits 0 even when it removes nothing.": { "fr": "Odoo sort en 0 même quand il ne retire rien.", "en": "Odoo exits 0 even when it removes nothing.", }, "Could not verify the uninstall.": { "fr": "Impossible de vérifier la désinstallation.", "en": "Could not verify the uninstall.", }, "Check the COW views that drifted": { "fr": "Vérifier les vues COW en retard sur leur vue module", "en": "Check the COW views that drifted", }, "Tool not found": { "fr": "Outil introuvable", "en": "Tool not found", }, "To reset one of them onto its module view:": { "fr": "Pour réinitialiser l'une d'elles sur sa vue module :", "en": "To reset one of them onto its module view:", }, "Read the diff first: a copy can hold a customisation.": { "fr": "Lire le diff d'abord : une copie peut porter une" " personnalisation.", "en": "Read the diff first: a copy can hold a customisation.", }, "Migration statistics (read-only)": { "fr": "📊 Statistiques de la migration (lecture seule)", "en": "📊 Migration statistics (read-only)", }, "Choice (0-3, default 1): ": { "fr": "Choix (0-3, défaut 1) : ", "en": "Choice (0-3, default 1): ", }, "Migration statistics": { "fr": "Statistiques de la migration", "en": "Migration statistics", }, "elapsed": { "fr": "écoulé", "en": "elapsed", }, "Level reached": { "fr": "Niveau atteint", "en": "Level reached", }, "Modules": { "fr": "Modules", "en": "Modules", }, "modules": { "fr": "modules", "en": "modules", }, "At the start": { "fr": "Au départ", "en": "At the start", }, "Removed in total": { "fr": "Supprimés au total", "en": "Removed in total", }, "Reported missing": { "fr": "Signalés manquants", "en": "Reported missing", }, "Duplicated": { "fr": "En double", "en": "Duplicated", }, "Migration fixes": { "fr": "Correctifs de migration", "en": "Migration fixes", }, "COW views": { "fr": "Vues COW", "en": "COW views", }, "views": { "fr": "vues", "en": "views", }, "no snapshot": { "fr": "aucun instantané", "en": "no snapshot", }, "Journal": { "fr": "Journal", "en": "Journal", }, "commands": { "fr": "commandes", "en": "commands", }, "recorded decisions": { "fr": "décisions annotées", "en": "recorded decisions", }, "Removed modules, with their reason": { "fr": "Modules supprimés, avec leur justification", "en": "Removed modules, with their reason", }, "Removed modules, comma-separated (copy)": { "fr": "Modules supprimés, séparés par des virgules (à copier)", "en": "Removed modules, comma-separated (copy)", }, "COW views: snapshots and differences": { "fr": "Vues COW : instantanés et différences", "en": "COW views: snapshots and differences", }, "Recorded decisions (journal)": { "fr": "Décisions annotées (journal)", "en": "Recorded decisions (journal)", }, "Executed commands (last 30)": { "fr": "Commandes exécutées (30 dernières)", "en": "Executed commands (last 30)", }, "nothing recorded": { "fr": "rien d'annoté", "en": "nothing recorded", }, "Need two snapshots to diff.": { "fr": "Il faut deux instantanés pour comparer.", "en": "Need two snapshots to diff.", }, "Diff which two? (e.g. 1,2 — blank to skip)": { "fr": "Comparer lesquels ? (ex. 1,2 — vide pour passer)", "en": "Diff which two? (e.g. 1,2 — blank to skip)", }, "No migration in progress to resume.": { "fr": "Aucune migration en cours à reprendre.", "en": "No migration in progress to resume.", }, "Quit without doing anything": { "fr": "Quitter sans rien faire", "en": "Quit without doing anything", }, "Version bumps": { "fr": "Montées de version", "en": "Version bumps", }, "Step": { "fr": "Étape", "en": "Step", }, "Detail": { "fr": "Détail", "en": "Detail", }, "Enter on a step or a version = replay from there": { "fr": "Entrée sur une étape ou une version = rejouer depuis là", "en": "Enter on a step or a version = replay from there", }, "New migration": { "fr": "Nouvelle migration", "en": "New migration", }, "Keep the zip only": { "fr": "Garder seulement le zip", "en": "Keep the zip only", }, "Reset all preferences": { "fr": "🧹 Réinitialiser toutes les préférences", "en": "🧹 Reset all preferences", }, "Preferences reset": { "fr": "Préférences réinitialisées", "en": "Preferences reset", }, "Interface:": { "fr": "Interface :", "en": "Interface:", }, "(change the default in TODO > Configuration)": { "fr": "(changer le défaut dans TODO > Configuration)", "en": "(change the default in TODO > Configuration)", }, "Loading (VM list, branches)...": { "fr": "Chargement (liste des VM, branches)...", "en": "Loading (VM list, branches)...", }, "Architecture": { "fr": "Architecture", "en": "Architecture", }, "Resources per VM": { "fr": "Ressources par VM", "en": "Resources per VM", }, "Install ERPLibre": { "fr": "Installer ERPLibre", "en": "Install ERPLibre", }, "Production (/opt, confined)": { "fr": "Production (/opt, confiné)", "en": "Production (/opt, confined)", }, "Monitoring dashboard": { "fr": "Tableau de bord de suivi", "en": "Monitoring dashboard", }, "Add each VM to ~/.ssh/config": { "fr": "Ajouter chaque VM à ~/.ssh/config", "en": "Add each VM to ~/.ssh/config", }, "Parallelism": { "fr": "Parallélisme", "en": "Parallelism", }, "Name": { "fr": "Nom", "en": "Name", }, "Distro": { "fr": "Distro", "en": "Distro", }, "Version": { "fr": "Version", "en": "Version", }, "Arch": { "fr": "Archi", "en": "Arch", }, "vCPU": { "fr": "vCPU", "en": "vCPU", }, "RAM (MB)": { "fr": "RAM (Mo)", "en": "RAM (MB)", }, "cloud-init still running after 20 min - install starts anyway" " (it waits for cloud-init first)": { "fr": "cloud-init tourne encore apres 20 min - l'installation demarre" " quand meme (elle attend d'abord cloud-init)", "en": "cloud-init still running after 20 min - install starts anyway" " (it waits for cloud-init first)", }, "Waiting for cloud-init to finish (up to 15 min)": { "fr": "Attente de la fin de cloud-init (jusqu'a 15 min)", "en": "Waiting for cloud-init to finish (up to 15 min)", }, "cloud-init:": { "fr": "cloud-init :", "en": "cloud-init:", }, "WARNING libvirt unreachable: the IP will not be refreshed" " (libvirt group? re-login required)": { "fr": "ATTENTION libvirt injoignable : l'IP ne sera pas rafraichie" " (groupe libvirt ? reconnexion necessaire)", "en": "WARNING libvirt unreachable: the IP will not be refreshed" " (libvirt group? re-login required)", }, "DHCP lease moved:": { "fr": "bail DHCP deplace :", "en": "DHCP lease moved:", }, "An install is still running:": { "fr": "Une installation est encore en cours :", "en": "An install is still running:", }, "VM(s) in progress": { "fr": "VM en cours", "en": "VM(s) in progress", }, "Last activity:": { "fr": "Dernière activité il y a :", "en": "Last activity:", }, "Reopen that monitoring": { "fr": "Rouvrir ce suivi", "en": "Reopen that monitoring", }, "Deploy anyway (new run)": { "fr": "Déployer quand même (nouveau run)", "en": "Deploy anyway (new run)", }, "Choice (number, blank = reopen): ": { "fr": "Choix (numéro, vide = rouvrir) : ", "en": "Choice (number, blank = reopen): ", }, "Python interpreter:": { "fr": "Interpreteur Python :", "en": "Python interpreter:", }, "mise (precompiled, faster)": { "fr": "mise (precompile, plus rapide)", "en": "mise (precompiled, faster)", }, "pyenv (compiles from source)": { "fr": "pyenv (compile depuis les sources)", "en": "pyenv (compiles from source)", }, "Choice (number, blank = mise): ": { "fr": "Choix (numero, vide = mise) : ", "en": "Choice (number, blank = mise): ", }, "mise has no binary for:": { "fr": "mise ne publie pas de binaire pour :", "en": "mise has no binary for:", }, "those VMs use pyenv": { "fr": "ces VM utiliseront pyenv", "en": "those VMs use pyenv", }, "Installing mise (precompiled Python)": { "fr": "Installation de mise (Python precompile)", "en": "Installing mise (precompiled Python)", }, "VM type:": { "fr": "Type de VM :", "en": "VM type:", }, "Server (no graphical interface)": { "fr": "Serveur (sans interface graphique)", "en": "Server (no graphical interface)", }, "Graphical (server + GNOME desktop)": { "fr": "Graphique (serveur + bureau GNOME)", "en": "Graphical (server + GNOME desktop)", }, "server": { "fr": "serveur", "en": "server", }, "Graphical (server + desktop):": { "fr": "Graphique (serveur + bureau) :", "en": "Graphical (server + desktop):", }, "Installing the desktop (long):": { "fr": "Installation du bureau (long) :", "en": "Installing the desktop (long):", }, "Choice (number, blank = server): ": { "fr": "Choix (numero, vide = serveur) : ", "en": "Choice (number, blank = server): ", }, "Installing the GNOME desktop (long)": { "fr": "Installation du bureau GNOME (long)", "en": "Installing the GNOME desktop (long)", }, "openSUSE mirror:": { "fr": "miroir openSUSE :", "en": "openSUSE mirror:", }, "Remote desktop:": { "fr": "Bureau distant :", "en": "Remote desktop:", }, "One run per install": { "fr": "une execution par installation", "en": "One run per install", }, "limit to host cores": { "fr": "limiter au nombre de coeurs de l'hote", "en": "limit to host cores", }, "free value…": { "fr": "valeur libre…", "en": "free value…", }, "Disk (e.g. 250G, 1.5T)": { "fr": "Disque (ex. 250G, 1,5T)", "en": "Disk (e.g. 250G, 1.5T)", }, "all archs": { "fr": "toutes", "en": "all", }, "Tick what to deploy": { "fr": "Cocher ce qu'on veut déployer", "en": "Tick what to deploy", }, "F7 main versions · F6 all": { "fr": "F7 versions principales · F6 tout", "en": "F7 main versions · F6 all", }, "exists - skipped": { "fr": "existe — ignorée", "en": "exists - skipped", }, "orphan disk - will FAIL": { "fr": "disque orphelin — ÉCHOUERA", "en": "orphan disk - will FAIL", }, "press F5 again to confirm": { "fr": "F5 à nouveau pour confirmer", "en": "press F5 again to confirm", }, "Deploy": { "fr": "Déployer", "en": "Deploy", }, "Edit VM": { "fr": "Éditer la VM", "en": "Edit VM", }, "Server": { "fr": "Serveur", "en": "Server", }, "VM type (default):": { "fr": "Type de VM (défaut) :", "en": "VM type (default):", }, "These values are the default for every VM;": { "fr": "Ces valeurs sont le défaut de chaque VM ;", "en": "These values are the default for every VM;", }, "adjust any of them per VM on the right.": { "fr": "ajustez-les VM par VM dans la vue de droite.", "en": "adjust any of them per VM on the right.", }, "Application store:": { "fr": "Magasin d'applications :", "en": "Application store:", }, "Application store (graphical Ubuntu VMs):": { "fr": "Magasin d'applications (VM Ubuntu graphiques) :", "en": "Application store (graphical Ubuntu VMs):", }, "deb only (epiphany-browser)": { "fr": "deb uniquement (epiphany-browser)", "en": "deb only (epiphany-browser)", }, "Flatpak tooling, no Flathub": { "fr": "outillage Flatpak, sans Flathub", "en": "Flatpak tooling, no Flathub", }, "snap (Ubuntu default, Firefox)": { "fr": "snap (défaut Ubuntu, Firefox)", "en": "snap (Ubuntu default, Firefox)", }, "snap needs the store; slow under emulation.": { "fr": "snap exige le store ; lent sous émulation.", "en": "snap needs the store; slow under emulation.", }, "No graphical VM on a snap-based distro.": { "fr": "Aucune VM graphique sur une distribution à snap.", "en": "No graphical VM on a snap-based distro.", }, "Resources — applied to ALL VMs": { "fr": "Ressources — appliquées à TOUTES les VM", "en": "Resources — applied to ALL VMs", }, "The profile and these fields change EVERY VM.": { "fr": "Le profil et ces champs changent TOUTES les VM.", "en": "The profile and these fields change EVERY VM.", }, "A VM edited on the right (marked) keeps its own.": { "fr": "Une VM modifiée à droite (marquée ✎) garde les siennes.", "en": "A VM edited on the right (marked) keeps its own.", }, "Rename the VM": { "fr": "Renommer la VM", "en": "Rename the VM", }, "Rename": { "fr": "Renommer", "en": "Rename", }, "Empty = back to the automatic name:": { "fr": "Vide = revenir au nom automatique :", "en": "Empty = back to the automatic name:", }, "Invalid name: letters, digits, hyphens.": { "fr": "Nom invalide : lettres, chiffres et traits d'union.", "en": "Invalid name: letters, digits, hyphens.", }, "default; a VM may differ, see its line": { "fr": "défaut ; une VM peut s'en écarter, voir sa ligne", "en": "default; a VM may differ, see its line", }, "varies, see each line": { "fr": "varie, voir chaque ligne", "en": "varies, see each line", }, "From your workstation:": { "fr": "Depuis votre poste :", "en": "From your workstation:", }, "then point your client at": { "fr": "puis pointez votre client sur", "en": "then point your client at", }, "Remote desktop tunnel (VNC/RDP through SSH)": { "fr": "🖥 Tunnel bureau distant (VNC/RDP par SSH)", "en": "🖥 Remote desktop tunnel (VNC/RDP through SSH)", }, "Remote desktop tunnel": { "fr": "Tunnel vers le bureau distant", "en": "Remote desktop tunnel", }, "Which VM?": {"fr": "Quelle VM ?", "en": "Which VM?"}, "No IP for this VM; is it running?": { "fr": "Pas d'IP pour cette VM ; tourne-t-elle ?", "en": "No IP for this VM; is it running?", }, "Run this on YOUR workstation:": { "fr": "À lancer sur VOTRE poste :", "en": "Run this on YOUR workstation:", }, "Graphical console (virt-viewer, built-in tunnel)": { "fr": "Console graphique (virt-viewer, tunnel intégré)", "en": "Graphical console (virt-viewer, built-in tunnel)", }, "virt-viewer is missing here; installing it.": { "fr": "virt-viewer manque ici ; installation.", "en": "virt-viewer is missing here; installing it.", }, # Là où « aucun gestionnaire » est vrai ET sans issue. "NixOS: nix-shell -p for one shell, or declare it in" " /etc/nixos/configuration.nix": { "fr": ( "NixOS : nix-shell -p le temps d'un shell, ou le" " déclarer dans /etc/nixos/configuration.nix" ), "en": ( "NixOS: nix-shell -p for one shell, or declare it in" " /etc/nixos/configuration.nix" ), }, "no known package manager here.": { "fr": "aucun gestionnaire de paquets connu ici.", "en": "no known package manager here.", }, "virt-viewer still missing after the install.": { "fr": "virt-viewer manque toujours après l'installation.", "en": "virt-viewer still missing after the install.", }, "Opening": {"fr": "Ouverture", "en": "Opening"}, "Window opening on your display": { "fr": "Fenêtre en ouverture sur votre affichage", "en": "Window opening on your display", }, "Log:": {"fr": "Journal :", "en": "Log:"}, "No display here; run this on YOUR workstation:": { "fr": "Aucun affichage ici ; à lancer sur VOTRE poste :", "en": "No display here; run this on YOUR workstation:", }, "~/.ssh/config written anyway (install)": { "fr": "entrée ~/.ssh/config écrite quand même : l'installation passe par le rebond", "en": "~/.ssh/config written anyway: the install needs the jump", }, "Still on the distribution kernel:": { "fr": "Encore sur le noyau de la distribution :", "en": "Still on the distribution kernel:", }, "Reboot the host: no bridge, no NAT until then.": { "fr": "Redémarrer l'hôte : ni pont ni NAT avant cela.", "en": "Reboot the host: no bridge, no NAT until then.", }, "A ~/.ssh/config alias works there too.": { "fr": "Un alias de ~/.ssh/config y fonctionne aussi.", "en": "A ~/.ssh/config alias works there too.", }, "It builds its own tunnel; no ssh -L to keep open.": { "fr": "Il monte son propre tunnel ; aucun ssh -L à tenir ouvert.", "en": "It builds its own tunnel; no ssh -L to keep open.", }, "Missing? Install virt-viewer:": { "fr": "Absent ? Installez virt-viewer :", "en": "Missing? Install virt-viewer:", }, "repo transfer into the app": { "fr": "transfert des dépôts dans l'application", "en": "repo transfer into the app", }, "graphical session started": { "fr": "session graphique démarrée", "en": "graphical session started", }, "graphical session not started; reboot the VM": { "fr": "session graphique non démarrée ; redémarrer la VM", "en": "graphical session not started; reboot the VM", }, "Hypervisor console (QEMU screen, no guest server)": { "fr": "Console de l'hyperviseur (écran QEMU, rien dans l'invitée)", "en": "Hypervisor console (QEMU screen, no guest server)", }, "then point your VNC client at": { "fr": "puis pointez votre client VNC sur", "en": "then point your VNC client at", }, "Target is the hypervisor": { "fr": "La cible est l'hyperviseur", "en": "Target is the hypervisor", }, "not the VM: the socket is QEMU-side.": { "fr": "et non la VM : le socket est du côté de QEMU.", "en": "not the VM: the socket is QEMU-side.", }, "This hypervisor is Proxmox VE: it has no libvirt.": { "fr": "Cet hyperviseur est un Proxmox VE : il n'a pas de libvirt.", "en": "This hypervisor is Proxmox VE: it has no libvirt.", }, "Its screen is served by a ticket, not by a VNC port.": { "fr": "Son écran est servi par un ticket, pas par un port VNC.", "en": "Its screen is served by a ticket, not by a VNC port.", }, "Two ways in:": { "fr": "Deux chemins :", "en": "Two ways in:", }, "the serial console, VMID from the Proxmox menu:": { "fr": "la console série, le VMID venant du menu Proxmox :", "en": "the serial console, VMID from the Proxmox menu:", }, "the web interface, through a tunnel:": { "fr": "l'interface web, par un tunnel :", "en": "the web interface, through a tunnel:", }, "TODO > Execute > Deploy > Proxmox VE does the first.": { "fr": "TODO > Execute > Deploy > Proxmox VE fait le premier.", "en": "TODO > Execute > Deploy > Proxmox VE does the first.", }, "This VM exposes no VNC port.": { "fr": "Cette VM n'expose aucun port VNC.", "en": "This VM exposes no VNC port.", }, "Its display is likely spice with listen=none:": { "fr": "Son affichage est probablement spice avec listen=none :", "en": "Its display is likely spice with listen=none:", }, "To open it on the loopback (VM restart required):": { "fr": "Pour l'ouvrir sur la boucle locale (redémarrage de la VM" " requis) :", "en": "To open it on the loopback (VM restart required):", }, "New VMs get this by default; see deploy_qemu.": { "fr": "Les VM neuves l'ont par défaut ; voir deploy_qemu.", "en": "New VMs get this by default; see deploy_qemu.", }, "No ProxyJump for this host in ~/.ssh/config.": { "fr": "Aucun ProxyJump pour cet hôte dans ~/.ssh/config.", "en": "No ProxyJump for this host in ~/.ssh/config.", }, "Cannot tell which machine runs its QEMU.": { "fr": "Impossible de savoir quelle machine fait tourner son QEMU.", "en": "Cannot tell which machine runs its QEMU.", }, "(through the ProxyJump already in ~/.ssh/config)": { "fr": "(par le ProxyJump déjà dans ~/.ssh/config)", "en": "(through the ProxyJump already in ~/.ssh/config)", }, "(the hypervisor only relays; -J puts the VM last)": { "fr": "(l'hyperviseur ne fait que relayer ; -J met la VM en dernier)", "en": "(the hypervisor only relays; -J puts the VM last)", }, "Choice": {"fr": "Choix", "en": "Choice"}, "failed steps": {"fr": "étapes en échec", "en": "failed steps"}, "Failed steps": {"fr": "Étapes en échec", "en": "Failed steps"}, "Hard signals": {"fr": "Signaux durs", "en": "Hard signals"}, "Grouped by shape": {"fr": "Regroupé par forme", "en": "Grouped by shape"}, "line": {"fr": "ligne", "en": "line"}, "free space": {"fr": "libre", "en": "free"}, "silent": {"fr": "silence", "en": "silent"}, "needs the ERPLibre install, skipped:": { "fr": "exige l'installation ERPLibre, écarté :", "en": "needs the ERPLibre install, skipped:", }, "Forgejo (git forge)": { "fr": "Forgejo (forge git)", "en": "Forgejo (git forge)", }, "self-hosted git forge on :3000, SQLite": { "fr": "forge git auto-hébergée sur :3000, SQLite", "en": "self-hosted git forge on :3000, SQLite", }, "no project yet, second try on the warm caches": { "fr": "pas de projet encore ; seconde tentative sur les caches chauds", "en": "no project yet, second try on the warm caches", }, "already there, download skipped": { "fr": "déjà présent, téléchargement évité", "en": "already there, download skipped", }, "inotify watches raised for the IDE": { "fr": "watches inotify relevées pour l'IDE", "en": "inotify watches raised for the IDE", }, "closing what survived the first open:": { "fr": "fermeture de ce qui a survécu à la première ouverture :", "en": "closing what survived the first open:", }, "Gradle daemon killed: out of memory": { "fr": "démon Gradle tué : mémoire épuisée", "en": "Gradle daemon killed: out of memory", }, "out of memory": {"fr": "mémoire épuisée", "en": "out of memory"}, "Gradle heap too small": { "fr": "tas Gradle trop petit", "en": "Gradle heap too small", }, "too many asset files for one APK (ZIP limit: 65535 entries)": { "fr": "trop de fichiers d'assets pour un APK (limite ZIP : 65535" " entrées)", "en": "too many asset files for one APK (ZIP limit: 65535 entries)", }, "4 GB of swap added for the build": { "fr": "4 Go de swap ajoutés pour la compilation", "en": "4 GB of swap added for the build", }, "no swap could be added; build may run short": { "fr": "swap impossible à ajouter ; la compilation peut manquer de mémoire", "en": "no swap could be added; build may run short", }, "memory:": {"fr": "mémoire :", "en": "memory:"}, "manifest repos not bundled (ZIP entry limit)": { "fr": "dépôts du manifeste non empaquetés (limite d'entrées ZIP)", "en": "manifest repos not bundled (ZIP entry limit)", }, "MB RAM,": {"fr": "Mo de RAM,", "en": "MB RAM,"}, "MB swap, kernel OOM kills:": { "fr": "Mo de swap, tués par le noyau (OOM) :", "en": "MB swap, kernel OOM kills:", }, "Tick the Android emulator tool when deploying.": { "fr": "Cochez l'outil Émulateur Android au déploiement.", "en": "Tick the Android emulator tool when deploying.", }, "Cannot reach this VM.": { "fr": "VM injoignable.", "en": "Cannot reach this VM.", }, "No Android SDK in this VM: no emulator binary.": { "fr": "Pas de SDK Android dans cette VM : aucun binaire emulator.", "en": "No Android SDK in this VM: no emulator binary.", }, "No AVD named erplibre in this VM.": { "fr": "Aucun AVD nommé erplibre dans cette VM.", "en": "No AVD named erplibre in this VM.", }, "It did not start; the VM log says:": { "fr": "Il n'a pas démarré ; le journal de la VM dit :", "en": "It did not start; the VM log says:", }, "No ~/.ssh/config entry; see SSH configuration.": { "fr": "Aucune entrée ~/.ssh/config ; voir Configuration SSH.", "en": "No ~/.ssh/config entry; see SSH configuration.", }, "Not in an SSH session: check the host address.": { "fr": "Hors session SSH : vérifiez l'adresse de l'hôte.", "en": "Not in an SSH session: check the host address.", }, "The tunnel stays open as long as that ssh runs.": { "fr": "Le tunnel reste ouvert tant que ce ssh tourne.", "en": "The tunnel stays open as long as that ssh runs.", }, "No VM defined.": {"fr": "Aucune VM définie.", "en": "No VM defined."}, "No host in ~/.ssh/config and no local VM.": { "fr": "Aucun hôte dans ~/.ssh/config et aucune VM locale.", "en": "No host in ~/.ssh/config and no local VM.", }, "local VM": {"fr": "VM locale", "en": "local VM"}, "Remote desktop kind:": { "fr": "Type de bureau distant :", "en": "Remote desktop kind:", }, "already defined, not counted": { "fr": "déjà définie(s), non comptée(s)", "en": "already defined, not counted", }, "RAM: 2048 or 8G": {"fr": "RAM : 2048 ou 8G", "en": "RAM: 2048 or 8G"}, "Diagnostic dump": {"fr": "Diagnostic", "en": "Diagnostic dump"}, "State written to": {"fr": "État écrit dans", "en": "State written to"}, "Reset VM": { "fr": "Réinit. VM", "en": "Reset VM", }, "Preview": { "fr": "Aperçu", "en": "Preview", }, "All": { "fr": "Tout", "en": "All", }, "Main versions": { "fr": "Versions principales", "en": "Main versions", }, "None": { "fr": "Rien", "en": "None", }, "Cancel": { "fr": "Annuler", "en": "Cancel", }, "Apply": { "fr": "Appliquer", "en": "Apply", }, "Close": { "fr": "Fermer", "en": "Close", }, "Copy log": { "fr": "Copier le log", "en": "Copy log", }, "Copy all logs": { "fr": "Copier tous les logs", "en": "Copy all logs", }, "all logs": { "fr": "tous les logs", "en": "all logs", }, "c copy log · C copy all · q quit": { "fr": "c copier le log · C copier tout · q quitter", "en": "c copy log · C copy all · q quit", }, "Clipboard": { "fr": "Presse-papiers", "en": "Clipboard", }, "chars": { "fr": "car.", "en": "chars", }, "tail only, log was truncated": { "fr": "fin seulement, log tronqué", "en": "tail only, log was truncated", }, "Needs an OSC 52 capable terminal.": { "fr": "Nécessite un terminal compatible OSC 52.", "en": "Needs an OSC 52 capable terminal.", }, "Nothing to copy.": { "fr": "Rien à copier.", "en": "Nothing to copy.", }, "TODO navigation telemetry": { "fr": "TODO — télémétrie de navigation", "en": "TODO navigation telemetry", }, "navigations": { "fr": "navigations", "en": "navigations", }, "menus": { "fr": "menus", "en": "menus", }, "Telemetry reset.": { "fr": "Télémétrie réinitialisée.", "en": "Telemetry reset.", }, "tree from code": { "fr": "arbre issu du code", "en": "tree from code", }, "visited paths only": { "fr": "chemins visités seulement", "en": "visited paths only", }, "Enter = run, F3 = view": { "fr": "Entrée = exécuter, F3 = vue", "en": "Enter = run, F3 = view", }, "Enter = run, F3/F4 = views": { "fr": "Entrée = exécuter, F3/F4 = vues", "en": "Enter = run, F3/F4 = views", }, "view": { "fr": "vue", "en": "view", }, "avg": { "fr": "moy", "en": "avg", }, "Last install:": { "fr": "Dernière install :", "en": "Last install:", }, "No command found.": { "fr": "Aucune commande trouvée.", "en": "No command found.", }, "Back to telemetry (r) or quit (Enter)? ": { "fr": "Revenir à la télémétrie (r) ou quitter (Entrée) ? ", "en": "Back to telemetry (r) or quit (Enter)? ", }, "F2 system · F3/F4 views · Enter run": { "fr": "F2 système · F3/F4 vues · Entrée exécute", "en": "F2 system · F3/F4 views · Enter run", }, "State": {"fr": "État", "en": "State"}, "uptime": {"fr": "actif depuis", "en": "uptime"}, "load": {"fr": "charge", "en": "load"}, "cores": {"fr": "cœurs", "en": "cores"}, "Memory": {"fr": "Mémoire", "en": "Memory"}, "Disk": {"fr": "Disque", "en": "Disk"}, "Network": {"fr": "Réseau", "en": "Network"}, "Battery": {"fr": "Batterie", "en": "Battery"}, "Temperature": {"fr": "Température", "en": "Temperature"}, "lm-sensors absent — press i to install": { "fr": "lm-sensors absent — appuyez sur i pour installer", "en": "lm-sensors absent — press i to install", }, "Sensors already available.": { "fr": "Capteurs déjà disponibles.", "en": "Sensors already available.", }, "Sensors now available.": { "fr": "Capteurs désormais disponibles.", "en": "Sensors now available.", }, "Still no temperature (reboot/modprobe may be needed).": { "fr": "Toujours pas de température (redémarrage/modprobe requis ?).", "en": "Still no temperature (reboot/modprobe may be needed).", }, "Unknown package manager for lm-sensors.": { "fr": "Gestionnaire de paquets inconnu pour lm-sensors.", "en": "Unknown package manager for lm-sensors.", }, "Proposed install command:": { "fr": "Commande d'installation proposée :", "en": "Proposed install command:", }, "Install lm-sensors now? (y/N): ": { "fr": "Installer lm-sensors maintenant ? (o/N) : ", "en": "Install lm-sensors now? (y/N): ", }, "Command failed: ": { "fr": "Échec de la commande : ", "en": "Command failed: ", }, "Textual is required for this screen.": { "fr": "Textual est nécessaire pour cet écran.", "en": "Textual is required for this screen.", }, "Install it now? (Y/n): ": { "fr": "L'installer maintenant ? (O/n, défaut : oui) : ", "en": "Install it now? (Y/n, default: yes): ", }, "Textual is installed.": { "fr": "Textual est installé.", "en": "Textual is installed.", }, "Installation finished but textual is still missing.": { "fr": "Installation terminée mais textual reste introuvable.", "en": "Installation finished but textual is still missing.", }, "pip exited with": { "fr": "pip a retourné", "en": "pip exited with", }, "Your distribution may package it as python3-textual.": { "fr": "Votre distribution le fournit peut-être en python3-textual.", "en": "Your distribution may package it as python3-textual.", }, "Resize a VM disk": { "fr": "📐 Redimensionner le disque d'une VM", "en": "📐 Resize a VM disk", }, "VM name to resize: ": { "fr": "Nom de la VM à redimensionner : ", "en": "VM name to resize: ", }, "VM not found.": { "fr": "VM introuvable.", "en": "VM not found.", }, "Main disk not found for this VM.": { "fr": "Disque principal introuvable pour cette VM.", "en": "Main disk not found for this VM.", }, "Current disk:": { "fr": "Disque actuel :", "en": "Current disk:", }, "Current virtual size:": { "fr": "Taille virtuelle actuelle :", "en": "Current virtual size:", }, "VM state:": { "fr": "État de la VM :", "en": "VM state:", }, "Could not read current disk size; aborting.": { "fr": "Impossible de lire la taille actuelle du disque ; abandon.", "en": "Could not read current disk size; aborting.", }, "Host free space:": { "fr": "Espace libre hôte :", "en": "Host free space:", }, "max sustainable total (before host full):": { "fr": "max soutenable au total (avant hôte plein) :", "en": "max sustainable total (before host full):", }, "Beyond host capacity by ~%.1f G — overcommit.": { "fr": "Dépasse la capacité de l'hôte de ~%.1f G — surallocation.", "en": "Beyond host capacity by ~%.1f G — overcommit.", }, "The qcow2 is thin: fine until the VM fills it, then the " "host disk runs out. Max sustainable: ~%.1f G.": { "fr": "Le qcow2 est creux : OK tant que la VM ne remplit pas, sinon " "l'hôte tombe à court. Max soutenable : ~%.1f G.", "en": "The qcow2 is thin: fine until the VM fills it, then the " "host disk runs out. Max sustainable: ~%.1f G.", }, "Safe shrink needs libguestfs (virt-resize).": { "fr": "La réduction sûre nécessite libguestfs (virt-resize).", "en": "Safe shrink needs libguestfs (virt-resize).", }, "Install libguestfs-tools now? (y/N): ": { "fr": "Installer libguestfs-tools maintenant ? (o/N) : ", "en": "Install libguestfs-tools now? (y/N): ", }, "Shrink aborted; disk left intact.": { "fr": "Réduction annulée ; disque laissé intact.", "en": "Shrink aborted; disk left intact.", }, "Could not detect the partition to shrink; aborting.": { "fr": "Partition à réduire introuvable ; abandon.", "en": "Could not detect the partition to shrink; aborting.", }, "Missing tools for safe shrink:": { "fr": "Outils manquants pour la réduction sûre :", "en": "Missing tools for safe shrink:", }, "Install them? (y/N): ": { "fr": "Les installer? (y/N) : ", "en": "Install them? (y/N): ", }, "Error installing the tools: ": { "fr": "Erreur lors de l'installation des outils : ", "en": "Error installing the tools: ", }, "Still missing, safe shrink cancelled:": { "fr": "Manquent toujours, réduction sûre annulée :", "en": "Still missing, safe shrink cancelled:", }, "No package known here for:": { "fr": "Aucun paquet connu ici pour :", "en": "No package known here for:", }, "Tools installed; on with the shrink.": { "fr": "Outils installés ; on passe à la réduction.", "en": "Tools installed; on with the shrink.", }, "A backup doubles the space used:": { "fr": "Une sauvegarde double la place occupée :", "en": "A backup doubles the space used:", }, "free here:": { "fr": "libre ici :", "en": "free here:", }, "Not enough free space for a full backup.": { "fr": "Pas assez de place libre pour une sauvegarde complète.", "en": "Not enough free space for a full backup.", }, "Back up anyway, at the risk of filling the disk? (y/N): ": { "fr": "Sauvegarder quand même, au risque de remplir le disque? (y/N) : ", "en": "Back up anyway, at the risk of filling the disk? (y/N): ", }, "Backing up the disk before shrinking…": { "fr": "Sauvegarde du disque avant réduction…", "en": "Backing up the disk before shrinking…", }, "Back up the disk before shrinking? (Y/n): ": { "fr": "Sauvegarder le disque avant réduction ? (O/n, défaut : oui) : ", "en": "Back up the disk before shrinking? (Y/n, default: yes): ", }, "No backup: a failure could leave the disk broken.": { "fr": "Sans sauvegarde : un échec pourrait rendre le disque inutilisable.", "en": "No backup: a failure could leave the disk broken.", }, "Disk safely shrunk.": { "fr": "Disque réduit en toute sécurité.", "en": "Disk safely shrunk.", }, "No backup to restore; run fsck on the disk before use.": { "fr": "Pas de sauvegarde à restaurer ; lancez fsck avant utilisation.", "en": "No backup to restore; run fsck on the disk before use.", }, "A disk backup was kept:": { "fr": "Une sauvegarde du disque a été conservée :", "en": "A disk backup was kept:", }, "Delete this backup now? (y/N): ": { "fr": "Effacer cette sauvegarde maintenant ? (o/N) : ", "en": "Delete this backup now? (y/N): ", }, "Backup deleted.": { "fr": "Sauvegarde effacée.", "en": "Backup deleted.", }, "Backup kept (delete later via Clean up QEMU).": { "fr": "Sauvegarde conservée (à effacer plus tard via Nettoyer QEMU).", "en": "Backup kept (delete later via Clean up QEMU).", }, "disk backup (resize)": { "fr": "sauvegarde de disque (redim.)", "en": "disk backup (resize)", }, "Backup failed; aborting.": { "fr": "Échec de la sauvegarde ; abandon.", "en": "Backup failed; aborting.", }, "Could not attach the disk (nbd); aborting.": { "fr": "Impossible d'attacher le disque (nbd) ; abandon.", "en": "Could not attach the disk (nbd); aborting.", }, "Only ext2/3/4 can be shrunk safely; aborting.": { "fr": "Seul ext2/3/4 peut être réduit en sécurité ; abandon.", "en": "Only ext2/3/4 can be shrunk safely; aborting.", }, "Target size too small for this layout; aborting.": { "fr": "Taille cible trop petite pour cette disposition ; abandon.", "en": "Target size too small for this layout; aborting.", }, "Not enough used-space margin to shrink; aborting.": { "fr": "Espace utilisé trop proche de la cible ; abandon.", "en": "Not enough used-space margin to shrink; aborting.", }, "Shrinking guest ext filesystem": { "fr": "Réduction du système de fichiers ext invité", "en": "Shrinking guest ext filesystem", }, "resize2fs failed; reverting.": { "fr": "resize2fs a échoué ; restauration.", "en": "resize2fs failed; reverting.", }, "Internal size check failed; reverting.": { "fr": "Contrôle de taille interne échoué ; restauration.", "en": "Internal size check failed; reverting.", }, "Shrinking the partition…": { "fr": "Réduction de la partition…", "en": "Shrinking the partition…", }, "Partition rewrite failed; reverting.": { "fr": "Réécriture de la partition échouée ; restauration.", "en": "Partition rewrite failed; reverting.", }, "Shrinking the qcow2 container…": { "fr": "Réduction du conteneur qcow2…", "en": "Shrinking the qcow2 container…", }, "Container shrink failed; reverting.": { "fr": "Réduction du conteneur échouée ; restauration.", "en": "Container shrink failed; reverting.", }, "Restoring the original disk from backup…": { "fr": "Restauration du disque d'origine depuis la sauvegarde…", "en": "Restoring the original disk from backup…", }, "Shrinking guest FS + partition via virt-resize": { "fr": "Réduction du FS invité + partition via virt-resize", "en": "Shrinking guest FS + partition via virt-resize", }, "virt-resize failed; original disk left intact.": { "fr": "virt-resize a échoué ; disque d'origine laissé intact.", "en": "virt-resize failed; original disk left intact.", }, "Disk safely shrunk. Backup kept at:": { "fr": "Disque réduit en toute sécurité. Sauvegarde conservée :", "en": "Disk safely shrunk. Backup kept at:", }, "click to expand": { "fr": "cliquer pour déplier", "en": "click to expand", }, "No error detected.": { "fr": "Aucune erreur détectée.", "en": "No error detected.", }, "Test a VM (open Odoo in a CLI browser)": { "fr": "🧪 Tester une VM (ouvrir Odoo dans un navigateur CLI)", "en": "🧪 Test a VM (open Odoo in a CLI browser)", }, "Reopen install monitoring (last run / history)": { "fr": "📈 Rouvrir le suivi d'installation (dernier run / historique)", "en": "📈 Reopen install monitoring (last run / history)", }, "No install run found in history.": { "fr": "Aucun run d'installation dans l'historique.", "en": "No install run found in history.", }, "Install runs (most recent first):": { "fr": "Runs d'installation (du plus récent) :", "en": "Install runs (most recent first):", }, "Choice (number, blank = last): ": { "fr": "Choix (numéro, vide = le dernier) : ", "en": "Choice (number, blank = last): ", }, "Invalid selection.": { "fr": "Sélection invalide.", "en": "Invalid selection.", }, "Resolving VM IP...": { "fr": "Résolution de l'IP de la VM…", "en": "Resolving VM IP...", }, "No IP found for this VM.": { "fr": "Aucune IP trouvée pour cette VM.", "en": "No IP found for this VM.", }, "No CLI browser installed. Which to install?": { "fr": "Aucun navigateur CLI installé. Lequel installer ?", "en": "No CLI browser installed. Which to install?", }, "Which browser to install?": { "fr": "Quel navigateur installer ?", "en": "Which browser to install?", }, "Install another browser": { "fr": "Installer un autre navigateur", "en": "Install another browser", }, "Choice (number, blank = w3m): ": { "fr": "Choix (numéro, vide = w3m) : ", "en": "Choice (number, blank = w3m): ", }, "Unknown package manager; install it manually.": { "fr": "Gestionnaire de paquets inconnu ; installez-le manuellement.", "en": "Unknown package manager; install it manually.", }, "Install now? (y/N): ": { "fr": "Installer maintenant ? (o/N) : ", "en": "Install now? (y/N): ", }, "Which browser to view the page?": { "fr": "Quel navigateur pour voir la page ?", "en": "Which browser to view the page?", }, "Choice (number, blank = first): ": { "fr": "Choix (numéro, vide = le premier) : ", "en": "Choice (number, blank = first): ", }, "Page may not have loaded: Odoo not started on :8069, " "or network/firewall.": { "fr": "La page ne s'est peut-être pas affichée : Odoo n'est pas " "démarré sur :8069, ou réseau/pare-feu.", "en": "Page may not have loaded: Odoo not started on :8069, " "or network/firewall.", }, "errors": { "fr": "erreurs", "en": "errors", }, "warnings": { "fr": "avertissements", "en": "warnings", }, "Esc to close": { "fr": "Échap pour fermer", "en": "Esc to close", }, "No running VM to pause.": { "fr": "Aucune VM en cours à mettre en pause.", "en": "No running VM to pause.", }, "No paused VM to resume.": { "fr": "Aucune VM en pause à reprendre.", "en": "No paused VM to resume.", }, "resumed": { "fr": "reprise(s)", "en": "resumed", }, "SSH grow failed; trying the guest agent.": { "fr": "Échec SSH ; tentative via l'agent invité.", "en": "SSH grow failed; trying the guest agent.", }, "No IP; trying the guest agent (no network).": { "fr": "Pas d'IP ; tentative via l'agent invité (sans réseau).", "en": "No IP; trying the guest agent (no network).", }, "Guest filesystem grown via guest agent.": { "fr": "FS invité étendu via l'agent invité.", "en": "Guest filesystem grown via guest agent.", }, "Guest agent grow failed; falling back to console.": { "fr": "Échec de l'agent invité ; repli sur la console.", "en": "Guest agent grow failed; falling back to console.", }, "Guest agent unavailable; falling back to serial console.": { "fr": "Agent invité indisponible ; repli sur la console série.", "en": "Guest agent unavailable; falling back to serial console.", }, "Running via guest agent (no network)…": { "fr": "Exécution via l'agent invité (sans réseau)…", "en": "Running via guest agent (no network)…", }, "SSH grow failed; falling back to serial console.": { "fr": "Échec de l'extension via SSH ; repli sur la console série.", "en": "SSH grow failed; falling back to serial console.", }, "No IP; falling back to serial console.": { "fr": "Pas d'IP ; repli sur la console série.", "en": "No IP; falling back to serial console.", }, "Serial console fallback. Log in, then paste:": { "fr": "Repli console série. Connectez-vous, puis collez :", "en": "Serial console fallback. Log in, then paste:", }, "Open the serial console now? (y/N): ": { "fr": "Ouvrir la console série maintenant ? (o/N) : ", "en": "Open the serial console now? (y/N): ", }, "The VM must be off. Shut it down and retry? (y/N): ": { "fr": "La VM doit être éteinte. L'éteindre et réessayer ? (o/N) : ", "en": "The VM must be off. Shut it down and retry? (y/N): ", }, "VM is still not off; aborting.": { "fr": "La VM n'est toujours pas éteinte ; abandon.", "en": "VM is still not off; aborting.", }, "Waiting for the VM to shut down...": { "fr": "Attente de l'arrêt de la VM…", "en": "Waiting for the VM to shut down...", }, "timeout": { "fr": "délai max", "en": "timeout", }, "shutting down": { "fr": "arrêt en cours", "en": "shutting down", }, "remaining": { "fr": "restantes", "en": "remaining", }, "VM is off.": { "fr": "VM éteinte.", "en": "VM is off.", }, "The VM was shut down for the resize.": { "fr": "La VM a été éteinte pour le redimensionnement.", "en": "The VM was shut down for the resize.", }, "Start the VM now? (y/N): ": { "fr": "Démarrer la VM maintenant ? (o/N) : ", "en": "Start the VM now? (y/N): ", }, "Graceful shutdown timed out. Force off (destroy)? (y/N): ": { "fr": "Arrêt gracieux trop long. Forcer l'arrêt (destroy) ? (o/N) : ", "en": "Graceful shutdown timed out. Force off (destroy)? (y/N): ", }, "Show advanced info (vCPU, RAM, disk)? (y/N): ": { "fr": "Afficher les infos avancées (vCPU, RAM, disque) ? (o/N) : ", "en": "Show advanced info (vCPU, RAM, disk)? (y/N): ", }, "What do you want to do?": { "fr": "Que voulez-vous faire ?", "en": "What do you want to do?", }, "Advanced info (vCPU, RAM, disk)": { "fr": "Infos avancées (vCPU, RAM, disque)", "en": "Advanced info (vCPU, RAM, disk)", }, "Change the state of one or more VMs": { "fr": "Changer l'état d'une ou plusieurs VM", "en": "Change the state of one or more VMs", }, "Enter": { "fr": "Entrée", "en": "Enter", }, "Nothing": { "fr": "Rien", "en": "Nothing", }, "Choice: ": { "fr": "Choix : ", "en": "Choice: ", }, "Available VMs:": { "fr": "VM disponibles :", "en": "Available VMs:", }, "VMs to change (comma-separated): ": { "fr": "VM à modifier (séparées par des virgules) : ", "en": "VMs to change (comma-separated): ", }, "Adjust hardware only (vCPU, RAM, 3D)": { "fr": "Régler le matériel seulement (vCPU, RAM, 3D)", "en": "Adjust hardware only (vCPU, RAM, 3D)", }, "Adjust hardware before starting? (y/N): ": { "fr": "Régler le matériel avant de démarrer ? (o/N) : ", "en": "Adjust hardware before starting? (y/N): ", }, "Not shut off, hardware left untouched:": { "fr": "Pas éteintes, matériel inchangé :", "en": "Not shut off, hardware left untouched:", }, "Host GPU:": { "fr": "GPU de l'hôte :", "en": "Host GPU:", }, "none (software rendering)": { "fr": "aucun (rendu logiciel)", "en": "none (software rendering)", }, "software rendering": { "fr": "rendu logiciel", "en": "software rendering", }, "Unreadable VM definition.": { "fr": "Définition de VM illisible.", "en": "Unreadable VM definition.", }, "Nothing to change.": { "fr": "Rien à changer.", "en": "Nothing to change.", }, "Changes:": { "fr": "Changements :", "en": "Changes:", }, "Apply these changes? (y/N): ": { "fr": "Appliquer ces changements ? (o/N) : ", "en": "Apply these changes? (y/N): ", }, "Autostart": { "fr": "Démarrage automatique", "en": "Autostart", }, "VM hardware": { "fr": "Matériel des VM", "en": "VM hardware", }, "3D": { "fr": "3D", "en": "3D", }, "3D acceleration (host GPU)": { "fr": "Accélération 3D (GPU de l'hôte)", "en": "3D acceleration (host GPU)", }, "Render node": { "fr": "Nœud de rendu", "en": "Render node", }, "VM ready - taking its measurements": { "fr": "VM prête — relevé en cours", "en": "VM ready - taking its measurements", }, "VM start-up": { "fr": "Mise en route de la VM", "en": "VM start-up", }, "system:": { "fr": "système :", "en": "system:", }, "kernel:": { "fr": "noyau :", "en": "kernel: ", }, "address:": { "fr": "adresse :", "en": "address:", }, "disk:": { "fr": "disque :", "en": "disk: ", }, "uptime:": { "fr": "actif :", "en": "uptime: ", }, "Watch the VMs start (no install)": { "fr": "Suivre le démarrage des VM (sans installation)", "en": "Watch the VMs start (no install)", }, "Proxmox VE - Deploy a VM on a remote host": { # 🗄 et non 💻 : l'entrée d'à côté déploie sur CETTE machine, celle-ci # sur une baie ailleurs. L'icône est ce qui distingue les deux d'un # coup d'œil dans le menu. "fr": "🗄 Proxmox VE - Déployer une VM sur un hôte distant", "en": "🗄 Proxmox VE - Deploy a VM on a remote host", }, "Deploy a virtual machine on Proxmox VE!": { "fr": "Déployer une machine virtuelle sur Proxmox VE !", "en": "Deploy a virtual machine on Proxmox VE!", }, "Which Proxmox host?": { "fr": "Quel hôte Proxmox ?", "en": "Which Proxmox host?", }, "From the local QEMU VMs": { "fr": "Depuis les VM QEMU locales", "en": "From the local QEMU VMs", }, "Type an address": { "fr": "Saisir une adresse", "en": "Type an address", }, "Keep": { "fr": "Garder", "en": "Keep", }, "Address (user@host, default user root): ": { "fr": "Adresse (utilisateur@hôte, utilisateur root par défaut) : ", "en": "Address (user@host, default user root): ", }, "SSH jump host (blank = none): ": { "fr": "Rebond SSH (vide = aucun) : ", "en": "SSH jump host (blank = none): ", }, "Local VMs:": { "fr": "VM locales :", "en": "Local VMs:", }, "No IP for this VM: is it running?": { "fr": "Pas d'IP pour cette VM : est-elle démarrée ?", "en": "No IP for this VM: is it running?", }, "Checking": { "fr": "Vérification de", "en": "Checking", }, "Not a Proxmox host (or unreachable):": { "fr": "Ce n'est pas un hôte Proxmox (ou il est injoignable) :", "en": "Not a Proxmox host (or unreachable):", }, "Reachable, but Proxmox VE is not there:": { "fr": "Machine joignable, mais Proxmox VE n'y est pas :", "en": "Reachable, but Proxmox VE is not there:", }, "SSH does not get through:": { "fr": "SSH ne passe pas :", "en": "SSH does not get through:", }, "Install it:": { "fr": "Pour l'installer :", "en": "Install it:", }, "Or redeploy the VM with the hypervisor profile.": { "fr": "Ou redéployer la VM avec le profil hyperviseur.", "en": "Or redeploy the VM with the hypervisor profile.", }, "Check the address, the SSH access and pveversion.": { "fr": "Vérifier l'adresse, l'accès SSH et pveversion.", "en": "Check the address, the SSH access and pveversion.", }, "Proxmox host:": { "fr": "Hôte Proxmox :", "en": "Proxmox host:", }, "through": { "fr": "par", "en": "through", }, "exit code": { "fr": "code de retour", "en": "exit code", }, "No VM on this Proxmox host.": { "fr": "Aucune VM sur cet hôte Proxmox.", "en": "No VM on this Proxmox host.", }, "No running VM on this Proxmox host.": { "fr": "Aucune VM démarrée sur cet hôte Proxmox.", "en": "No running VM on this Proxmox host.", }, "VMs on this host:": { "fr": "VM de cet hôte :", "en": "VMs on this host:", }, "Selection (number): ": { "fr": "Sélection (numéro) : ", "en": "Selection (number): ", }, "Deploy a VM on the Proxmox host": { "fr": "🚀 Déployer une VM sur l'hôte Proxmox", "en": "🚀 Deploy a VM on the Proxmox host", }, "Preview a deployment (dry-run, nothing sent)": { "fr": "🔍 Prévisualiser un déploiement (dry-run, rien n'est envoyé)", "en": "🔍 Preview a deployment (dry-run, nothing sent)", }, "Download a cloud image on the host": { "fr": "📥 Télécharger une image cloud sur l'hôte", "en": "📥 Download a cloud image on the host", }, "List VMs (qm list)": { "fr": "📋 Lister les VM (qm list)", "en": "📋 List VMs (qm list)", }, "Clean up (orphan disks)": { "fr": "🧹 Nettoyer (disques orphelins)", "en": "🧹 Clean up (orphan disks)", }, "Statistics (host and VMs)": { "fr": "📊 Statistiques (hôte et VM)", "en": "📊 Statistics (host and VMs)", }, "Remote desktop tunnel (VNC/RDP over SSH)": { "fr": "🖥 Tunnel bureau distant (VNC/RDP par SSH)", "en": "🖥 Remote desktop tunnel (VNC/RDP over SSH)", }, "List available images and their specs": { "fr": "🗂 Lister les images disponibles et leurs specs", "en": "🗂 List available images and their specs", }, "Proxmox - example sequence (dry-run)": { "fr": "🎬 Proxmox - exemple de séquence (dry-run)", "en": "🎬 Proxmox - example sequence (dry-run)", }, "Host": { "fr": "🏠 Hôte", "en": "🏠 Host", }, "Change the Proxmox host": { "fr": "🔀 Changer d'hôte Proxmox", "en": "🔀 Change the Proxmox host", }, "VM name (default: erplibre-): ": { "fr": "Nom de la VM (défaut : erplibre-) : ", "en": "VM name (default: erplibre-): ", }, "RAM in MB, blank = 4096": { "fr": "RAM en Mo, vide = 4096", "en": "RAM in MB, blank = 4096", }, "vCPU, blank = 2": { "fr": "vCPU, vide = 2", "en": "vCPU, blank = 2", }, "Disk size (default 32G): ": { "fr": "Taille du disque (défaut 32G) : ", "en": "Disk size (default 32G): ", }, "Size (+10G to add, 40G for a target): ": { "fr": "Taille (+10G pour ajouter, 40G pour une cible) : ", "en": "Size (+10G to add, 40G for a target): ", }, "The cluster probe did not answer: cause unknown.": { "fr": "La sonde du cluster n'a pas répondu : cause inconnue.", "en": "The cluster probe did not answer: cause unknown.", }, "This screen can repair it (see below).": { "fr": "Cet écran peut le réparer (voir ci-dessous).", "en": "This screen can repair it (see below).", }, "Repair it from here?": { "fr": "Le réparer d'ici ?", "en": "Repair it from here?", }, "freeze cloud-init, fix /etc/hosts, restart pmxcfs": { "fr": "geler cloud-init, corriger /etc/hosts, relancer pmxcfs", "en": "freeze cloud-init, fix /etc/hosts, restart pmxcfs", }, "leave it alone": { "fr": "ne rien toucher", "en": "leave it alone", }, "Cannot tell which address reaches this host.": { "fr": "Impossible de savoir quelle adresse atteint cet hôte.", "en": "Cannot tell which address reaches this host.", }, "address the node will answer for": { "fr": "adresse sous laquelle le nœud répondra", "en": "address the node will answer for", }, "mounted then lost again": { "fr": "monté puis reperdu", "en": "mounted then lost again", }, "restarts": { "fr": "relances", "en": "restarts", }, "mounted": { "fr": "monté", "en": "mounted", }, "The hostname resolves fine: only the units are down.": { "fr": "Le nom d'hôte résout bien : seules les unités sont à terre.", "en": "The hostname resolves fine: only the units are down.", }, "restart pmxcfs only (the address is fine)": { "fr": "relancer pmxcfs seulement (l'adresse est bonne)", "en": "restart pmxcfs only (the address is fine)", }, "would not start:": { "fr": "n'a pas démarré :", "en": "would not start:", }, "Cannot tell whether it mounted (link lost).": { "fr": "Impossible de constater le montage (lien perdu).", "en": "Cannot tell whether it mounted (link lost).", }, "still absent": { "fr": "toujours absent", "en": "still absent", }, "The address written may not be the one pmxcfs needs.": { "fr": "L'adresse écrite n'est peut-être pas celle qu'il faut à pmxcfs.", "en": "The address written may not be the one pmxcfs needs.", }, "Destroy all that? (y/N): ": { "fr": "Détruire tout cela ? (o/N) : ", "en": "Destroy all that? (y/N): ", }, "Long tests - real VMs, hours": { "fr": "⏳ Tests longs - vraies VM, des heures", "en": "⏳ Long tests - real VMs, hours", }, "Long tests: real VMs, hours. Not the unit suite.": { "fr": "Tests longs : de vraies VM, des heures. Pas la suite unitaire.", "en": "Long tests: real VMs, hours. Not the unit suite.", }, "Nested Proxmox depth: plan only (dry-run)": { "fr": "Profondeur Proxmox imbriqué : le plan seulement (à blanc)", "en": "Nested Proxmox depth: plan only (dry-run)", }, "Nested Proxmox depth: run it": { "fr": "Profondeur Proxmox imbriqué : le lancer", "en": "Nested Proxmox depth: run it", }, "Undo what the descent created": { "fr": "Défaire ce que la descente a créé", "en": "Undo what the descent created", }, "Script not found:": { "fr": "Script introuvable :", "en": "Script not found:", }, "Nested QEMU depth: plan only (dry-run)": { "fr": "Profondeur QEMU imbriqué : le plan seulement (à blanc)", "en": "Nested QEMU depth: plan only (dry-run)", }, # ERPLibre installé sur NixOS, de bout en bout. "ERPLibre on NixOS: plan only (dry-run)": { "fr": "ERPLibre sur NixOS : le plan seulement (à blanc)", "en": "ERPLibre on NixOS: plan only (dry-run)", }, "ERPLibre on NixOS: run it": { "fr": "ERPLibre sur NixOS : le lancer", "en": "ERPLibre on NixOS: run it", }, "Where does the install run?": { "fr": "Où l'installation se fait-elle ?", "en": "Where does the install run?", }, "Create a fresh NixOS VM": { "fr": "Créer une VM NixOS neuve", "en": "Create a fresh NixOS VM", }, "Use a NixOS machine you already have": { "fr": "Partir d'une machine NixOS qu'on possède déjà", "en": "Use a NixOS machine you already have", }, "Nested QEMU depth: run it": { "fr": "Profondeur QEMU imbriqué : le lancer", "en": "Nested QEMU depth: run it", }, "Where does the descent start?": { "fr": "D'où part la descente ?", "en": "Where does the descent start?", }, "Create a fresh QEMU VM as level one": { "fr": "Créer une VM QEMU neuve comme premier étage", "en": "Create a fresh QEMU VM as level one", }, "Start from:": { "fr": "Partir de :", "en": "Start from:", }, "Start from another existing host": { "fr": "Partir d'un autre hôte existant", "en": "Start from another existing host", }, "Choice (1-3, default 1): ": { "fr": "Choix (1-3, défaut 1) : ", "en": "Choice (1-3, default 1): ", }, "Address (user@host, blank = cancel): ": { "fr": "Adresse (utilisateur@hôte, vide = annuler) : ", "en": "Address (user@host, blank = cancel): ", }, "Depth (default 3): ": { "fr": "Profondeur (défaut 3) : ", "en": "Depth (default 3): ", }, "Nesting level": { "fr": "Étage d'imbrication", "en": "Nesting level", }, "vendors document two, not more.": { "fr": "les fabricants en documentent deux, pas plus.", "en": "vendors document two, not more.", }, "Measured at level 4: 36x slower, then a frozen kernel.": { "fr": "Mesuré au niveau 4 : 36x plus lent, et 12 vCPU gelaient.", "en": "Measured at level 4: 36x slower, and 12 vCPU froze.", }, "vCPU capped to": { "fr": "vCPU borné à", "en": "vCPU capped to", }, "pve-cluster is down: /etc/pve is not mounted.": { "fr": "pve-cluster est à terre : /etc/pve n'est pas monté.", "en": "pve-cluster is down: /etc/pve is not mounted.", }, "Without it pvesm answers nothing, hence no storage.": { "fr": "Sans lui, pvesm ne répond rien — d'où l'absence de stockage.", "en": "Without it pvesm answers nothing, hence no storage.", }, "The hostname only resolves to": { "fr": "Le nom d'hôte ne résout que vers", "en": "The hostname only resolves to", }, "pmxcfs needs a routable address.": { "fr": "pmxcfs exige une adresse routable.", "en": "pmxcfs needs a routable address.", }, "cloud-init rewrites /etc/hosts at every boot.": { "fr": "cloud-init réécrit /etc/hosts à chaque démarrage.", "en": "cloud-init rewrites /etc/hosts at every boot.", }, "replay install_proxmox.sh on the host: it fixes /etc/hosts and stops cloud-init undoing it.": { "fr": "rejouer install_proxmox.sh sur l'hôte : il corrige /etc/hosts et empêche cloud-init de le défaire.", "en": "replay install_proxmox.sh on the host: it fixes /etc/hosts and stops cloud-init undoing it.", }, "The VM clones": { "fr": "La VM clone", "en": "The VM clones", }, "not this checkout.": { "fr": "et non ce checkout.", "en": "not this checkout.", }, "local commit(s) are missing there:": { "fr": "commit(s) local(aux) y manquent :", "en": "local commit(s) are missing there:", }, "to deploy your own work.": { "fr": "pour déployer votre propre travail.", "en": "to deploy your own work.", }, "No storage able to hold a VM disk.": { "fr": "Aucun stockage capable d'héberger un disque de VM.", "en": "No storage able to hold a VM disk.", }, "No NAT table on this host: the bridge would lead nowhere.": { "fr": "Pas de table NAT sur cet hôte : le pont ne mènerait nulle part.", "en": "No NAT table on this host: the bridge would lead nowhere.", }, "reboot it to boot the Proxmox kernel:": { "fr": "à redémarrer pour amorcer le noyau Proxmox :", "en": "reboot it to boot the Proxmox kernel:", }, "Rebooting to boot the new kernel": { "fr": "Redémarrage pour amorcer le nouveau noyau", "en": "Rebooting to boot the new kernel", }, "waiting for the machine to come back": { "fr": "attente du retour de la machine", "en": "waiting for the machine to come back", }, "kernel booted:": { "fr": "noyau amorcé :", "en": "kernel booted:", }, "the machine did not come back on the expected kernel:": { "fr": "la machine n'est pas revenue sur le noyau attendu :", "en": "the machine did not come back on the expected kernel:", }, "Running kernel:": { "fr": "Noyau en cours :", "en": "Running kernel:", }, "The distribution kernel carries no netfilter module.": { "fr": "Le noyau de la distribution ne porte aucun module netfilter.", "en": "The distribution kernel carries no netfilter module.", }, "Proxmox kernel installed:": { "fr": "Noyau Proxmox installé :", "en": "Proxmox kernel installed:", }, "taken at next boot": { "fr": "pris au prochain démarrage", "en": "taken at next boot", }, "then come back here.": { "fr": "puis revenir ici.", "en": "then come back here.", }, "No Proxmox kernel installed: finish the install first.": { "fr": "Aucun noyau Proxmox installé : terminer l'installation d'abord.", "en": "No Proxmox kernel installed: finish the install first.", }, "No free subnet left for an internal bridge.": { "fr": "Plus aucun réseau libre pour un pont interne.", "en": "No free subnet left for an internal bridge.", }, "No network bridge on this host.": { "fr": "Aucun pont réseau sur cet hôte.", "en": "No network bridge on this host.", }, # --- Écran de déploiement Proxmox VE (formulaire TUI) --- "Deploy one or more ERPLibre VMs on Proxmox VE!": { "fr": "Déployer une ou plusieurs VM ERPLibre sur Proxmox VE !", "en": "Deploy one or more ERPLibre VMs on Proxmox VE!", }, "Proxmox host": { "fr": "Hôte Proxmox", "en": "Proxmox host", }, "node": { "fr": "nœud", "en": "node", }, "Proxmox VE": { "fr": "Proxmox VE", "en": "Proxmox VE", }, "Bridge": { "fr": "Pont", "en": "Bridge", }, "First VMID": { "fr": "Premier VMID", "en": "First VMID", }, "Access": { "fr": "Accès", "en": "Access", }, "SSH public key": { "fr": "Clé publique SSH", "en": "SSH public key", }, "Start the VM after creating it": { "fr": "Démarrer la VM après sa création", "en": "Start the VM after creating it", }, "Add an entry to ~/.ssh/config": { "fr": "Ajouter une entrée à ~/.ssh/config", "en": "Add an entry to ~/.ssh/config", }, "Follow the installation (dashboard)": { "fr": "Suivre l'installation (tableau de bord)", "en": "Follow the installation (dashboard)", }, "Text prompts": { "fr": "Questions texte", "en": "Text prompts", }, "Nothing to deploy.": { "fr": "Rien à déployer.", "en": "Nothing to deploy.", }, "No bridge on the host.": { "fr": "Aucun pont sur l'hôte.", "en": "No bridge on the host.", }, "more disk than the storage has free": { "fr": "plus de disque que le stockage n'en a de libre", "en": "more disk than the storage has free", }, "more RAM than the host has free": { "fr": "plus de RAM que l'hôte n'en a de libre", "en": "more RAM than the host has free", }, "Loading (host, storage, bridges, VMs)...": { "fr": "Chargement (hôte, stockage, ponts, VM)…", "en": "Loading (host, storage, bridges, VMs)...", }, "TUI unavailable": { "fr": "Interface graphique indisponible", "en": "TUI unavailable", }, "VM": { "fr": "VM", "en": "VM", }, "VMID": { "fr": "VMID", "en": "VMID", }, "address": { "fr": "adresse", "en": "address", }, "storage": { "fr": "stockage", "en": "storage", }, "other…": { "fr": "autre…", "en": "other…", }, "offered": { "fr": "proposés", "en": "offered", }, "Would run on": { "fr": "Serait exécuté sur", "en": "Would run on", }, "SSH key ->": { "fr": "clé SSH ->", "en": "SSH key ->", }, "Deploy this VM now? (Y/n): ": { "fr": "Déployer cette VM maintenant ? (O/n) : ", "en": "Deploy this VM now? (Y/n): ", }, "SSH key unreadable:": { "fr": "Clé SSH illisible :", "en": "SSH key unreadable:", }, "SSH key not pushed: password login only.": { "fr": "Clé SSH non transmise : connexion par mot de passe seulement.", "en": "SSH key not pushed: password login only.", }, "Step failed, stopping here.": { "fr": "Étape en échec, on s'arrête ici.", "en": "Step failed, stopping here.", }, "Waiting for the VM address…": { "fr": "Attente de l'adresse de la VM…", "en": "Waiting for the VM address…", }, "No address yet. Try [6] later.": { "fr": "Pas encore d'adresse. Réessayer avec [6] plus tard.", "en": "No address yet. Try [6] later.", }, "Install ERPLibre on it? (Y/n): ": { "fr": "Y installer ERPLibre ? (O/n) : ", "en": "Install ERPLibre on it? (Y/n): ", }, "No address from the guest agent.": { "fr": "Aucune adresse rendue par l'agent invité.", "en": "No address from the guest agent.", }, "Is qemu-guest-agent installed and the VM started?": { "fr": "qemu-guest-agent est-il installé et la VM démarrée ?", "en": "Is qemu-guest-agent installed and the VM started?", }, "Ctrl+O to quit the serial console.": { "fr": "Ctrl+O pour quitter la console série.", "en": "Ctrl+O to quit the serial console.", }, "Proxmox can only GROW a disk, never shrink it.": { "fr": "Proxmox ne sait qu'AGRANDIR un disque, jamais le rétrécir.", "en": "Proxmox can only GROW a disk, never shrink it.", }, "This also destroys their disks and backups.": { "fr": "Cela détruit aussi leurs disques et leurs sauvegardes.", "en": "This also destroys their disks and backups.", }, "Nothing orphaned.": { "fr": "Rien d'orphelin.", "en": "Nothing orphaned.", }, "Orphan disks:": { "fr": "Disques orphelins :", "en": "Orphan disks:", }, "Free them?": { "fr": "Les libérer ?", "en": "Free them?", }, "no address, skipped": { "fr": "pas d'adresse, ignorée", "en": "no address, skipped", }, "unreachable from here.": { "fr": "injoignable d'ici.", "en": "unreachable from here.", }, "Use [13] to add a ProxyJump entry, then a tunnel.": { "fr": "Utiliser [13] pour l'entrée ProxyJump, puis un tunnel.", "en": "Use [13] to add a ProxyJump entry, then a tunnel.", }, "Example: demo-vm, Debian 13, on a Proxmox host": { "fr": "Exemple : demo-vm, Debian 13, sur un hôte Proxmox", "en": "Example: demo-vm, Debian 13, on a Proxmox host", }, "storages": { "fr": "stockages", "en": "storages", }, "memory": { "fr": "mémoire", "en": "memory", }, "No address for this VM.": { "fr": "Aucune adresse pour cette VM.", "en": "No address for this VM.", }, "A static address is visible right after creation.": { "fr": "Une adresse fixe est connue dès la création.", "en": "A static address is visible right after creation.", }, "address given at creation:": { "fr": "adresse donnée à la création :", "en": "address given at creation:", }, "qm create needs one. Two ways:": { "fr": "« qm create » en exige un. Deux voies :", "en": "qm create needs one. Two ways:", }, "create an internal": { "fr": "créer un pont interne", "en": "create an internal", }, "touches no physical NIC": { "fr": "ne touche à aucune interface physique", "en": "touches no physical NIC", }, "do it myself (bridge-ports , needs console)": { "fr": "le faire moi-même (bridge-ports , console requise)", "en": "do it myself (bridge-ports , needs console)", }, "To bridge the LAN, on the host:": { "fr": "Pour ponter le LAN, sur l'hôte :", "en": "To bridge the LAN, on the host:", }, "This moves the host address: do it from a console.": { "fr": "Cela déplace l'adresse de l'hôte : à faire depuis une console.", "en": "This moves the host address: do it from a console.", }, "uplink for NAT": {"fr": "sortie pour le NAT", "en": "uplink for NAT"}, "none": {"fr": "aucune", "en": "none"}, "The bridge did not come up.": { "fr": "Le pont n'est pas monté.", "en": "The bridge did not come up.", }, "SSH does not know this host key yet.": { "fr": "ssh ne connaît pas encore la clé de cet hôte.", "en": "SSH does not know this host key yet.", }, "Would record:": { "fr": "Enregistrerait :", "en": "Would record:", }, "Record it?": { "fr": "L'enregistrer ?", "en": "Record it?", }, "No host key obtained.": { "fr": "Aucune clé d'hôte obtenue.", "en": "No host key obtained.", }, "key(s) recorded in ~/.ssh/known_hosts": { "fr": "clé(s) enregistrée(s) dans ~/.ssh/known_hosts", "en": "key(s) recorded in ~/.ssh/known_hosts", }, "qm needs root: no root, and sudo asks for a password.": { "fr": "qm exige root : ni root, ni sudo sans mot de passe.", "en": "qm needs root: no root, and sudo asks for a password.", }, "Connect as root@, or allow NOPASSWD sudo.": { "fr": "Se connecter en root@, ou autoriser sudo sans mot de passe.", "en": "Connect as root@, or allow NOPASSWD sudo.", }, "Proxmox VE hypervisor (no Odoo)": { "fr": "Hyperviseur Proxmox VE (sans Odoo)", "en": "Proxmox VE hypervisor (no Odoo)", }, "Proxmox will NOT be installed: plain Debian VM.": { "fr": "Proxmox ne sera PAS installé : la VM restera une Debian nue.", "en": "Proxmox will NOT be installed: plain Debian VM.", }, "Later, in the VM:": { "fr": "Plus tard, dans la VM :", "en": "Later, in the VM:", }, "sshfs mount failed.": { "fr": "Le montage sshfs a échoué.", "en": "sshfs mount failed.", }, "Checking SSH access…": { "fr": "Vérification de l'accès SSH…", "en": "Checking SSH access…", }, "SSH reaches this host: ~/.ssh/config is fine.": { "fr": "SSH joint cet hôte : ~/.ssh/config est bon.", "en": "SSH reaches this host: ~/.ssh/config is fine.", }, "sshfs reads the « + » as host chaining.": { "fr": "sshfs lit le « + » comme un chaînage d'hôtes.", "en": "sshfs reads the « + » as host chaining.", }, "Run this instead:": { "fr": "À lancer plutôt :", "en": "Run this instead:", }, "ssh -G resolved nothing: check ~/.ssh/config.": { "fr": "« ssh -G » n'a rien résolu : vérifier ~/.ssh/config.", "en": "ssh -G resolved nothing: check ~/.ssh/config.", }, "Is sshfs (and fuse) installed here?": { "fr": "sshfs (et fuse) sont-ils installés ici ?", "en": "Is sshfs (and fuse) installed here?", }, "SSH fails too:": { "fr": "SSH échoue aussi :", "en": "SSH fails too:", }, "Update ~/.ssh/config, or check the server is up.": { "fr": "Mettre à jour ~/.ssh/config, ou vérifier que le serveur répond.", "en": "Update ~/.ssh/config, or check the server is up.", }, "Check the SSH host and that the server is up.": { "fr": "Vérifier l'hôte SSH saisi et que le serveur répond.", "en": "Check the SSH host and that the server is up.", }, "unknown host name: check HostName": { "fr": "nom d'hôte inconnu : vérifier HostName", "en": "unknown host name: check HostName", }, "no answer: is the server up and reachable?": { "fr": "aucune réponse : le serveur est-il allumé et joignable ?", "en": "no answer: is the server up and reachable?", }, "no route: check the network or the ProxyJump": { "fr": "pas de route : vérifier le réseau ou le ProxyJump", "en": "no route: check the network or the ProxyJump", }, "nothing listening on the SSH port": { "fr": "rien n'écoute sur le port SSH", "en": "nothing listening on the SSH port", }, "authentication refused: check User and key": { "fr": "authentification refusée : vérifier User et la clé", "en": "authentication refused: check User and key", }, "host key changed for this address": { "fr": "la clé d'hôte a changé pour cette adresse", "en": "host key changed for this address", }, "no statistics yet": { "fr": "pas encore de statistiques", "en": "no statistics yet", }, "10s average": { "fr": "moyenne 10 s", "en": "10s average", }, "total written": { "fr": "cumul écrit", "en": "total written", }, "Screens": { "fr": "Écrans", "en": "Screens", }, "bridge": { "fr": "pont", "en": "bridge", }, "this VM has no interface": { "fr": "cette VM n'a pas d'interface réseau", "en": "this VM has no interface", }, "CPU mode": { "fr": "Mode CPU", "en": "CPU mode", }, "no render node on the host": { "fr": "aucun nœud de rendu sur l'hôte", "en": "no render node on the host", }, "this VM has no virtual screen": { "fr": "cette VM n'a pas d'écran virtuel", "en": "this VM has no virtual screen", }, "Unknown VM(s):": { "fr": "VM inconnue(s) :", "en": "Unknown VM(s):", }, "Target state:": { "fr": "État cible :", "en": "Target state:", }, "Target environment?": { "fr": "Environnement cible ?", "en": "Target environment?", }, "Development (~/git/erplibre, SELinux relaxed)": { "fr": "Développement (~/git/erplibre, SELinux relâché)", "en": "Development (~/git/erplibre, SELinux relaxed)", }, "Production (/opt/erplibre, SELinux enforced)": { "fr": "Production (/opt/erplibre, SELinux confiné)", "en": "Production (/opt/erplibre, SELinux enforced)", }, "Choice (1-2, default 1): ": { "fr": "Choix (1-2, défaut 1) : ", "en": "Choice (1-2, default 1): ", }, "Open (start)": { "fr": "Ouvrir (démarrer)", "en": "Open (start)", }, "Close (shut down)": { "fr": "Fermer (éteindre)", "en": "Close (shut down)", }, "start": { "fr": "démarrer", "en": "start", }, "shut down": { "fr": "éteindre", "en": "shut down", }, "Apply:": { "fr": "Appliquer :", "en": "Apply:", }, "Confirm for real? (y/N): ": { "fr": "Confirmer pour de vrai ? (o/N) : ", "en": "Confirm for real? (y/N): ", }, "Storage": { "fr": "Stockage", "en": "Storage", }, "total": { "fr": "au total", "en": "total", }, "used": { "fr": "utilisés", "en": "used", }, "Enter +NG to grow, -NG to shrink, or NG for a target size " "(e.g. +20G, -10G, 60G).": { "fr": "Entrez +NG pour agrandir, -NG pour réduire, ou NG pour une " "taille cible (ex. +20G, -10G, 60G).", "en": "Enter +NG to grow, -NG to shrink, or NG for a target size " "(e.g. +20G, -10G, 60G).", }, "Resize: ": { "fr": "Redimensionner : ", "en": "Resize: ", }, "Invalid size.": { "fr": "Taille invalide.", "en": "Invalid size.", }, "No change.": { "fr": "Aucun changement.", "en": "No change.", }, "New virtual size:": { "fr": "Nouvelle taille virtuelle :", "en": "New virtual size:", }, "SHRINKING is DANGEROUS: the guest filesystem is NOT shrunk. " "Data beyond the new size is LOST. Shrink the guest FS FIRST, " "and only then shrink here.": { "fr": "RÉDUIRE est DANGEREUX : le système de fichiers invité n'est " "PAS réduit. Les données au-delà de la nouvelle taille sont PERDUES. " "Réduisez d'ABORD le FS invité, puis seulement ici.", "en": "SHRINKING is DANGEROUS: the guest filesystem is NOT shrunk. " "Data beyond the new size is LOST. Shrink the guest FS FIRST, " "and only then shrink here.", }, "Shut the VM off before shrinking (virsh shutdown).": { "fr": "Éteignez la VM avant de réduire (virsh shutdown).", "en": "Shut the VM off before shrinking (virsh shutdown).", }, "Type y to confirm you understand the risk (y/N): ": { "fr": "Tapez o pour confirmer que vous comprenez le risque " "(o/N, défaut : non) : ", "en": "Type y to confirm you understand the risk (y/N): ", }, "Resize failed (see error above).": { "fr": "Échec du redimensionnement (voir l'erreur ci-dessus).", "en": "Resize failed (see error above).", }, "Virtual disk resized.": { "fr": "Disque virtuel redimensionné.", "en": "Virtual disk resized.", }, "Grow the guest filesystem now (over SSH)? (y/N): ": { "fr": "Étendre le système de fichiers invité maintenant (via SSH) ? " "(o/N, défaut : non) : ", "en": "Grow the guest filesystem now (over SSH)? (y/N): ", }, "No IP; grow the guest FS manually once booted.": { "fr": "Pas d'IP ; étendez le FS invité manuellement après le boot.", "en": "No IP; grow the guest FS manually once booted.", }, "completed": { "fr": "terminées", "en": "completed", }, "deleted": { "fr": "effacée", "en": "deleted", }, "paused": { "fr": "pause", "en": "paused", }, "Waiting for the VM to start (boot + cloud-init)": { "fr": "En attente du démarrage de la VM (boot + cloud-init)", "en": "Waiting for the VM to start (boot + cloud-init)", }, "(an emulated architecture can be slow; this is normal)": { "fr": "(une architecture émulée peut être lente ; c'est normal)", "en": "(an emulated architecture can be slow; this is normal)", }, "VM ready - starting the ERPLibre install": { "fr": "VM prête — installation ERPLibre en cours", "en": "VM ready - starting the ERPLibre install", }, "Choice (number or name, blank = native):": { "fr": "Choix (numéro ou nom, vide = native) :", "en": "Choice (number or name, blank = native):", }, "Pick exact versions (comma-separated list)": { "fr": "Choisir des versions précises (liste séparée par des virgules)", "en": "Pick exact versions (comma-separated list)", }, "Selection (numbers, 'all', 'principal' or 'granulaire'," " default: all): ": { "fr": "Sélection (numéros, « all », « principal » ou « granulaire »," " défaut : all) : ", "en": "Selection (numbers, 'all', 'principal' or 'granulaire'," " default: all): ", }, "All versions:": { "fr": "Toutes les versions :", "en": "All versions:", }, "Selection (comma-separated numbers): ": { "fr": "Sélection (numéros séparés par des virgules) : ", "en": "Selection (comma-separated numbers): ", }, "s390x images only exist for:": { "fr": "images s390x disponibles seulement pour :", "en": "s390x images only exist for:", }, "ignored:": { "fr": "ignoré :", "en": "ignored:", }, "IBM Z — emulated, slow on x86": { "fr": "IBM Z — émulé, lent sur x86", "en": "IBM Z — emulated, slow on x86", }, "Choice (number or name, blank = amd64):": { "fr": "Choix (numéro ou nom, vide = amd64) :", "en": "Choice (number or name, blank = amd64):", }, "s390x is emulated (TCG): boot and install are much slower than x86.": { "fr": "s390x est émulé (TCG) : le boot et l'installation sont bien " "plus lents que x86.", "en": "s390x is emulated (TCG): boot and install are much " "slower than x86.", }, "Choice (number or version, blank = default):": { "fr": "Choix (numéro ou version, vide = défaut) :", "en": "Choice (number or version, blank = default):", }, "Invalid selection, using": { "fr": "Sélection invalide, utilisation de", "en": "Invalid selection, using", }, "select all": { "fr": "tout sélectionner", "en": "select all", }, "Delete VM(s)": { "fr": "🗑 Effacer une ou plusieurs VM", "en": "🗑 Delete VM(s)", }, "No VM found.": { "fr": "Aucune VM trouvée.", "en": "No VM found.", }, "Select VMs to delete:": { "fr": "Sélectionner les VM à effacer :", "en": "Select VMs to delete:", }, "Selection (numbers, or 'all'): ": { "fr": "Sélection (numéros, ou « all ») : ", "en": "Selection (numbers, or 'all'): ", }, "Also delete disk images (qcow2 + seed ISO)? (y/N): ": { "fr": "Effacer aussi les disques (qcow2 + seed ISO) ? (o/N, défaut : non) : ", "en": "Also delete disk images (qcow2 + seed ISO)? (y/N, default: no): ", }, "Will delete:": { "fr": "Sera effacé :", "en": "Will delete:", }, "disk images and seed ISOs": { "fr": "les disques et les seed ISO", "en": "disk images and seed ISOs", }, "disks kept": { "fr": "disques conservés", "en": "disks kept", }, "Confirm deletion? (y/N): ": { "fr": "Confirmer l'effacement ? (o/N, défaut : non) : ", "en": "Confirm deletion? (y/N, default: no): ", }, "Deletion done.": { "fr": "Effacement terminé.", "en": "Deletion done.", }, "Clean up QEMU (orphan files)": { "fr": "🧹 Nettoyer QEMU (fichiers orphelins)", "en": "🧹 Clean up QEMU (orphan files)", }, "Scanning for orphan QEMU files...": { "fr": "Recherche des fichiers QEMU orphelins...", "en": "Scanning for orphan QEMU files...", }, "orphan disk": { "fr": "disque orphelin", "en": "orphan disk", }, "orphan seed": { "fr": "seed orphelin", "en": "orphan seed", }, "partial download": { "fr": "téléchargement interrompu", "en": "partial download", }, "orphan UEFI nvram": { "fr": "nvram UEFI orpheline", "en": "orphan UEFI nvram", }, "No orphan files found.": { "fr": "Aucun fichier orphelin trouvé.", "en": "No orphan files found.", }, "Orphan files:": { "fr": "Fichiers orphelins :", "en": "Orphan files:", }, "connection guide written": { "fr": "guide de connexion écrit (/etc/motd)", "en": "connection guide written (/etc/motd)", }, "guide not written": { "fr": "guide non écrit", "en": "guide not written", }, "Quit (q) to start the ERPLibre install": { "fr": "Quitter (q) pour lancer l'installation d'ERPLibre", "en": "Quit (q) to start the ERPLibre install", }, "Quit (q) to follow the VM starting up": { "fr": "Quitter (q) pour suivre la mise en route de la VM", "en": "Quit (q) to follow the VM starting up", }, "This name is already taken by": { "fr": "Ce nom est déjà pris par", "en": "This name is already taken by", }, "a local VM": { "fr": "une VM locale", "en": "a local VM", }, "A local VM already bears this name:": { "fr": "Une VM locale porte déjà ce nom :", "en": "A local VM already bears this name:", }, "the alias goes to": { "fr": "l'alias devient", "en": "the alias goes to", }, "s ssh · c copy log · C copy all · q quit": { "fr": "s ssh · c copier le log · C copier tout · q quitter", "en": "s ssh · c copy log · C copy all · q quit", }, "No VM created yet.": { "fr": "Aucune VM créée pour l'instant.", "en": "No VM created yet.", }, # « models » manquait alors que ses trois voisines de la même ligne # étaient traduites : le rapport de qualité de migration sortait # « 42 modules · 812 models · 1 204 vues ». "models": { "fr": "modèles", "en": "models", }, "shutdown (clean)": { "fr": "éteindre (proprement)", "en": "shutdown (clean)", }, "stop (pulls the plug)": { "fr": "arrêter (coupe le courant)", "en": "stop (pulls the plug)", }, "Choice (blank = back): ": { "fr": "Choix (vide = retour) : ", "en": "Choice (blank = back): ", }, "Confirm? (y/N): ": { "fr": "Confirmer ? (o/N) : ", "en": "Confirm? (y/N): ", }, "Creating the bridge on the host…": { "fr": "Création du pont sur l'hôte…", "en": "Creating the bridge on the host…", }, "no disk file found for this VM": { "fr": "aucun fichier de disque trouvé pour cette VM", "en": "no disk file found for this VM", }, "a running process": { "fr": "un processus en cours", "en": "a running process", }, "Kept (still attached to a VM):": { "fr": "Conservés (encore attachés à une VM) :", "en": "Kept (still attached to a VM):", }, "Total:": { "fr": "Total :", "en": "Total:", }, "files": { "fr": "fichiers", "en": "files", }, "Delete these orphan files? (y/N): ": { "fr": "Effacer ces fichiers orphelins ? (o/N, défaut : non) : ", "en": "Delete these orphan files? (y/N, default: no): ", }, "Cleanup done.": { "fr": "Nettoyage terminé.", "en": "Cleanup done.", }, "Cached base images (reusable):": { "fr": "Images de base en cache (réutilisables) :", "en": "Cached base images (reusable):", }, "Also delete the cached base images? (y/N): ": { "fr": "Effacer aussi les images de base en cache ? (o/N, défaut : non) : ", "en": "Also delete the cached base images? (y/N, default: no): ", }, "All cached base images (reusable):": { "fr": "Toutes les images de base en cache (réutilisables) :", "en": "All cached base images (reusable):", }, "Delete ALL cached base images? (y/N): ": { "fr": "Effacer TOUTES les images de base en cache ? (o/N, défaut : non) : ", "en": "Delete ALL cached base images? (y/N, default: no): ", }, "Ghost domains (defined but disk missing):": { "fr": "Domaines fantômes (définis, disque manquant) :", "en": "Ghost domains (defined but disk missing):", }, "Undefine these ghost domains? (y/N): ": { "fr": "Supprimer la définition de ces domaines ? (o/N, défaut : non) : ", "en": "Undefine these ghost domains? (y/N, default: no): ", }, "Stale codename-named Ubuntu images (duplicates):": { "fr": "Images Ubuntu nommées par codename (doublons) :", "en": "Stale codename-named Ubuntu images (duplicates):", }, "Delete these duplicate images? (y/N): ": { "fr": "Effacer ces images en double ? (o/N, défaut : non) : ", "en": "Delete these duplicate images? (y/N, default: no): ", }, "its jump host is gone:": { "fr": "son rebond n'existe plus :", "en": "its jump host is gone:", }, "Orphan ~/.ssh/config entries:": { "fr": "Entrées ~/.ssh/config orphelines :", "en": "Orphan ~/.ssh/config entries:", }, "Kept (still leads somewhere):": { "fr": "Conservées (mènent encore quelque part) :", "en": "Kept (still leads somewhere):", }, "reached through a jump host": { "fr": "joignable par un rebond", "en": "reached through a jump host", }, "a VM of the Proxmox host": { "fr": "une VM de l'hôte Proxmox", "en": "a VM of the Proxmox host", }, "Remove these ~/.ssh/config entries? (y/N): ": { "fr": "Retirer ces entrées de ~/.ssh/config ? (o/N, défaut : non) : ", "en": "Remove these ~/.ssh/config entries? (y/N, default: no): ", }, "Stale DHCP leases (no matching VM):": { "fr": "Baux DHCP périmés (aucune VM correspondante) :", "en": "Stale DHCP leases (no matching VM):", }, "Clear these stale leases? (y/N): ": { "fr": "Effacer ces baux périmés ? (o/N, défaut : non) : ", "en": "Clear these stale leases? (y/N, default: no): ", }, "Deploy ERPLibre infra (one minimal VM per image)": { "fr": "Déployer l'infra ERPLibre (une VM minimale par image)", "en": "Deploy ERPLibre infra (one minimal VM per image)", }, "Deploy ERPLibre infra: one minimal VM per image": { "fr": "Déployer l'infra ERPLibre : une VM minimale par image", "en": "Deploy ERPLibre infra: one minimal VM per image", }, "Cannot load QEMU catalog: ": { "fr": "Impossible de charger le catalogue QEMU : ", "en": "Cannot load QEMU catalog: ", }, "Distributions:": { "fr": "Distributions :", "en": "Distributions:", }, "Whole catalog (every version)": { "fr": "Tout le catalogue (chaque version)", "en": "Whole catalog (every version)", }, "The main version of each distro (marked *)": { "fr": "La version principale de chaque distro (marquée *)", "en": "The main version of each distro (marked *)", }, "Selection (numbers, 'all' or 'principal', default: all): ": { "fr": "Sélection (numéros, « all » ou « principal », défaut : all) : ", "en": "Selection (numbers, 'all' or 'principal', default: all): ", }, "Selection (numbers, or 'all', default: all): ": { "fr": "Sélection (numéros, ou « all », défaut : all) : ", "en": "Selection (numbers, or 'all', default: all): ", }, "Nothing selected.": { "fr": "Rien de sélectionné.", "en": "Nothing selected.", }, "Deployment plan": { "fr": "Plan de déploiement", "en": "Deployment plan", }, "disk": { "fr": "disque", "en": "disk", }, "Total RAM (all running):": { "fr": "RAM totale (toutes actives) :", "en": "Total RAM (all running):", }, "Total virtual disk (thin qcow2):": { "fr": "Disque virtuel total (qcow2 thin) :", "en": "Total virtual disk (thin qcow2):", }, "Host RAM available:": { "fr": "RAM disponible de l'hôte :", "en": "Host RAM available:", }, "Total RAM exceeds host free RAM: not all VMs will run at once.": { "fr": "La RAM totale dépasse la RAM libre de l'hôte : les VM ne " "tourneront pas toutes en même temps.", "en": "Total RAM exceeds host free RAM: not all VMs will run at once.", }, "Install ERPLibre into ~/git/erplibre on each VM? (Y/n): ": { "fr": "Installer ERPLibre dans ~/git/erplibre sur chaque VM ? " "(O/n, défaut : oui) : ", "en": "Install ERPLibre into ~/git/erplibre on each VM? " "(Y/n, default: yes): ", }, "Deploy these VMs now? (Y/n): ": { "fr": "Déployer ces VM maintenant ? (O/n, défaut : oui) : ", "en": "Deploy these VMs now? (Y/n, default: yes): ", }, "Discard everything and start over? (y/N): ": { "fr": "Tout abandonner et recommencer ? (o/N, défaut : non) : ", "en": "Discard everything and start over? (y/N, default: no): ", }, "Final review before deployment": { "fr": "Récapitulatif final avant déploiement", "en": "Final review before deployment", }, "VMs to create:": { "fr": "VM à créer :", "en": "VMs to create:", }, "Existing, left untouched:": { "fr": "Existantes, laissées intactes :", "en": "Existing, left untouched:", }, # Renommée : la case commande TOUTE installation — ERPLibre, Odoo, mais # aussi l'hyperviseur Proxmox VE, qui n'installe ni l'un ni l'autre. "Install:": { "fr": "Installation :", "en": "Install:", }, "Install software in the VM": { "fr": "Installer un logiciel dans la VM", "en": "Install software in the VM", }, "Installation": { "fr": "Installation", "en": "Installation", }, "Monitoring and parallelism": { "fr": "Suivi et parallélisme", "en": "Monitoring and parallelism", }, "profile": { "fr": "profil", "en": "profile", }, "branch": { "fr": "branche", "en": "branch", }, "production (/opt, confined)": { "fr": "production (/opt, confiné)", "en": "production (/opt, confined)", }, "development (~/git)": { "fr": "développement (~/git)", "en": "development (~/git)", }, "no": { "fr": "non", "en": "no", }, "SSH key:": { "fr": "Clé SSH :", "en": "SSH key:", }, "~/.ssh/config:": { "fr": "~/.ssh/config :", "en": "~/.ssh/config:", }, "one entry per VM": { "fr": "une entrée par VM", "en": "one entry per VM", }, "untouched": { "fr": "inchangé", "en": "untouched", }, "Parallelism:": { "fr": "Parallélisme :", "en": "Parallelism:", }, "at a time": { "fr": "à la fois", "en": "at a time", }, "Nothing to create - every VM already exists.": { "fr": "Rien à créer — toutes les VM existent déjà.", "en": "Nothing to create — every VM already exists.", }, "Name collisions detected": { "fr": "Collisions de noms détectées", "en": "Name collisions detected", }, "VM already defined - SKIPPED, nothing overwritten": { "fr": "VM déjà définie — IGNORÉE, rien ne sera écrasé", "en": "VM already defined — SKIPPED, nothing overwritten", }, "disk present without VM - deployment will FAIL": { "fr": "disque présent sans VM — le déploiement ÉCHOUERA", "en": "disk present without VM - deployment will FAIL", }, "Remove it by hand, or rename the VM.": { "fr": "L'effacer à la main, ou renommer la VM.", "en": "Remove it by hand, or rename the VM.", }, "Continue despite these collisions? (y/N): ": { "fr": "Continuer malgré ces collisions ? (o/N, défaut : non) : ", "en": "Continue despite these collisions? (y/N, default: no): ", }, "Resolving VM IPs (parallel, emulated boot is slow)...": { "fr": "Résolution des IP des VM (en parallèle, le démarrage émulé " "est lent)...", "en": "Resolving VM IPs (parallel, emulated boot is slow)...", }, "no IP": { "fr": "pas d'IP", "en": "no IP", }, "Cloning ERPLibre on each VM": { "fr": "Clonage d'ERPLibre sur chaque VM", "en": "Cloning ERPLibre on each VM", }, "per VM": { "fr": "par VM", "en": "per VM", }, "Installing ERPLibre on each VM": { "fr": "Installation d'ERPLibre sur chaque VM", "en": "Installing ERPLibre on each VM", }, "Install ERPLibre into ~/git/erplibre on this VM? (y/N): ": { "fr": "Installer ERPLibre dans ~/git/erplibre sur cette VM ? (o/N, défaut : non) : ", "en": "Install ERPLibre into ~/git/erplibre on this VM? (y/N, default: no): ", }, "installing ERPLibre": { "fr": "installation d'ERPLibre", "en": "installing ERPLibre", }, "no IP obtained, ERPLibre install skipped.": { "fr": "aucune IP obtenue, installation ERPLibre ignorée.", "en": "no IP obtained, ERPLibre install skipped.", }, "waiting for SSH...": { "fr": "attente du SSH...", "en": "waiting for SSH...", }, "SSH not reachable, ERPLibre install skipped.": { "fr": "SSH injoignable, installation ERPLibre ignorée.", "en": "SSH not reachable, ERPLibre install skipped.", }, "What to install on the VM(s)?": { "fr": "Que veut-on installer sur la/les VM ?", "en": "What to install on the VM(s)?", }, "Choice (number, blank = Odoo 18): ": { "fr": "Choix (numéro, vide = Odoo 18) : ", "en": "Choice (number, blank = Odoo 18): ", }, "ERPLibre + all Odoo versions": { "fr": "ERPLibre + toutes les versions Odoo", "en": "ERPLibre + all Odoo versions", }, "ERPLibre only (no Odoo)": { "fr": "ERPLibre seulement (sans Odoo)", "en": "ERPLibre only (no Odoo)", }, "ERPLibre mobile (home)": { "fr": "ERPLibre mobile (home)", "en": "ERPLibre mobile (home)", }, "ERPLibre Deployment (+ QEMU + dev)": { "fr": "ERPLibre Déploiement (+ QEMU + dev)", "en": "ERPLibre Deployment (+ QEMU + dev)", }, "Interactive monitoring dashboard? (y/N): ": { "fr": "Suivi interactif (dashboard) ? (O/n, défaut : oui) : ", "en": "Interactive monitoring dashboard? (Y/n, default: yes): ", }, "resolving IP...": { "fr": "résolution de l'IP...", "en": "resolving IP...", }, "no IP, skipped.": { "fr": "pas d'IP, ignorée.", "en": "no IP, skipped.", }, "No VM to install.": { "fr": "Aucune VM à installer.", "en": "No VM to install.", }, "Opening the interactive monitor...": { "fr": "Ouverture du suivi interactif...", "en": "Opening the interactive monitor...", }, "Monitor closed. Installs keep running in the background.": { "fr": "Suivi fermé. Les installations continuent en arrière-plan.", "en": "Monitor closed. Installs keep running in the background.", }, "Logs:": { "fr": "Logs :", "en": "Logs:", }, "3D was on; retry without it:": { "fr": "La 3D était active ; réessayer sans elle :", "en": "3D was on; retry without it:", }, "Recommended before installing:": { "fr": "Recommandé avant d'installer :", "en": "Recommended before installing:", }, "Grant libvirt access, or every VM command will": { "fr": "Donner l'accès à libvirt, sinon chaque commande VM", "en": "Grant libvirt access, or every VM command will", }, "ask for a sudo password:": { "fr": "demandera un mot de passe sudo :", "en": "ask for a sudo password:", }, "then log out and back in.": { "fr": "puis se déconnecter et se reconnecter.", "en": "then log out and back in.", }, "Orphan disks that would fail the deployment": { "fr": "Disques orphelins qui feraient échouer le déploiement", "en": "Orphan disks that would fail the deployment", }, "Delete them and continue? (y/N): ": { "fr": "Les effacer et continuer ? (o/N) : ", "en": "Delete them and continue? (y/N, default: no): ", }, "Kept - the deployment of these VMs will FAIL:": { "fr": "Conservés — le déploiement de ces VM ÉCHOUERA :", "en": "Kept - the deployment of these VMs will FAIL:", }, "3D acceleration (host GPU), even without a screen": { "fr": "Accélération 3D (GPU de l'hôte), même sans écran", "en": "3D acceleration (host GPU), even without a screen", }, "3D acceleration (host GPU), even without a screen? (y/N): ": { "fr": "Accélération 3D (GPU de l'hôte), même sans écran ? (o/N) : ", "en": ( "3D acceleration (host GPU), even without a screen?" " (y/N, default: no): " ), }, # Récupération de fichiers dans le disque d'une VM (libguestfs) # Outils d'assistance posés dans une VM au déploiement. "AI coding tools": { "fr": "Outils d'assistance IA", "en": "AI coding tools", }, # Ce qu'il faut savoir de l'image d'une VM, dit avant de la créer. "%s: image rebuilt by a third party, not published by the distribution": { "fr": ( "%s : image reconstruite par un tiers, non publiée par la" " distribution" ), "en": ( "%s: image rebuilt by a third party, not published by the" " distribution" ), }, "release pinned to %s, sha256 fixed in the repository": { "fr": "release épinglée sur %s, sha256 figée dans le dépôt", "en": "release pinned to %s, sha256 fixed in the repository", }, # Pourquoi le déploiement demande un mot de passe, dit AVANT l'invite. "sudo password: asked when the deployment starts": { "fr": "Mot de passe sudo : demandé au lancement du déploiement, pour", "en": "sudo password: asked when the deployment starts, for", }, "write into %s — checked: %s %s, writing refused here": { "fr": "écrire dans %s — vérifié : %s %s, écriture refusée ici", "en": "write into %s — checked: %s %s, writing refused here", }, "the libvirt group opens the qemu:///system socket, not this directory": { "fr": ( "le groupe libvirt ouvre la socket qemu:///system, pas ce" " répertoire" ), "en": ( "the libvirt group opens the qemu:///system socket, not this" " directory" ), }, "the system steps of the script (service, group)": { "fr": "les gestes système du script (service, groupe)", "en": "the system steps of the script (service, group)", }, "the libvirt socket does not answer without sudo either: group absent" " from this session, or libvirt not started": { "fr": ( "la socket libvirt ne répond pas non plus sans sudo : groupe" " absent de cette session, ou libvirt pas démarré" ), "en": ( "the libvirt socket does not answer without sudo either: group" " absent from this session, or libvirt not started" ), }, "Python IDE, opens the ERPLibre checkout": { "fr": "IDE Python, ouvre le dépôt ERPLibre", "en": "Python IDE, opens the ERPLibre checkout", }, "rtk, starship, one agent, git and Claude ready": { "fr": "rtk, starship, un agent, git et Claude prêts", "en": "rtk, starship, one agent, git and Claude ready", }, # Nix posé dans une VM qui n'est pas NixOS, et l'installateur qui porte # NixOS sur une autre machine. "nix + nixos-anywhere": { "fr": "nix + nixos-anywhere", "en": "nix + nixos-anywhere", }, "nix, flakes, and nixos-anywhere to install NixOS elsewhere": { "fr": "nix, flakes et nixos-anywhere pour installer NixOS ailleurs", "en": "nix, flakes, and nixos-anywhere to install NixOS elsewhere", }, "the official multi-user installer, nix as a daemon": { "fr": "l'installateur officiel multi-utilisateur, nix en démon", "en": "the official multi-user installer, nix as a daemon", }, "experimental-features: nix-command and flakes": { "fr": "experimental-features : nix-command et flakes", "en": "experimental-features: nix-command and flakes", }, "nixos-anywhere, by nix profile install": { "fr": "nixos-anywhere, par nix profile install", "en": "nixos-anywhere, by nix profile install", }, "it installs NixOS on any machine reachable over SSH": { "fr": "il installe NixOS sur toute machine joignable en SSH", "en": "it installs NixOS on any machine reachable over SSH", }, "nixos-anywhere ready": { "fr": "nixos-anywhere prêt", "en": "nixos-anywhere ready", }, "nixos-anywhere missing, see the log above": { "fr": "nixos-anywhere absent, voir le journal ci-dessus", "en": "nixos-anywhere missing, see the log above", }, "Help": { "fr": "Aide", "en": "Help", }, "What each option installs": { "fr": "Ce que chaque option installe", "en": "What each option installs", }, "(F1 or ? : details)": { "fr": "(F1 ou ? : le détail)", "en": "(F1 or ? : details)", }, "VM type": { "fr": "Type de VM", "en": "VM type", }, "Application store": { "fr": "Magasin d'applications", "en": "Application store", }, "Python interpreter": { "fr": "Interpréteur Python", "en": "Python interpreter", }, "clone of the checkout, then the make target of the profile": { "fr": "clone du dépôt, puis la cible make du profil", "en": "clone of the checkout, then the make target of the profile", }, "in ~/git/erplibre, or /opt/erplibre in production": { "fr": "dans ~/git/erplibre, ou /opt/erplibre en production", "en": "in ~/git/erplibre, or /opt/erplibre in production", }, "unchecked: the VM stays a bare distribution": { "fr": "décochée : la VM reste une distribution nue", "en": "unchecked: the VM stays a bare distribution", }, "about +5 Go of disk": { "fr": "environ +5 Go de disque", "en": "about +5 Go of disk", }, "/opt/erplibre instead of ~/git/erplibre": { "fr": "/opt/erplibre au lieu de ~/git/erplibre", "en": "/opt/erplibre instead of ~/git/erplibre", }, "Odoo registered as a systemd service": { "fr": "Odoo enregistré en service systemd", "en": "Odoo registered as a systemd service", }, "automatic updates left ON, unlike a dev VM": { "fr": "mises à jour automatiques laissées ACTIVES, contrairement au dev", "en": "automatic updates left ON, unlike a dev VM", }, "server: SSH only, no graphical session": { "fr": "serveur : SSH seul, sans session graphique", "en": "server: SSH only, no graphical session", }, "graphical: the chosen desktop plus its remote access": { "fr": "graphique : le bureau choisi et son accès distant", "en": "graphical: the chosen desktop plus its remote access", }, "an IDE needs a desktop, the build tools do not": { "fr": "un IDE demande un bureau, les outils de compilation non", "en": "an IDE needs a desktop, the build tools do not", }, "deb/rpm: packages of the distribution only": { "fr": "deb/rpm : les paquets de la distribution seulement", "en": "deb/rpm: packages of the distribution only", }, "snap: snapd kept active where the distribution has it": { "fr": "snap : snapd laissé actif là où la distribution l'a", "en": "snap: snapd kept active where the distribution has it", }, "IANA name written by cloud-init at first boot": { "fr": "nom IANA écrit par cloud-init au premier démarrage", "en": "IANA name written by cloud-init at first boot", }, "a misspelled name is IGNORED: the VM stays in UTC": { "fr": "un nom mal orthographié est IGNORÉ : la VM reste en UTC", "en": "a misspelled name is IGNORED: the VM stays in UTC", }, "mise poses a precompiled CPython, in minutes": { "fr": "mise pose un CPython précompilé, en quelques minutes", "en": "mise poses a precompiled CPython, in minutes", }, "pyenv compiles it, which is much longer": { "fr": "pyenv le compile, ce qui est bien plus long", "en": "pyenv compiles it, which is much longer", }, "mise publishes no binary for every architecture": { "fr": "mise ne publie pas de binaire pour toutes les architectures", "en": "mise publishes no binary for every architecture", }, "JetBrains archive in /opt, launcher /usr/local/bin/pycharm": { "fr": "archive JetBrains dans /opt, lanceur /usr/local/bin/pycharm", "en": "JetBrains archive in /opt, launcher /usr/local/bin/pycharm", }, "the checkout as project, .idea written like pycharm_configure": { "fr": "le dépôt comme projet, .idea écrit comme pycharm_configure", "en": "the checkout as project, .idea written like pycharm_configure", }, "Android Studio in /opt, desktop launcher and studio command": { "fr": "Android Studio dans /opt, lanceur de bureau et commande studio", "en": "Android Studio in /opt, desktop launcher and studio command", }, "x86_64 only: Google publishes no other build": { "fr": "x86_64 seulement : Google n'en publie pas d'autre", "en": "x86_64 only: Google publishes no other build", }, "the extension manager, plus the suggested extensions": { "fr": "le gestionnaire d'extensions, et les extensions suggérées", "en": "the extension manager, plus the suggested extensions", }, "distribution packages installed without being enabled": { "fr": "les paquets de la distribution posés sans être activés", "en": "distribution packages installed without being enabled", }, "extensions named by UUID are enabled": { "fr": "les extensions nommées par leur UUID sont activées", "en": "extensions named by UUID are enabled", }, "Android SDK, then the debug APK and the Vitest run": { "fr": "le SDK Android, puis l'APK debug et la passe Vitest", "en": "Android SDK, then the debug APK and the Vitest run", }, "a failed build marks the VM as failed": { "fr": "une compilation en échec fait échouer la VM", "en": "a failed build marks the VM as failed", }, "git forge on port 3000, SQLite database": { "fr": "forge git sur le port 3000, base SQLite", "en": "git forge on port 3000, SQLite database", }, "system account, systemd service, admin account": { "fr": "compte système, service systemd, compte administrateur", "en": "system account, systemd service, admin account", }, "posed by script/forgejo/install_forgejo.sh": { "fr": "posé par script/forgejo/install_forgejo.sh", "en": "posed by script/forgejo/install_forgejo.sh", }, "tig, htop and vim": { "fr": "tig, htop et vim", "en": "tig, htop and vim", }, "rtk, plus its global auto-rewrite hook": { "fr": "rtk, et son hook global de réécriture", "en": "rtk, plus its global auto-rewrite hook", }, "starship, hooked into ~/.bashrc": { "fr": "starship, accroché au ~/.bashrc", "en": "starship, hooked into ~/.bashrc", }, "the chosen agent: Claude Code or opencode": { "fr": "l'agent choisi : Claude Code ou opencode", "en": "the chosen agent: Claude Code or opencode", }, "git: merge.conflictStyle zdiff3, core.editor vim if unset": { "fr": "git : merge.conflictStyle zdiff3, core.editor vim s'il est vide", "en": "git: merge.conflictStyle zdiff3, core.editor vim if unset", }, "git hooks of the checkout: commit-msg, pre-commit": { "fr": "les hooks git du dépôt : commit-msg, pre-commit", "en": "git hooks of the checkout: commit-msg, pre-commit", }, "the Claude commands: /commit, /git_prepare_merge, /todo_*": { "fr": "les commandes Claude : /commit, /git_prepare_merge, /todo_*", "en": "the Claude commands: /commit, /git_prepare_merge, /todo_*", }, "source .venv.erplibre/bin/activate in the shell history": { "fr": "source .venv.erplibre/bin/activate dans l'historique du shell", "en": "source .venv.erplibre/bin/activate in the shell history", }, "Android SDK, then a Pixel AVD named erplibre": { "fr": "le SDK Android, puis un AVD Pixel nommé erplibre", "en": "Android SDK, then a Pixel AVD named erplibre", }, "software rendering: it opens over ssh -X": { "fr": "rendu logiciel : il s'ouvre par ssh -X", "en": "software rendering: it opens over ssh -X", }, "needs nested virtualization on the host": { "fr": "demande la virtualisation imbriquée sur l'hôte", "en": "needs nested virtualization on the host", }, "AI coding tools, pre-configuration": { "fr": "Outils d'assistance IA, pré-configuration", "en": "AI coding tools, pre-configuration", }, "no checkout: git hooks and Claude commands skipped": { "fr": "sans dépôt : hooks git et commandes Claude sautés", "en": "no checkout: git hooks and Claude commands skipped", }, "Name for git": { "fr": "Nom pour git", "en": "Name for git", }, "Email for git": { "fr": "Courriel pour git", "en": "Email for git", }, "3D per VM": { "fr": "3D par VM", "en": "3D per VM", }, "no video device": { "fr": "aucun périphérique vidéo", "en": "no video device", }, "not pinned": { "fr": "non figé", "en": "not pinned", }, "non-GL device pinned: 3D will not start": { "fr": "device sans GL figé : la 3D ne démarrera pas", "en": "non-GL device pinned: 3D will not start", }, "To unpin, VM stopped:": { "fr": "Pour défiger, la VM arrêtée :", "en": "To unpin, VM stopped:", }, # Une VM dont libvirt a figé le device vidéo sur une variante sans GL # tourne sans 3D, même avec « accel3d=yes » dans sa définition. "frozen on": { "fr": "figée sur", "en": "frozen on", }, "Recover files from a VM disk (libguestfs)": { "fr": "💾 Récupérer des fichiers dans le disque d'une VM (libguestfs)", "en": "💾 Recover files from a VM disk (libguestfs)", }, "guestfish is missing: libguestfs is not here.": { "fr": "guestfish est absent : libguestfs n'est pas installé ici.", "en": "guestfish is missing: libguestfs is not here.", }, "Some libguestfs helpers are missing:": { "fr": "Des utilitaires libguestfs manquent :", "en": "Some libguestfs helpers are missing:", }, "Unknown package manager: install libguestfs.": { "fr": "Gestionnaire de paquets inconnu : installez libguestfs.", "en": "Unknown package manager: install libguestfs.", }, "Install libguestfs now? (Y/n): ": { "fr": "Installer libguestfs maintenant ? (O/n) : ", "en": "Install libguestfs now? (Y/n, default: yes): ", }, "This VM is running.": { "fr": "Cette VM est allumée.", "en": "This VM is running.", }, "Reading a live disk sees a possibly torn state:": { "fr": "Lire un disque vivant montre un état peut-être incohérent :", "en": "Reading a live disk sees a possibly torn state:", }, "a half-written file, an unreplayed journal.": { "fr": "un fichier à moitié écrit, un journal non rejoué.", "en": "a half-written file, an unreplayed journal.", }, "Read anyway (read-only, no risk for the VM)": { "fr": "Lire quand même (lecture seule, sans risque pour la VM)", "en": "Read anyway (read-only, no risk for the VM)", }, "Shut the VM down cleanly, then read": { "fr": "Éteindre proprement la VM, puis lire", "en": "Shut the VM down cleanly, then read", }, "No filesystem found on this disk.": { "fr": "Aucun système de fichiers trouvé sur ce disque.", "en": "No filesystem found on this disk.", }, "Filesystem to mount": { "fr": "Système de fichiers à monter", "en": "Filesystem to mount", }, "Empty or unreadable directory.": { "fr": "Répertoire vide ou illisible.", "en": "Empty or unreadable directory.", }, "Cannot create the destination: ": { "fr": "Impossible de créer la destination : ", "en": "Cannot create the destination: ", }, "Extraction failed.": { "fr": "L'extraction a échoué.", "en": "Extraction failed.", }, "Extracted to: ": { "fr": "Extrait vers : ", "en": "Extracted to: ", }, "Partitions and sizes": { "fr": "Partitions et tailles", "en": "Partitions and sizes", }, "Free space per filesystem": { "fr": "Espace libre par système de fichiers", "en": "Free space per filesystem", }, "Detected operating system": { "fr": "Système d'exploitation détecté", "en": "Detected operating system", }, "Does the libguestfs appliance boot?": { "fr": "L'appliance libguestfs démarre-t-elle ?", "en": "Does the libguestfs appliance boot?", }, "No disk found for this VM.": { "fr": "Aucun disque trouvé pour cette VM.", "en": "No disk found for this VM.", }, "Disk:": { "fr": "Disque :", "en": "Disk:", }, "Run the diagnostics first? (y/N): ": { "fr": "Lancer d'abord les diagnostics ? (o/N) : ", "en": "Run the diagnostics first? (y/N, default: no): ", }, "Directory to list [/]: ": { "fr": "Répertoire à lister [/] : ", "en": "Directory to list [/]: ", }, "Another directory, or Enter to extract: ": { "fr": "Autre répertoire, ou Entrée pour extraire : ", "en": "Another directory, or Enter to extract: ", }, "Path to extract": { "fr": "Chemin à extraire", "en": "Path to extract", }, "Destination on the host": { "fr": "Destination sur l'hôte", "en": "Destination on the host", }, "EGL does not start on this host GPU.": { "fr": "EGL ne démarre pas sur le GPU de cet hôte.", "en": "EGL does not start on this host GPU.", }, "The VM cannot boot while 3D stays in its definition.": { "fr": ( "La VM ne démarrera pas tant que la 3D reste dans sa définition." ), "en": "The VM cannot boot while 3D stays in its definition.", }, "Remove the 3D and start again? (Y/n): ": { "fr": "Retirer la 3D et redémarrer ? (O/n) : ", "en": "Remove the 3D and start again? (Y/n, default: yes): ", }, "3D on this host": { "fr": "La 3D sur cet hôte", "en": "3D on this host", }, "Render node:": { "fr": "Nœud de rendu :", "en": "Render node:", }, "Check EGL itself on that node:": { "fr": "Vérifier EGL lui-même sur ce nœud :", "en": "Check EGL itself on that node:", }, "VM access": { "fr": "🔌 Accès aux VM", "en": "🔌 VM access", }, # Menu QEMU — section « Réseau » "VM network": { "fr": "🌐 Réseau", "en": "🌐 Network", }, "Show the libvirt network state": { "fr": "🌐 Voir l'état du réseau libvirt (sous-réseau, VM, baux)", "en": "🌐 Show the libvirt network state (subnet, VMs, leases)", }, "Recreate the VM subnet (stop, redefine, restart)": { "fr": "♻️ Recréer le sous-réseau des VM (arrêter, redéfinir, relancer)", "en": "♻️ Recreate the VM subnet (stop, redefine, restart)", }, "Recreating the subnet does three things:": { "fr": "Recréer le sous-réseau fait trois choses :", "en": "Recreating the subnet does three things:", }, "shut down the VMs attached to the network": { "fr": "arrêter les VM attachées au réseau", "en": "shut down the VMs attached to the network", }, "redefine the network on the wanted prefix": { "fr": "redéfinir le réseau sur le préfixe voulu", "en": "redefine the network on the wanted prefix", }, "start those same VMs again": { "fr": "redémarrer ces mêmes VM", "en": "start those same VMs again", }, "Target prefix": { "fr": "Préfixe visé", "en": "Target prefix", }, "libvirt network": { "fr": "Réseau libvirt", "en": "libvirt network", }, "Power off VMs that ignore the shutdown? (y/N): ": { "fr": "Couper le courant des VM qui n'obéissent pas ? (o/N) : ", "en": "Power off VMs that ignore the shutdown? (y/N): ", }, "Troubleshoot": { "fr": "🩺 Dépanner", "en": "🩺 Troubleshoot", }, "Diagnostics (report to share)": { "fr": "🩺 Diagnostic (rapport à transmettre)", "en": "🩺 Diagnostics (report to share)", }, "Collecting the diagnostics...": { "fr": "Relevé du diagnostic en cours…", "en": "Collecting the diagnostics...", }, "Cannot write the report: ": { "fr": "Impossible d'écrire le rapport : ", "en": "Cannot write the report: ", }, "Report written to: ": { "fr": "Rapport écrit dans : ", "en": "Report written to: ", }, "It names this host, its paths and its addresses.": { "fr": "Il nomme cette machine, ses chemins et ses adresses.", "en": "It names this host, its paths and its addresses.", }, "Read it before sharing it.": { "fr": "Relisez-le avant de le transmettre.", "en": "Read it before sharing it.", }, "These tools would complete the report:": { "fr": "Ces outils compléteraient le rapport :", "en": "These tools would complete the report:", }, "unknown package manager": { "fr": "gestionnaire de paquets inconnu", "en": "unknown package manager", }, "Install them now? (y/N): ": { "fr": "Les installer maintenant ? (o/N) : ", "en": "Install them now? (y/N, default: no): ", }, "Run the diagnostics again for a fuller report.": { "fr": "Relancez le diagnostic pour un rapport plus complet.", "en": "Run the diagnostics again for a fuller report.", }, "Devices QEMU may open": { "fr": "Périphériques que QEMU peut ouvrir", "en": "Devices QEMU may open", }, "Unreadable, so this may already be set:": { "fr": "Illisible, donc peut-être déjà réglé :", "en": "Unreadable, so this may already be set:", }, "A list exists: ADD to it, never replace it.": { "fr": "Une liste existe : y AJOUTER, ne jamais la remplacer.", "en": "A list exists: ADD to it, never replace it.", }, "In": { "fr": "Dans", "en": "In", }, "Then restart the daemon and recreate the VM:": { "fr": "Puis redémarrer le démon et recréer la VM :", "en": "Then restart the daemon and recreate the VM:", }, "then stop and start the VM (a guest reboot is not": { "fr": "puis éteindre et rallumer la VM (un redémarrage de", "en": "then stop and start the VM (a guest reboot is not", }, "enough: the list applies when QEMU is launched).": { "fr": "l'invité ne suffit pas : la liste s'applique au lancement).", "en": "enough: the list applies when QEMU is launched).", }, "package": { "fr": "paquet", "en": "package", }, "Will run, as root:": { "fr": "Va exécuter, en root :", "en": "Will run, as root:", }, "Full output:": { "fr": "Sortie complète :", "en": "Full output:", }, "Read the logs:": { "fr": "Lire les logs :", "en": "Read the logs:", }, "Log files:": { "fr": "Fichiers de log :", "en": "Log files:", }, "Parallel deployments (default:": { "fr": "Déploiements en parallèle (défaut :", "en": "Parallel deployments (default:", }, "VMs": { "fr": "VM", "en": "VMs", }, "Deploy summary:": { "fr": "Bilan déploiement :", "en": "Deploy summary:", }, "IPs resolved:": { "fr": "IP résolues :", "en": "IPs resolved:", }, "still waiting for": { "fr": "encore en attente de", "en": "still waiting for", }, "TOTAL summary": { "fr": "Sommaire TOTAL", "en": "TOTAL summary", }, "VMs deployed:": { "fr": "VM déployées :", "en": "VMs deployed:", }, "total incl. existing:": { "fr": "total avec existantes :", "en": "total incl. existing:", }, "Total time:": { "fr": "Temps total :", "en": "Total time:", }, "Deploying": { "fr": "Déploiement de", "en": "Deploying", }, "parallel jobs:": { "fr": "tâches parallèles :", "en": "parallel jobs:", }, "ERPLibre infra deployment done.": { "fr": "Déploiement de l'infra ERPLibre terminé.", "en": "ERPLibre infra deployment done.", }, "Manage with:": { "fr": "Gérer avec :", "en": "Manage with:", }, "Fetching ERPLibre branch list...": { "fr": "Récupération de la liste des branches ERPLibre...", "en": "Fetching ERPLibre branch list...", }, "Branch (default:": { "fr": "Branche (défaut :", "en": "Branch (default:", }, "Branches:": { "fr": "Branches :", "en": "Branches:", }, "Choice (number or name, default:": { "fr": "Choix (numéro ou nom, défaut :", "en": "Choice (number or name, default:", }, "no IP obtained, ERPLibre clone skipped.": { "fr": "aucune IP obtenue, clonage ERPLibre ignoré.", "en": "no IP obtained, ERPLibre clone skipped.", }, "cloning ERPLibre": { "fr": "clonage d'ERPLibre", "en": "cloning ERPLibre", }, "VM name (required): ": { "fr": "Nom de la VM (requis) : ", "en": "VM name (required): ", }, "VM name is required!": { "fr": "Le nom de la VM est requis !", "en": "VM name is required!", }, "VM name: ": { "fr": "Nom de la VM : ", "en": "VM name: ", }, "VM name or ID: ": { "fr": "Nom ou ID de la VM : ", "en": "VM name or ID: ", }, "VM name or ID (or 'all'): ": { "fr": "Nom ou ID de la VM (ou « all ») : ", "en": "VM name or ID (or 'all'): ", }, "RAM in MB (blank = version minimum): ": { "fr": "RAM en Mo (vide = minimum de la version) : ", "en": "RAM in MB (blank = version minimum): ", }, "vCPUs (default: 2): ": { "fr": "vCPU (défaut : 2) : ", "en": "vCPUs (default: 2): ", }, "Disk size (blank = version min; e.g. 30G, 1T): ": { "fr": "Taille du disque (vide = min. version ; ex. 30G, 1T) : ", "en": "Disk size (blank = version min; e.g. 30G, 1T): ", }, "VM name (default: ": { "fr": "Nom de la VM (défaut : ", "en": "VM name (default: ", }, "Deployment failed (see the error above).": { "fr": "Échec du déploiement (voir l'erreur ci-dessus).", "en": "Deployment failed (see the error above).", }, "SSH public key path": { "fr": "Chemin de la clé publique SSH", "en": "SSH public key path", }, "not installed (see above)": { "fr": "non installé (voir ci-dessus)", "en": "not installed (see above)", }, "download impossible (network or cache):": { "fr": "téléchargement impossible (réseau ou cache) :", "en": "download impossible (network or cache):", }, "mise download impossible (network or cache): pyenv will take over": { "fr": "téléchargement de mise impossible (réseau ou cache) : pyenv prendra le relais", "en": "mise download impossible (network or cache): pyenv will take over", }, "mise installer failed: pyenv will take over": { "fr": "l'installateur de mise a échoué : pyenv prendra le relais", "en": "mise installer failed: pyenv will take over", }, "timezone not set": { "fr": "fuseau non posé", "en": "timezone not set", }, "No internet connection": { "fr": "Sans connexion internet", "en": "No internet connection", }, "Cache - Fill what offline runs lacked": { "fr": "🩹 Cache - Combler ce qui a manqué hors ligne", "en": "🩹 Cache - Fill what offline runs lacked", }, "Cache - Logs": { "fr": "📜 Cache - Journaux", "en": "📜 Cache - Logs", }, "Read the error above, fix it, and run entry 1.": { "fr": "Lire l'erreur ci-dessus, la corriger, et relancer l'entrée 1.", "en": "Read the error above, fix it, and run entry 1.", }, "Cache - Automatic cleanup": { "fr": "🧹 Cache - Nettoyage automatique", "en": "🧹 Cache - Automatic cleanup", }, "Automatic cleanup of the cache": { "fr": "Nettoyage automatique du cache", "en": "Automatic cleanup of the cache", }, "Cleanup - Set the age limit": { "fr": "⏳ Nettoyage - Régler l'âge limite", "en": "⏳ Cleanup - Set the age limit", }, "Cleanup - Set the size ceiling": { "fr": "📏 Nettoyage - Régler le plafond de taille", "en": "📏 Cleanup - Set the size ceiling", }, "Cleanup - Preview now (dry run)": { "fr": "🔍 Nettoyage - Voir ce qui partirait (à blanc)", "en": "🔍 Cleanup - Preview now (dry run)", }, "Cleanup - Run now": { "fr": "🧹 Nettoyage - Lancer maintenant", "en": "🧹 Cleanup - Run now", }, "Age limit:": { "fr": "Âge limite :", "en": "Age limit:", }, "Size ceiling:": { "fr": "Plafond de taille :", "en": "Size ceiling:", }, "disabled": { "fr": "désactivé", "en": "disabled", }, "Daily timer:": { "fr": "Minuteur quotidien :", "en": "Daily timer:", }, "Timer absent: reinstall the cache from entry 1.": { "fr": "Minuteur absent : réinstaller le cache par l'entrée 1.", "en": "Timer absent: reinstall the cache from entry 1.", }, "Not served since (e.g. 90j), empty to disable": { "fr": "Pas servi depuis (ex. 90j), vide pour désactiver", "en": "Not served since (e.g. 90j), empty to disable", }, "Size ceiling (e.g. 50G), empty to disable": { "fr": "Plafond de taille (ex. 50G), vide pour désactiver", "en": "Size ceiling (e.g. 50G), empty to disable", }, "Unreadable value:": { "fr": "Valeur illisible :", "en": "Unreadable value:", }, "Write this setting?": { "fr": "Écrire ce réglage ?", "en": "Write this setting?", }, "Nothing to do: both settings are empty.": { "fr": "Rien à faire : les deux réglages sont vides.", "en": "Nothing to do: both settings are empty.", }, "Cache - Copy it to another machine": { "fr": "📦 Cache - L'emporter sur une autre machine", "en": "📦 Cache - Copy it to another machine", }, "Copy the cache to another machine": { "fr": "Emporter le cache sur une autre machine", "en": "Copy the cache to another machine", }, "Target machine (user@host, or an ssh alias)": { "fr": "Machine d'arrivée (utilisateur@hôte, ou un alias ssh)", "en": "Target machine (user@host, or an ssh alias)", }, "The target has no cache installed:": { "fr": "La machine d'arrivée n'a pas le cache :", "en": "The target has no cache installed:", }, "Cannot reach it over ssh:": { "fr": "Injoignable par ssh :", "en": "Cannot reach it over ssh:", }, "This entry needs a password-less ssh access:": { "fr": "Cette entrée exige un accès ssh sans mot de passe :", "en": "This entry needs a password-less ssh access:", }, "If it asks for a password, post a key there:": { "fr": "S'il réclame un mot de passe, y déposer une clé :", "en": "If it asks for a password, post a key there:", }, "Entry 1 installs the cache HERE; the target needs its own.": { "fr": "L'entrée 1 pose le cache ICI ; l'arrivée doit avoir le sien.", "en": "Entry 1 installs the cache HERE; the target needs its own.", }, "Steps, ON the target machine:": { "fr": "Les gestes, SUR la machine d'arrivée :", "en": "Steps, ON the target machine:", }, "go to its ERPLibre checkout, then:": { "fr": "aller dans son checkout ERPLibre, puis :", "en": "go to its ERPLibre checkout, then:", }, "without that branch, the installer is not there": { "fr": "sans cette branche, l'installateur n'y est pas", "en": "without that branch, the installer is not there", }, "the branch used here": { "fr": "la branche utilisée ici", "en": "the branch used here", }, "sudo asks for a password on the target:": { "fr": "sudo réclame un mot de passe à l'arrivée :", "en": "sudo asks for a password on the target:", }, "The store travels on ssh stdin, which carries no terminal,": { "fr": "Le magasin voyage dans l'entrée de ssh, qui n'a pas de terminal,", "en": "The store travels on ssh stdin, which carries no terminal,", }, "so nothing can type it. Two ways out:": { "fr": "donc rien ne peut le taper. Deux issues :", "en": "so nothing can type it. Two ways out:", }, "1) Allow it there without a password, once:": { "fr": "1) L'y autoriser sans mot de passe, une fois :", "en": "1) Allow it there without a password, once:", }, "2) Carry it in two steps, the last one in your terminal there:": { "fr": "2) L'emporter en deux temps, le dernier dans ton terminal là-bas :", "en": "2) Carry it in two steps, the last one in your terminal there:", }, "needed there:": { "fr": "place requise :", "en": "needed there:", }, "free there:": { "fr": "place libre :", "en": "free there:", }, "Not enough room there: the two-step mode is out.": { "fr": "Place insuffisante là-bas : le mode en deux temps est exclu.", "en": "Not enough room there: the two-step mode is out.", }, "Send it now, and print the command to finish there?": { "fr": "Envoyer maintenant, et afficher la commande à finir là-bas ?", "en": "Send it now, and print the command to finish there?", }, "The send failed; nothing was extracted.": { "fr": "L'envoi a échoué ; rien n'a été extrait.", "en": "The send failed; nothing was extracted.", }, "Sent. To finish, ON the target machine, in a terminal:": { "fr": "Envoyé. Pour finir, SUR la machine d'arrivée, en terminal :", "en": "Sent. To finish, ON the target machine, in a terminal:", }, "The last command removes the file.": { "fr": "La dernière commande retire le fichier.", "en": "The last command removes the file.", }, "or, in its own TODO: Execute > Deploy > QEMU cache, entry 1": { "fr": "ou, dans son TODO : Exécuter > Déploiement > Cache QEMU, entrée 1", "en": "or, in its own TODO: Execute > Deploy > QEMU cache, entry 1", }, "The installer reads the « default » libvirt network to find": { "fr": "L'installateur lit le réseau libvirt « default » pour trouver", "en": "The installer reads the « default » libvirt network to find", }, "the bridge; a stopped libvirt makes it die on « not found »:": { "fr": "le pont ; libvirt arrêté, il meurt sur un « introuvable » :", "en": "the bridge; a stopped libvirt makes it die on « not found »:", }, "Or name the bridge by hand, libvirt being optional then:": { "fr": "Ou nommer le pont à la main, libvirt devenant facultatif :", "en": "Or name the bridge by hand, libvirt being optional then:", }, "Then come back to this entry.": { "fr": "Puis revenir à cette entrée.", "en": "Then come back to this entry.", }, "The cache is there but its service account is not:": { "fr": "Le cache est là, mais pas son compte de service :", "en": "The cache is there but its service account is not:", }, "Reinstall it there: the installer creates the account.": { "fr": "L'y réinstaller : l'installateur crée le compte.", "en": "Reinstall it there: the installer creates the account.", }, "Carrying it to another machine": { "fr": "L'emporter sur une autre machine", "en": "Carrying it to another machine", }, " Entry 11 copies the STORE, not the service: an object is": { "fr": " L'entrée 11 copie le MAGASIN, pas le service : un objet est", "en": " Entry 11 copies the STORE, not the service: an object is", }, " keyed by URL and a git mirror is a repository, so both are": { "fr": " rangé sous une clé d'URL et un miroir git est un dépôt : les", "en": " keyed by URL and a git mirror is a repository, so both are", }, " worth the same elsewhere. The settings stay here — bridge,": { "fr": " deux valent ailleurs. Les réglages restent ici — le pont,", "en": " worth the same elsewhere. The settings stay here — bridge,", }, " subnet and authority belong to the host that serves them.": { "fr": " le sous-réseau et l'autorité sont à l'hôte qui les sert.", "en": " subnet and authority belong to the host that serves them.", }, " The target must already carry the cache, installed from": { "fr": " L'arrivée doit déjà porter le cache, posé depuis SON propre", "en": " The target must already carry the cache, installed from", }, " ITS own checkout, and answer ssh without a password.": { "fr": " checkout, et répondre à ssh sans mot de passe.", "en": " ITS own checkout, and answer ssh without a password.", }, "What travels:": { "fr": "Ce qui voyage :", "en": "What travels:", }, "objects": { "fr": "objets", "en": "objects", }, "git mirrors": { "fr": "miroirs git", "en": "git mirrors", }, "The settings stay here: bridge, subnet and authority": { "fr": "Les réglages restent ici : pont, sous-réseau et autorité", "en": "The settings stay here: bridge, subnet and authority", }, "belong to this host, and are posed by entry 1 there.": { "fr": "appartiennent à cet hôte ; l'entrée 1 les pose là-bas.", "en": "belong to this host, and are posed by entry 1 there.", }, "Copy now?": { "fr": "Emporter maintenant ?", "en": "Copy now?", }, "Logs of the download cache": { "fr": "Journaux du cache de téléchargement", "en": "Logs of the download cache", }, "Ctrl-C ends a live follow.": { "fr": "Ctrl-C arrête un suivi en direct.", "en": "Ctrl-C ends a live follow.", }, "Logs - Requests, live": { "fr": "Journaux - Les requêtes, en direct", "en": "Logs - Requests, live", }, "Logs - Only requests that went to the internet, live": { "fr": "Journaux - Seulement les requêtes sorties sur l'internet, en direct", "en": "Logs - Only requests that went to the internet, live", }, "Logs - Last 40 requests": { "fr": "Journaux - Les 40 dernières requêtes", "en": "Logs - Last 40 requests", }, "Logs - Service journal, live": { "fr": "Journaux - Journal du service, en direct", "en": "Logs - Service journal, live", }, "No access log yet:": { "fr": "Pas encore de journal d'accès :", "en": "No access log yet:", }, "GPU groups set": { "fr": "groupes du GPU posés", "en": "GPU groups set", }, "apt mirror pinned": { "fr": "miroir apt fixé", "en": "apt mirror pinned", }, "the cache has no package named": { "fr": "le cache n'a aucun paquet nommé", "en": "the cache has no package named", }, "an offline VM will not install it": { "fr": "une VM hors ligne ne l'installera pas", "en": "an offline VM will not install it", }, "these git repositories are not mirrored:": { "fr": "ces dépôts git ne sont pas en miroir :", "en": "these git repositories are not mirrored:", }, "an offline VM cannot clone them": { "fr": "une VM hors ligne ne peut pas les cloner", "en": "an offline VM cannot clone them", }, "fill them from Cache › Git mirrors": { "fr": "les remplir depuis Cache › Miroirs git", "en": "fill them from Cache › Git mirrors", }, "cache holds no index for": { "fr": "le cache n'a aucun index pour", "en": "cache holds no index for", }, "those packages will not be found": { "fr": "ces paquets ne seront pas trouvés", "en": "those packages will not be found", }, "waiting for the VM to answer ssh": { "fr": "attente que la VM réponde en ssh", "en": "waiting for the VM to answer ssh", }, "No ssh answer: guest left as created.": { "fr": "Pas de réponse ssh : l'invité reste tel qu'il est né.", "en": "No ssh answer: guest left as created.", }, "No 3D: the host lacks": { "fr": "Pas de 3D : il manque à l'hôte", "en": "No 3D: the host lacks", }, "Install on the host": { "fr": "Installer sur l'hôte", "en": "Install on the host", }, "3D is now available: the box is here.": { "fr": "La 3D est maintenant possible : la case est là.", "en": "3D is now available: the box is here.", }, "Still missing on the host:": { "fr": "Il manque encore à l'hôte :", "en": "Still missing on the host:", }, "apt mirror not pinned": { "fr": "miroir apt non fixé", "en": "apt mirror not pinned", }, "GPU groups not set": { "fr": "groupes du GPU non posés", "en": "GPU groups not set", }, " Entry 10 follows it live: a request that goes out to the": { "fr": " L'entrée 10 le suit en direct : une requête qui sort sur", "en": " Entry 10 follows it live: a request that goes out to the", }, " internet shows there, and a cut leaves that view empty.": { "fr": " l'internet s'y voit, et une coupure y laisse le vide.", "en": " internet shows there, and a cut leaves that view empty.", }, "What offline runs lacked": { "fr": "Ce qui a manqué hors ligne", "en": "What offline runs lacked", }, "Start it from entry 3 of this menu.": { "fr": "Le démarrer depuis l'entrée 3 de ce menu.", "en": "Start it from entry 3 of this menu.", }, "A replay now would only record more misses.": { "fr": "Un rejeu maintenant ne ferait qu'ajouter des manques.", "en": "A replay now would only record more misses.", }, "No offline miss in the recent window: nothing to fill.": { "fr": "Aucun manque hors ligne récent : rien à combler.", "en": "No offline miss in the recent window: nothing to fill.", }, "Everything that was missed is held now.": { "fr": "Tout ce qui a manqué est désormais détenu.", "en": "Everything that was missed is held now.", }, "according to the log: a purge can make it wrong": { "fr": "selon le journal : une purge peut le rendre faux", "en": "according to the log: a purge can make it wrong", }, "replay through the cache": { "fr": "à rejouer par le cache", "en": "replay through the cache", }, "never kept: the cache keeps only GET and HEAD": { "fr": "jamais gardée : le cache ne garde que GET et HEAD", "en": "never kept: the cache keeps only GET and HEAD", }, "the cache does not keep this address": { "fr": "le cache ne garde pas cette adresse", "en": "the cache does not keep this address", }, "host in tunnel: nothing to keep": { "fr": "hôte en tunnel : rien à garder", "en": "host in tunnel: nothing to keep", }, "git negotiation: fill the mirror from entry 5": { "fr": "négociation git : remplir le miroir depuis l'entrée 5", "en": "git negotiation: fill the mirror from entry 5", }, "not a host name: a replay could loop back into the cache": { "fr": "pas un nom d'hôte : le rejeu pourrait revenir dans le cache", "en": "not a host name: a replay could loop back into the cache", }, "Nothing here can be replayed.": { "fr": "Rien ici ne peut être rejoué.", "en": "Nothing here can be replayed.", }, "The replay sends curl's own headers: a server that varies on": { "fr": "Le rejeu envoie les en-têtes de curl : un serveur qui varie selon", "en": "The replay sends curl's own headers: a server that varies on", }, "User-Agent or Accept may keep another answer than the VM's.": { "fr": "User-Agent ou Accept peut garder une autre réponse que celle de la VM.", "en": "User-Agent or Accept may keep another answer than the VM's.", }, "Replay these addresses through the cache now?": { "fr": "Rejouer ces adresses par le cache maintenant ?", "en": "Replay these addresses through the cache now?", }, "held": { "fr": "détenu", "en": "held", }, "not held": { "fr": "non détenu", "en": "not held", }, "not re-checked: this binary has no --detient": { "fr": "non revérifié : ce binaire n'a pas --detient", "en": "not re-checked: this binary has no --detient", }, "Tunnel refusals learned by the service:": { "fr": "Refus de tunnel appris par le service :", "en": "Tunnel refusals learned by the service:", }, "curl got no answer": { "fr": "curl n'a obtenu aucune réponse", "en": "curl got no answer", }, "the last offline run of": { "fr": "le dernier déploiement hors ligne de", "en": "the last offline run of", }, "age:": { "fr": "âge :", "en": "age:", }, "lacked at least": { "fr": "a manqué d'au moins", "en": "lacked at least", }, "addresses": { "fr": "adresses", "en": "addresses", }, "e.g.": { "fr": "par exemple", "en": "e.g.", }, "fill them from Cache › Fill what offline runs lacked": { "fr": "les combler depuis Cache › Combler ce qui a manqué hors ligne", "en": "fill them from Cache › Fill what offline runs lacked", }, "Upstream CUT: the cache can pull nothing from the internet": { "fr": "Amont COUPÉ : le cache ne peut rien tirer de l'internet", "en": "Upstream CUT: the cache can pull nothing from the internet", }, "Every VM then gets a 504 from every mirror.": { "fr": "Toute VM reçoit alors un 504 depuis tous les miroirs.", "en": "Every VM then gets a 504 from every mirror.", }, "Lift it with:": { "fr": "La lever par :", "en": "Lift it with:", }, "waiting for the guest agent install (apt lock)": { "fr": "attente de la pose de l'agent invité (verrou apt)", "en": "waiting for the guest agent install (apt lock)", }, "apt-get update never succeeded in 5 min (lock held, or nothing served)": { "fr": "apt-get update n'a jamais abouti : le verrou est resté pris", "en": "apt-get update never succeeded in 5 min (lock held, or nothing served)", }, "An offline deployment is still running: the cut": { "fr": "Un déploiement hors ligne tourne encore : la coupure", "en": "An offline deployment is still running: the cut", }, "is shared, and its end would lift yours.": { "fr": "est partagée, et sa fin lèverait la vôtre.", "en": "is shared, and its end would lift yours.", }, "Nothing deployed.": { "fr": "Rien n'est déployé.", "en": "Nothing deployed.", }, "Lift it now with:": { "fr": "La lever maintenant par :", "en": "Lift it now with:", }, "The cache upstream is already cut, and nothing": { "fr": "L'amont du cache est déjà coupé, et rien", "en": "The cache upstream is already cut, and nothing", }, "will lift it: an interrupted deployment, or one": { "fr": "ne le rebranchera : un déploiement interrompu, ou un", "en": "will lift it: an interrupted deployment, or one", }, "still installing without the monitor.": { "fr": "autre qui installe encore sans le suivi.", "en": "still installing without the monitor.", }, "Lift it and continue? (y/N): ": { "fr": "Lever la coupure et continuer ? (o/N) : ", "en": "Lift it and continue? (y/N): ", }, "The cache upstream stays cut until the last": { "fr": "L'amont du cache reste coupé jusqu'à la fin de la", "en": "The cache upstream stays cut until the last", }, "installation ends, at most": { "fr": "dernière installation, au plus", "en": "installation ends, at most", }, "The cache upstream comes back when the last": { "fr": "L'amont du cache revient à la fin de la", "en": "The cache upstream comes back when the last", }, "even if the monitor is closed.": { "fr": "même si le suivi est fermé.", "en": "even if the monitor is closed.", }, "Could not hand the lift over to systemd-run:": { "fr": "Impossible de confier la levée à systemd-run :", "en": "Could not hand the lift over to systemd-run:", }, "the cache upstream comes back when the monitor": { "fr": "l'amont du cache revient à la fermeture du suivi ;", "en": "the cache upstream comes back when the monitor", }, "closes; closing it early finishes the installs online.": { "fr": "le fermer avant la fin fait finir les installations en ligne.", "en": "closes; closing it early finishes the installs online.", }, "The cache upstream may still be cut.": { "fr": "L'amont du cache est peut-être encore coupé.", "en": "The cache upstream may still be cut.", }, "Existing checkout kept, not updated:": { "fr": "Dépôt existant gardé, sans mise à jour :", "en": "Existing checkout kept, not updated:", }, "The cache mirror has no branch": { "fr": "Le miroir du cache n'a pas la branche", "en": "The cache mirror has no branch", }, "an offline clone will fail.": { "fr": "un clone hors ligne échouera.", "en": "an offline clone will fail.", }, "Offline, the VM clones the cache mirror of": { "fr": "Hors ligne, la VM clone le miroir du cache de", "en": "Offline, the VM clones the cache mirror of", }, "this checkout has": { "fr": "ce checkout est à", "en": "this checkout has", }, "commit(s) missing from the mirror": { "fr": "commit(s) absent(s) du miroir", "en": "commit(s) missing from the mirror", }, "A push alone changes nothing: the mirror is": { "fr": "Un push seul n'y change rien : le miroir ne se", "en": "A push alone changes nothing: the mirror is", }, "refreshed only when a VM clones it online.": { "fr": "rafraîchit que quand une VM le clone en ligne.", "en": "refreshed only when a VM clones it online.", }, "Nothing is cut before F5: the upstream falls": { "fr": "Rien n'est coupé avant F5 : l'amont tombe", "en": "Nothing is cut before F5: the upstream falls", }, "at launch and comes back when the last install": { "fr": "au lancement et revient à la fin de la dernière", "en": "at launch and comes back when the last install", }, "ends (12 h at most), even with the monitor closed.": { "fr": "installation (12 h au plus), suivi fermé ou non.", "en": "ends (12 h at most), even with the monitor closed.", }, "Another offline deployment is starting or": { "fr": "Un autre déploiement hors ligne démarre ou", "en": "Another offline deployment is starting or", }, "running in another terminal.": { "fr": "tourne dans un autre terminal.", "en": "running in another terminal.", }, "An offline deployment is still installing.": { "fr": "Un déploiement hors ligne installe encore.", "en": "An offline deployment is still installing.", }, "This deployment would therefore run offline.": { "fr": "Ce déploiement tournerait donc hors ligne.", "en": "This deployment would therefore run offline.", }, "An offline deployment is starting in another": { "fr": "Un déploiement hors ligne se lance dans un autre", "en": "An offline deployment is starting in another", }, "terminal: the cache upstream is cut until it ends.": { "fr": "terminal : l'amont du cache est coupé jusqu'à sa fin.", "en": "terminal: the cache upstream is cut until it ends.", }, "Deploy anyway, offline? (y/N): ": { "fr": "Déployer quand même, hors ligne ? (o/N) : ", "en": "Deploy anyway, offline? (y/N): ", }, "Upstream CUT by an offline deployment still installing,": { "fr": "Amont COUPÉ par un déploiement hors ligne qui installe encore,", "en": "Upstream CUT by an offline deployment still installing,", }, "held until its last installation ends (12 h at most).": { "fr": "coupure tenue jusqu'à la fin de sa dernière installation (12 h au plus).", "en": "held until its last installation ends (12 h at most).", }, "Lifting it now makes those installations finish online.": { "fr": "La lever maintenant fait finir ces installations en ligne.", "en": "Lifting it now makes those installations finish online.", }, "The lift watcher still runs, with no cut left to lift.": { "fr": "Le guet de levée tourne encore, sans coupure à lever.", "en": "The lift watcher still runs, with no cut left to lift.", }, "Stop it with:": { "fr": "L'arrêter par :", "en": "Stop it with:", }, "Cannot tell whether the upstream is cut: reading nft needs a sudo password here.": { "fr": "Impossible de savoir si l'amont est coupé : lire nft exige ici le mot de passe de sudo.", "en": "Cannot tell whether the upstream is cut: reading nft needs a sudo password here.", }, "Under the cut, a replay would only record more misses.": { "fr": "Sous la coupure, un rejeu n'ajouterait que des manques.", "en": "Under the cut, a replay would only record more misses.", }, "Replay anyway?": { "fr": "Rejouer quand même ?", "en": "Replay anyway?", }, "The monitor stays ticked: it is what arms that return.": { "fr": "Le suivi reste coché : c'est lui qui arme ce retour.", "en": "The monitor stays ticked: it is what arms that return.", }, "git repositories not mirrored: fill them from entry 5 of the cache menu": { "fr": "dépôts git absents du miroir : les remplir depuis l'entrée 5 du menu du cache", "en": "git repositories not mirrored: fill them from entry 5 of the cache menu", }, "requests the cache never keeps:": { "fr": "requêtes que le cache ne garde jamais :", "en": "requests the cache never keeps:", }, "Cuts internet for the cache and the VMs: proves": { "fr": "Coupe l'internet du cache et des VM : prouve que", "en": "Cuts internet for the cache and the VMs: proves", }, "the install builds from what the cache holds.": { "fr": "l'installation se bâtit avec ce que le cache détient.", "en": "the install builds from what the cache holds.", }, "The VMs have no direct way out either: only the host answers them.": { "fr": "Les VM n'ont plus de sortie directe non plus : seul l'hôte leur répond.", "en": "The VMs have no direct way out either: only the host answers them.", }, "cache holds nothing for": { "fr": "le cache ne détient rien pour", "en": "cache holds nothing for", }, "an offline VM will fail": { "fr": "une VM hors ligne échouera", "en": "an offline VM will fail", }, "The cut hits every user of the cache:": { "fr": "La coupure vaut pour tous les usagers du cache :", "en": "The cut hits every user of the cache:", }, "a deployment run from another terminal": { "fr": "un déploiement mené depuis un autre terminal", "en": "a deployment run from another terminal", }, "goes offline too, without asking for it.": { "fr": "sera hors ligne aussi, sans l'avoir demandé.", "en": "goes offline too, without asking for it.", }, "Cache upstream cut for this deployment.": { "fr": "Amont du cache coupé pour ce déploiement.", "en": "Cache upstream cut for this deployment.", }, "Cache upstream restored.": { "fr": "Amont du cache rebranché.", "en": "Cache upstream restored.", }, "Upstream not cut: nothing deployed.": { "fr": "Amont non coupé : rien n'est déployé.", "en": "Upstream not cut: nothing deployed.", }, "The result would look offline without being so.": { "fr": "Le résultat se lirait comme hors ligne sans l'être.", "en": "The result would look offline without being so.", }, "dnsmasq is missing on the host: names cannot": { "fr": "dnsmasq manque sur l'hôte : les noms ne peuvent", "en": "dnsmasq is missing on the host: names cannot", }, "be cut. Install the dnsmasq package, then F5.": { "fr": "pas être coupés. Installer le paquet dnsmasq, puis F5.", "en": "be cut. Install the dnsmasq package, then F5.", }, "download cache authority installed": { "fr": "autorité du cache de téléchargement posée", "en": "download cache authority installed", }, "download cache authority not installed": { "fr": "autorité du cache de téléchargement non posée", "en": "download cache authority not installed", }, "Clean - Forget one URL": { "fr": "Nettoyer - Oublier une URL", "en": "Clean - Forget one URL", }, "URL to forget (or METHOD URL)": { "fr": "URL à oublier (ou MÉTHODE URL)", "en": "URL to forget (or METHOD URL)", }, "What the store holds for it:": { "fr": "Ce que le magasin en tient :", "en": "What the store holds for it:", }, "Remove this entry from the store?": { "fr": "Retirer cette entrée du magasin ?", "en": "Remove this entry from the store?", }, "Prepared by the host:": { "fr": "Préparé par l'hôte :", "en": "Prepared by the host:", }, "host taken out of the download cache": { "fr": "hôte soustrait au cache de téléchargement", "en": "host taken out of the download cache", }, "its own downloads stop being cached too.": { "fr": "ses propres téléchargements cessent aussi d'être gardés.", "en": "its own downloads stop being cached too.", }, "download cache bypass not set": { "fr": "exception au cache de téléchargement non posée", "en": "download cache bypass not set", }, "download cache: host MAC not found": { "fr": "cache de téléchargement : MAC de l'hôte introuvable", "en": "download cache: host MAC not found", }, "no trust store for this distribution, its downloads will fail": { "fr": ( "pas de magasin de confiance pour cette distribution, ses " "téléchargements échoueront" ), "en": "no trust store for this distribution, its downloads will fail", }, "Timezone": { "fr": "Fuseau horaire", "en": "Timezone", }, "virsh cannot reach qemu:///system without sudo.": { "fr": "virsh ne peut pas joindre qemu:///system sans sudo.", "en": "virsh cannot reach qemu:///system without sudo.", }, "The install monitor runs detached and cannot type a": { "fr": "Le suivi d'installation tourne détaché et ne peut pas saisir", "en": "The install monitor runs detached and cannot type a", }, "password: it would lose the VM when its lease moves.": { "fr": "de mot de passe : il perdrait la VM au changement de bail.", "en": "password: it would lose the VM when its lease moves.", }, "You are in the libvirt group, but this session": { "fr": "Vous êtes dans le groupe libvirt, mais cette session est", "en": "You are in the libvirt group, but this session", }, "predates it. Log out and back in, or run:": { "fr": "antérieure. Reconnectez-vous, ou lancez :", "en": "predates it. Log out and back in, or run:", }, "Group is active, so the cause is elsewhere:": { "fr": "Le groupe est actif : la cause est donc ailleurs.", "en": "Group is active, so the cause is elsewhere:", }, "Add your user to the libvirt group?": { "fr": "Ajouter votre utilisateur au groupe libvirt ?", "en": "Add your user to the libvirt group?", }, "Run it now? (Y/n): ": { "fr": "L'exécuter maintenant ? (O/n) : ", "en": "Run it now? (Y/n): ", }, "Command failed.": { "fr": "La commande a échoué.", "en": "Command failed.", }, "Added. Log out and back in for it to take effect,": { "fr": "Ajouté. Reconnectez-vous pour que ça prenne effet,", "en": "Added. Log out and back in for it to take effect,", }, "or start a new shell with: newgrp libvirt": { "fr": "ou ouvrez un shell neuf avec : newgrp libvirt", "en": "or start a new shell with: newgrp libvirt", }, "Timezone for the VMs": { "fr": "Fuseau horaire des VM", "en": "Timezone for the VMs", }, "Locale for the VMs": { "fr": "Locale des VM", "en": "Locale for the VMs", }, "KVM is unavailable: the VMs will be EMULATED.": { "fr": "KVM indisponible : les VM seront ÉMULÉES.", "en": "KVM is unavailable: the VMs will be EMULATED.", }, "A boot then takes 10-15 min, not under a minute.": { "fr": "Un démarrage prend alors 10 à 15 min, pas moins d'une minute.", "en": "A boot then takes 10-15 min, not under a minute.", }, "Cause: /dev/kvm is missing. This host is itself a VM": { "fr": "Cause : /dev/kvm est absent. Cet hôte est lui-même une VM", "en": "Cause: /dev/kvm is missing. This host is itself a VM", }, "whose hypervisor does not expose nested virtualization.": { "fr": "dont l'hyperviseur n'expose pas la virtualisation imbriquée.", "en": "whose hypervisor does not expose nested virtualization.", }, "To fix it ON THE PARENT HYPERVISOR, not here:": { "fr": "Pour corriger, SUR L'HYPERVISEUR PARENT, pas ici :", "en": "To fix it ON THE PARENT HYPERVISOR, not here:", }, "then set this VM to the host-passthrough CPU mode and": { "fr": "puis donner à cette VM le mode CPU « host-passthrough », et", "en": "then set this VM to the host-passthrough CPU mode and", }, "stop it and start it again - a reboot is not enough.": { "fr": "l'arrêter puis la redémarrer — un reboot ne suffit pas.", "en": "stop it and start it again - a reboot is not enough.", }, "Without access to that hypervisor, nothing to do here.": { "fr": "Sans accès à cet hyperviseur, il n'y a rien à régler ici.", "en": "Without access to that hypervisor, nothing to do here.", }, "Usual cause: this host is itself a VM without nested": { "fr": "Cause habituelle : cet hôte est lui-même une VM sans", "en": "Usual cause: this host is itself a VM without nested", }, "virtualization. Check: systemd-detect-virt": { "fr": "virtualisation imbriquée. Vérifier : systemd-detect-virt", "en": "virtualization. Check: systemd-detect-virt", }, "Unknown timezone, keeping": { "fr": "Fuseau inconnu, on garde", "en": "Unknown timezone, keeping", }, "No SSH key found. Set a password instead? (Y/n): ": { "fr": "Aucune clé SSH trouvée. Définir un mot de passe ? (O/n) : ", "en": "No SSH key found. Set a password instead? (Y/n): ", }, "Overwrite existing VM disk if present? (y/N): ": { "fr": "Écraser le disque de la VM s'il existe ? (o/N, défaut : non) : ", "en": "Overwrite existing VM disk if present? (y/N, default: no): ", }, "Verify SHA256 after download? (y/N): ": { "fr": "Vérifier le SHA256 après téléchargement ? (o/N, défaut : non) : ", "en": "Verify SHA256 after download? (y/N, default: no): ", }, "QEMU - Sample dry-run (demo-vm, Ubuntu 24.04)": { "fr": "🧰 QEMU - Exemple dry-run (demo-vm, Ubuntu 24.04)", "en": "🧰 QEMU - Sample dry-run (demo-vm, Ubuntu 24.04)", }, # QEMU - statistics screen "Statistics (installs, durations, VMs)": { "fr": "📊 Statistiques (installations, durées, VM)", "en": "📊 Statistics (installs, durations, VMs)", }, "QEMU statistics": {"fr": "Statistiques QEMU", "en": "QEMU statistics"}, "No installation recorded yet.": { "fr": "Aucune installation enregistrée pour l'instant.", "en": "No installation recorded yet.", }, "Installations": {"fr": "Installations", "en": "Installations"}, "Total": {"fr": "Total", "en": "Total"}, "succeeded": {"fr": "réussies", "en": "succeeded"}, "failed": {"fr": "échouées", "en": "failed"}, "Period": {"fr": "Période", "en": "Period"}, "days": {"fr": "jours", "en": "days"}, "Median duration": {"fr": "Durée médiane", "en": "Median duration"}, "min": {"fr": "min", "en": "min"}, "max": {"fr": "max", "en": "max"}, "Cumulated time": {"fr": "Temps cumulé", "en": "Cumulated time"}, "By distribution": {"fr": "Par distribution", "en": "By distribution"}, "By version": {"fr": "Par version", "en": "By version"}, "By architecture": {"fr": "Par architecture", "en": "By architecture"}, "Virtual machines": { "fr": "Machines virtuelles", "en": "Virtual machines", }, "Defined": {"fr": "Définies", "en": "Defined"}, "running": {"fr": "en cours", "en": "running"}, "stopped": {"fr": "arrêtées", "en": "stopped"}, "Disk used": {"fr": "Disque utilisé", "en": "Disk used"}, "image": {"fr": "image", "en": "image"}, "failure": {"fr": "échec", "en": "failure"}, "Reset the statistics": { "fr": "Réinitialiser les statistiques", "en": "Reset the statistics", }, "Nothing to reset.": {"fr": "Rien à effacer.", "en": "Nothing to reset."}, "Erase": {"fr": "Effacer", "en": "Erase"}, "recorded runs": {"fr": "runs enregistrés", "en": "recorded runs"}, "runs erased": {"fr": "runs effacés", "en": "runs erased"}, "Cancelled.": {"fr": "Annulé.", "en": "Cancelled."}, # Database migration - resume menu "Migration in progress": { "fr": "Migration en cours", "en": "Migration in progress", }, "File": {"fr": "Fichier", "en": "File"}, "Database": {"fr": "Base", "en": "Database"}, "Target": {"fr": "Cible", "en": "Target"}, "Started": {"fr": "Démarrée", "en": "Started"}, "Steps": {"fr": "Étapes", "en": "Steps"}, "Prepare the environment": { "fr": "Préparer l'environnement", "en": "Prepare the environment", }, "Restore and neutralize the database": { "fr": "Restaurer et neutraliser la base", "en": "Restore and neutralize the database", }, "Update all addons": { "fr": "Mettre à jour tous les modules", "en": "Update all addons", }, "Clean up before data migration": { "fr": "Nettoyer avant la migration des données", "en": "Clean up before data migration", }, "Upgrade version by version (OpenUpgrade)": { "fr": "Monter de version en version (OpenUpgrade)", "en": "Upgrade version by version (OpenUpgrade)", }, "not started": {"fr": "non démarrée", "en": "not started"}, "done": {"fr": "terminée", "en": "done"}, "partially done": {"fr": "partielle", "en": "partially done"}, "version bumps migrated": { "fr": "montées de version faites", "en": "version bumps migrated", }, "Continue where it stopped": { "fr": "Continuer là où ça s'est arrêté", "en": "Continue where it stopped", }, "Replay from that step": { "fr": "Reprendre à partir de cette étape", "en": "Replay from that step", }, "erases the progression of that step and the next ones": { "fr": "efface la progression de cette étape et des suivantes", "en": "erases the progression of that step and the next ones", }, "New migration, erase everything": { "fr": "Nouvelle migration, tout effacer", "en": "New migration, erase everything", }, "Keep the zip only, ask every question again": { "fr": "Garder seulement le zip, reposer toutes les questions", "en": "Keep the zip only, ask every question again", }, "Your choice": {"fr": "Votre choix", "en": "Your choice"}, "Unknown choice, continuing where it stopped": { "fr": "Choix inconnu, on continue là où ça s'est arrêté", "en": "Unknown choice, continuing where it stopped", }, "Replaying from step": { "fr": "Reprise à partir de l'étape", "en": "Replaying from step", }, "Replay the upgrade from version N": { "fr": "Reprendre la montée à partir de la version N", "en": "Replay the upgrade from version N", }, "rebuilds the intermediate database": { "fr": "recrée la base intermédiaire", "en": "rebuilds the intermediate database", }, "Unknown version": {"fr": "Version inconnue", "en": "Unknown version"}, "The progression file is invalid, ignoring it": { "fr": "Le fichier de progression est invalide, on l'ignore", "en": "The progression file is invalid, ignoring it", }, # --- Menu Execute › Analyse --- # L'émoji vit dans la valeur, jamais dans la clé. Deux clés distinctes, # comme « Data » / « Database » : l'entrée de menu porte l'émoji, # l'étiquette du fil d'Ariane est nue — _todo_telemetry_tui traduit le # dernier segment du chemin, et un émoji y détonnerait. "Analyse - Odoo database analysis": { "fr": "🔬 Analyse - Analyse de base de données Odoo", "en": "🔬 Analyse - Odoo database analysis", }, "Analyse": {"fr": "Analyse", "en": "Analysis"}, "Analyse a database. Reading never writes.": { "fr": "Analyser une base ; la lecture n'écrit jamais.", "en": "Analyse a database. Reading never writes.", }, "About to install into": { "fr": "Sur le point d'installer dans", "en": "About to install into", }, "Cannot install from here.": { "fr": "Installation impossible d'ici.", "en": "Cannot install from here.", }, "Enter = cancel": { "fr": "Entrée = annuler", "en": "Enter = cancel", }, "Go ahead?": { "fr": "On y va ?", "en": "Go ahead?", }, "Ignored, not in the list:": { "fr": "Ignorés, absents de la liste :", "en": "Ignored, not in the list:", }, "Install some of the": { "fr": "Installer une partie des", "en": "Install some of the", }, "Numbers, space separated:": { "fr": "Numéros, séparés par des espaces :", "en": "Numbers, space separated:", }, "every one of them": { "fr": "tous", "en": "every one of them", }, "need repair first": { "fr": "à réparer d'abord", "en": "need repair first", }, "suggested module(s) waiting in this database?": { "fr": "module(s) suggéré(s) qui attendent dans cette base ?", "en": "suggested module(s) waiting in this database?", }, "Analyse a database, without ever writing to it!": { "fr": "Analyser une base, sans jamais y écrire !", "en": "Analyse a database, without ever writing to it!", }, # Les icônes du sous-menu Analyse. Elles sont réservées d'avance pour la # famille entière — 🧱 index, 🎈 ballonnement, 📎 pièces jointes, # 🔗 ir_model_data — pour qu'ajouter un outil ne demande pas d'en # rechercher une libre, et que deux outils voisins ne se ressemblent pas. "Structure": {"fr": "🗄 Structure", "en": "🗄 Structure"}, "Tables and database size": { "fr": "📏 Tables et poids de la base", "en": "📏 Tables and database size", }, "Customisation": {"fr": "🎭 Personnalisation", "en": "🎭 Customisation"}, "Customised views, website copies included": { "fr": "🖼 Vues personnalisées, copies de site web comprises", "en": "🖼 Customised views, website copies included", }, "Analysis failed: ": { "fr": "L'analyse a échoué : ", "en": "Analysis failed: ", }, "Full list and JSON output:": { "fr": "Liste complète et sortie JSON :", "en": "Full list and JSON output:", }, "A backup holds no registry, so nothing was compared with the module" " source. The classification above needs none; only the differences do." " Restore it, or run this on the database.": { "fr": "Une sauvegarde n'a pas de registre, donc rien n'a été comparé" " avec la source du module. Le classement ci-dessus n'en a pas besoin" " ; seuls les écarts en ont. Restaurez-la, ou lancez ceci sur la base.", "en": "A backup holds no registry, so nothing was compared with the" " module source. The classification above needs none; only the" " differences do. Restore it, or run this on the database.", }, "Could not archive the previous log": { "fr": "Impossible d'archiver le journal précédent", "en": "Could not archive the previous log", }, "Previous migration log kept in": { "fr": "Journal de la migration précédente conservé dans", "en": "Previous migration log kept in", }, "done early, before the neutralization": { "fr": "faite plus tôt, avant la neutralisation", "en": "done early, before the neutralization", }, "compare each website copy with the module view it shadows": { "fr": "comparer chaque copie de site web à la vue de module qu'elle" " masque", "en": "compare each website copy with the module view it shadows", }, "Compare the website copies with the view they shadow": { "fr": "🪞 Comparer les copies de site web à la vue qu'elles masquent", "en": "🪞 Compare the website copies with the view they shadow", }, "website copies compared with their module view,": { "fr": "copies de site web comparées à leur vue de module,", "en": "website copies compared with their module view,", }, "differ.": {"fr": "diffèrent.", "en": "differ."}, "What do you want to do with these COW copies?": { "fr": "Que voulez-vous faire de ces copies COW ?", "en": "What do you want to do with these COW copies?", }, "Enter = decide at the version bump": { "fr": "Entrée = décider au palier de version", "en": "Enter = decide at the version bump", }, "what each copy holds": { "fr": "ce que chaque copie porte", "en": "what each copy holds", }, "why it breaks": { "fr": "pourquoi ça casse", "en": "why it breaks", }, "full screen": { "fr": "plein écran", "en": "full screen", }, "neutralize now, reversible": { "fr": "neutraliser maintenant, réversible", "en": "neutralize now, reversible", }, "Undo with": { "fr": "Annuler avec", "en": "Undo with", }, "Nothing decided": { "fr": "Rien de décidé", "en": "Nothing decided", }, "the migration will ask again at the version bump.": { "fr": "la migration reposera la question au palier de version.", "en": "the migration will ask again at the version bump.", }, "Target version directory not found": { "fr": "Répertoire de la version cible introuvable", "en": "Target version directory not found", }, "No website COW view changes shape in": { "fr": "Aucune vue COW de site ne change de forme dans", "en": "No website COW view changes shape in", }, "website COW view(s) will break when moving to": { "fr": "vue(s) COW de site casseront au passage à", "en": "website COW view(s) will break when moving to", }, "the copy keeps an arch whose shape no longer matches what": { "fr": "la copie garde une arch dont la forme ne correspond plus à ce que", "en": "the copy keeps an arch whose shape no longer matches what", }, "the target module view expects.": { "fr": "la vue module cible attend.", "en": "the target module view expects.", }, "The migration offers to neutralize them, and shows what": { "fr": "La migration propose de les neutraliser, et montre ce que", "en": "The migration offers to neutralize them, and shows what", }, "each copy holds before you answer. To look now:": { "fr": "chaque copie porte avant que vous répondiez. Pour regarder maintenant :", "en": "each copy holds before you answer. To look now:", }, "reversible with --restore": { "fr": "réversible avec --restore", "en": "reversible with --restore", }, "Or by hand. To neutralize a copy, rename its key": { "fr": "Ou à la main. Pour neutraliser une copie, renommer sa clé", "en": "Or by hand. To neutralize a copy, rename its key", }, "an unmatched key is never paired with the": { "fr": "une clé sans correspondance n'est jamais appariée à la", "en": "an unmatched key is never paired with the", }, "module view, so the copy never receives the new": { "fr": "vue module, la copie ne reçoit donc jamais le nouveau", "en": "module view, so the copy never receives the new", }, "Setting active=false alone is NOT enough:": { "fr": "Mettre active=false seul ne suffit PAS :", "en": "Setting active=false alone is NOT enough:", }, "an inactive copy keeping the same key still shadows it.": { "fr": "une copie inactive gardant la même clé la masque toujours.", "en": "an inactive copy keeping the same key still shadows it.", }, "COW view(s) belong to a module absent from": { "fr": "vue(s) COW appartiennent à un module absent de", "en": "COW view(s) belong to a module absent from", }, "COW view(s) are pages or records made in the website": { "fr": "vue(s) COW sont des pages ou des enregistrements faits dans", "en": "COW view(s) are pages or records made in the website", }, "editor (no module view of that name): not at risk.": { "fr": "l'éditeur de site (aucune vue module de ce nom) : hors de danger.", "en": "editor (no module view of that name): not at risk.", }, "Use -v to list them.": { "fr": "Utiliser -v pour les lister.", "en": "Use -v to list them.", }, "No view with this prefix on": { "fr": "Aucune vue avec ce préfixe sur", "en": "No view with this prefix on", }, "archived COW view(s) on": { "fr": "vue(s) COW archivées sur", "en": "archived COW view(s) on", }, "Their arch is intact. Restore them all with --restore,": { "fr": "Leur arch est intacte. Toutes les restaurer avec --restore,", "en": "Their arch is intact. Restore them all with --restore,", }, "once the module view they shadow has the right shape.": { "fr": "une fois que la vue module qu'elles masquent a la bonne forme.", "en": "once the module view they shadow has the right shape.", }, "COW view(s) restored on": { "fr": "vue(s) COW restaurées sur", "en": "COW view(s) restored on", }, "No website COW view to neutralize.": { "fr": "Aucune vue COW de site à neutraliser.", "en": "No website COW view to neutralize.", }, "website COW view(s) would break the bump": { "fr": "vue(s) COW de site casseraient le palier", "en": "website COW view(s) would break the bump", }, "to": { "fr": "vers", "en": "to", }, "Dry-run. Add --apply to rename their key to": { "fr": "Simulation. Ajouter --apply pour renommer leur clé en", "en": "Dry-run. Add --apply to rename their key to", }, "and deactivate them. Reversible": { "fr": "et les désactiver. Réversible", "en": "and deactivate them. Reversible", }, "with --restore; the arch stays in database.": { "fr": "avec --restore ; l'arch reste en base.", "en": "with --restore; the arch stays in database.", }, "COW view(s) neutralized (key prefixed with": { "fr": "vue(s) COW neutralisées (clé préfixée par", "en": "COW view(s) neutralized (key prefixed with", }, "deactivated). The arch is kept as an": { "fr": "désactivées). L'arch est conservée comme", "en": "deactivated). The arch is kept as an", }, "archive; use --restore to undo.": { "fr": "archive ; utiliser --restore pour annuler.", "en": "archive; use --restore to undo.", }, "target inherits, copy holds a standalone template": { "fr": "la cible hérite, la copie porte un modèle autonome", "en": "target inherits, copy holds a standalone template", }, "target is a root view, copy holds inheritance specs": { "fr": "la cible est une vue racine, la copie porte des specs d'héritage", "en": "target is a root view, copy holds inheritance specs", }, "No module view carries this key, so there is nothing to": { "fr": "Aucune vue module ne porte cette clé, il n'y a donc rien à", "en": "No module view carries this key, so there is nothing to", }, "compare: this copy is a page made in the website editor.": { "fr": "comparer : cette copie est une page faite dans l'éditeur de site.", "en": "compare: this copy is a page made in the website editor.", }, "The copy is identical to the module view.": { "fr": "La copie est identique à la vue module.", "en": "The copy is identical to the module view.", }, "line(s) added": { "fr": "ligne(s) ajoutée(s)", "en": "line(s) added", }, "removed": { "fr": "retirée(s)", "en": "removed", }, "this is what neutralizing gives up.": { "fr": "c'est ce que la neutralisation abandonne.", "en": "this is what neutralizing gives up.", }, "the module no longer declares this template": { "fr": "le module ne déclare plus ce modèle", "en": "the module no longer declares this template", }, "inheritance specs (needs inherit_id)": { "fr": "des specs d'héritage (exige inherit_id)", "en": "inheritance specs (needs inherit_id)", }, "a standalone template": { "fr": "un modèle autonome", "en": "a standalone template", }, "Odoo changing the shape of its own template is NOT the": { "fr": "Qu'Odoo change la forme de son propre modèle n'est PAS le", "en": "Odoo changing the shape of its own template is NOT the", }, "problem: on a database without a copy, the module upgrade": { "fr": "problème : sur une base sans copie, la mise à jour du module", "en": "problem: on a database without a copy, the module upgrade", }, "rewrites the view and nothing breaks. It breaks here because": { "fr": "réécrit la vue et rien ne casse. Ça casse ici parce qu'une", "en": "rewrites the view and nothing breaks. It breaks here because", }, "a COPY exists and froze the old shape — the copy follows the": { "fr": "COPIE existe et a figé l'ancienne forme — la copie suit le", "en": "a COPY exists and froze the old shape — the copy follows the", }, "module and becomes an extension, while still holding a": { "fr": "module et devient une extension, tout en portant encore un", "en": "module and becomes an extension, while still holding a", }, "standalone template. Odoo then applies that template as an": { "fr": "modèle autonome. Odoo applique alors ce modèle comme une", "en": "standalone template. Odoo then applies that template as an", }, "inheritance spec and stops on « cannot be located in parent": { "fr": "spec d'héritage et s'arrête sur « cannot be located in parent", "en": "inheritance spec and stops on « cannot be located in parent", }, "view ».": { "fr": "view ».", "en": "view ».", }, "This copy has no module view of that name: it is a page": { "fr": "Cette copie n'a aucune vue module de ce nom : c'est une page", "en": "This copy has no module view of that name: it is a page", }, "made in the website editor, and nothing holds its content.": { "fr": "faite dans l'éditeur de site, et rien d'autre ne porte son contenu.", "en": "made in the website editor, and nothing holds its content.", }, "This copy is IDENTICAL to the module view it shadows: it": { "fr": "Cette copie est IDENTIQUE à la vue module qu'elle masque : elle", "en": "This copy is IDENTICAL to the module view it shadows: it", }, "holds no customization, so neutralizing it loses nothing.": { "fr": "ne porte aucune personnalisation, la neutraliser ne perd rien.", "en": "holds no customization, so neutralizing it loses nothing.", }, "This copy differs from the module view by": { "fr": "Cette copie diffère de la vue module de", "en": "This copy differs from the module view by", }, "line(s):": { "fr": "ligne(s) :", "en": "line(s):", }, "that is the customization, and all neutralizing gives up.": { "fr": "c'est la personnalisation, et tout ce que la neutralisation abandonne.", "en": "that is the customization, and all neutralizing gives up.", }, "Run without --shape to read it.": { "fr": "Lancer sans --shape pour la lire.", "en": "Run without --shape to read it.", }, "No website COW view is at risk.": { "fr": "Aucune vue COW de site n'est en danger.", "en": "No website COW view is at risk.", }, "No COW copy has drifted from its module view.": { "fr": "Aucune copie COW n'a dérivé de sa vue module.", "en": "No COW copy has drifted from its module view.", }, "COW copy(ies) drifted from their module": { "fr": "copie(s) COW ont dérivé de leur vue", "en": "COW copy(ies) drifted from their module", }, "view in": { "fr": "module dans", "en": "view in", }, "Odoo surfaces this when the module view is rewritten (a": { "fr": "Odoo le fait apparaître quand la vue module est réécrite (un", "en": "Odoo surfaces this when the module view is rewritten (a", }, "version bump) or when the page is rendered.": { "fr": "palier de version) ou quand la page est rendue.", "en": "version bump) or when the page is rendered.", }, "NO module view with this key": { "fr": "AUCUNE vue module avec cette clé", "en": "NO module view with this key", }, "child": { "fr": "enfant", "en": "child", }, "cannot apply": { "fr": "ne peut s'appliquer", "en": "cannot apply", }, "Nothing changed. Re-run with --reset --apply to": { "fr": "Rien n'a changé. Relancer avec --reset --apply pour", "en": "Nothing changed. Re-run with --reset --apply to", }, "reset a copy onto its module view.": { "fr": "réinitialiser une copie sur sa vue module.", "en": "reset a copy onto its module view.", }, "no module view to reset onto, skipped.": { "fr": "aucune vue module sur laquelle réinitialiser, ignorée.", "en": "no module view to reset onto, skipped.", }, "dry-run": { "fr": "simulation", "en": "dry-run", }, "would reset": { "fr": "réinitialiserait", "en": "would reset", }, "onto": { "fr": "sur", "en": "onto", }, "reset": { "fr": "réinitialisé", "en": "reset", }, "previous arch saved to": { "fr": "arch précédente sauvegardée dans", "en": "previous arch saved to", }, "copy(ies) reset. Re-apply any real customisation": { "fr": "copie(s) réinitialisée(s). Réappliquer toute vraie personnalisation", "en": "copy(ies) reset. Re-apply any real customisation", }, "as an INHERITING view, not a copy, so it cannot go stale": { "fr": "comme une vue HÉRITANTE, pas une copie, pour qu'elle ne périme plus", "en": "as an INHERITING view, not a copy, so it cannot go stale", }, "again.": { "fr": "à l'avenir.", "en": "again.", }, "lxml is required to resolve the xpath expressions.": { "fr": "lxml est requis pour résoudre les expressions xpath.", "en": "lxml is required to resolve the xpath expressions.", }, "COW view(s) recorded in": { "fr": "vue(s) COW enregistrées dans", "en": "COW view(s) recorded in", }, "COW view(s) disappeared": { "fr": "vue(s) COW ont disparu", "en": "COW view(s) disappeared", }, "COW view(s) appeared": { "fr": "vue(s) COW sont apparues", "en": "COW view(s) appeared", }, "arch rewritten": { "fr": "arch réécrite", "en": "arch rewritten", }, "COW view(s) changed": { "fr": "vue(s) COW ont changé", "en": "COW view(s) changed", }, "No change on the website COW views.": { "fr": "Aucun changement sur les vues COW de site.", "en": "No change on the website COW views.", }, "Welcome to the Odoo database upgrade with ERPLibre": { "fr": "Bienvenue dans la mise à niveau de base de données Odoo avec ERPLibre", "en": "Welcome to the Odoo database upgrade with ERPLibre", }, "Select the zip file of your database backup.": { "fr": "Sélectionnez le fichier zip de votre sauvegarde de base de données.", "en": "Select the zip file of your database backup.", }, "Give the path of the file, or empty to use a file": { "fr": "Donnez le chemin du fichier, ou rien pour utiliser un", "en": "Give the path of the file, or empty to use a file", }, "browser, or type": { "fr": "navigateur de fichiers, ou tapez", "en": "browser, or type", }, "to download from production": { "fr": "pour télécharger depuis la production", "en": "to download from production", }, "Cannot retrieve the database from remote, please retry the migration.": { "fr": "Impossible de récupérer la base distante, veuillez relancer la migration.", "en": "Cannot retrieve the database from remote, please retry the migration.", }, "Open file": { "fr": "Ouverture du fichier", "en": "Open file", }, "Detected Odoo CE version": { "fr": "Version Odoo CE détectée", "en": "Detected Odoo CE version", }, "Which version do you want to upgrade to?": { "fr": "Vers quelle version voulez-vous migrer ?", "en": "Which version do you want to upgrade to?", }, "Search the Odoo version": { "fr": "Recherche de la version Odoo", "en": "Search the Odoo version", }, "Find the right environment, read the .zip file": { "fr": "Recherche du bon environnement, lecture du fichier .zip", "en": "Find the right environment, read the .zip file", }, "Would you like to install": { "fr": "Voulez-vous installer", "en": "Would you like to install", }, "You need an installed system before": { "fr": "Il faut un système installé avant de", "en": "You need an installed system before", }, "continuing, check your Odoo installation.": { "fr": "continuer, vérifiez votre installation Odoo.", "en": "continuing, check your Odoo installation.", }, "Install the environment if missing": { "fr": "Installation de l'environnement s'il manque", "en": "Install the environment if missing", }, "Search missing modules": { "fr": "Recherche des modules manquants", "en": "Search missing modules", }, "Install the missing modules, search for them or": { "fr": "Installer les modules manquants, les chercher ou", "en": "Install the missing modules, search for them or", }, "ask to uninstall them (can break data)": { "fr": "demander à les désinstaller (peut casser des données)", "en": "ask to uninstall them (can break data)", }, "Cannot set up the environment to begin.": { "fr": "Impossible de préparer l'environnement pour commencer.", "en": "Cannot set up the environment to begin.", }, "Missing module": { "fr": "Module manquant", "en": "Missing module", }, "Duplicate module": { "fr": "Module en double", "en": "Duplicate module", }, "Missing or duplicate module detected at init,": { "fr": "Module manquant ou en double détecté à l'init,", "en": "Missing or duplicate module detected at init,", }, "do you want to continue?": { "fr": "voulez-vous continuer ?", "en": "do you want to continue?", }, "Missing or duplicate module detected at init, do": { "fr": "Module manquant ou en double détecté à l'init,", "en": "Missing or duplicate module detected at init, do", }, "you want to continue?": { "fr": "voulez-vous continuer ?", "en": "you want to continue?", }, "Which database name do you want to work with?": { "fr": "Avec quel nom de base voulez-vous travailler ?", "en": "Which database name do you want to work with?", }, "Ignore the database neutralization": { "fr": "Ignorer la neutralisation de la base", "en": "Ignore the database neutralization", }, "Working with database": { "fr": "Travail sur la base", "en": "Working with database", }, "will copy": { "fr": "va copier", "en": "will copy", }, "a file already exists, do you want to": { "fr": "un fichier existe déjà, voulez-vous", "en": "a file already exists, do you want to", }, "continue?": { "fr": "continuer ?", "en": "continue?", }, "Restore the database": { "fr": "Restauration de la base", "en": "Restore the database", }, "Update all addons before neutralizing (already": { "fr": "Mettre à jour tous les modules avant la neutralisation (déjà", "en": "Update all addons before neutralizing (already", }, "neutralized by Odoo if supported)": { "fr": "neutralisée par Odoo si pris en charge)", "en": "neutralized by Odoo if supported)", }, "Do you need to upgrade before neutralizing the": { "fr": "Faut-il mettre à jour avant de neutraliser la", "en": "Do you need to upgrade before neutralizing the", }, "database? Press enter to ignore": { "fr": "base ? Entrée pour ignorer", "en": "database? Press enter to ignore", }, "Update the database before neutralizing, by module": { "fr": "Mise à jour de la base avant neutralisation, par module", "en": "Update the database before neutralizing, by module", }, "Neutralize the database": { "fr": "Neutralisation de la base", "en": "Neutralize the database", }, "Modules to uninstall before the migration": { "fr": "Modules à désinstaller avant la migration", "en": "Modules to uninstall before the migration", }, "Uninstall modules": { "fr": "Désinstallation des modules", "en": "Uninstall modules", }, "Install modules": { "fr": "Installation des modules", "en": "Install modules", }, "Go to Settings / Technical / Cleanup... / Purge and": { "fr": "Aller dans Configuration / Technique / Nettoyage... / Purger et", "en": "Go to Settings / Technical / Cleanup... / Purge and", }, "purge the obsolete modules": { "fr": "purger les modules obsolètes", "en": "purge the obsolete modules", }, "Press enter to continue step 3": { "fr": "Entrée pour continuer l'étape 3", "en": "Press enter to continue step 3", }, "Inspect zip": { "fr": "Inspection du zip", "en": "Inspect zip", }, "Import database from zip": { "fr": "Import de la base depuis le zip", "en": "Import database from zip", }, "Succeed update all addons": { "fr": "Mise à jour de tous les modules", "en": "Succeed update all addons", }, "Clean up database before data migration": { "fr": "Nettoyage de la base avant la migration des données", "en": "Clean up database before data migration", }, "Upgrade version with OpenUpgrade": { "fr": "Montée de version avec OpenUpgrade", "en": "Upgrade version with OpenUpgrade", }, "Cleaning up database after upgrade": { "fr": "Nettoyage de la base après la montée de version", "en": "Cleaning up database after upgrade", }, "Migration finished": { "fr": "Migration terminée", "en": "Migration finished", }, "Clone to Odoo": { "fr": "Clonage vers Odoo", "en": "Clone to Odoo", }, "FAILED (status": { "fr": "ÉCHEC (statut", "en": "FAILED (status", }, "Stopping:": { "fr": "Arrêt :", "en": "Stopping:", }, "is not usable.": { "fr": "n'est pas utilisable.", "en": "is not usable.", }, "Clone Odoo": { "fr": "Clonage Odoo", "en": "Clone Odoo", }, "nothing": { "fr": "rien", "en": "nothing", }, "Switch Odoo": { "fr": "Bascule Odoo", "en": "Switch Odoo", }, "done with update": { "fr": "terminée avec mise à jour", "en": "done with update", }, "Module upgrade Odoo": { "fr": "Mise à jour des modules Odoo", "en": "Module upgrade Odoo", }, "Database upgrade Odoo": { "fr": "Migration de la base Odoo", "en": "Database upgrade Odoo", }, "Modules to uninstall before Odoo": { "fr": "Modules à désinstaller avant Odoo", "en": "Modules to uninstall before Odoo", }, "to redo the command": { "fr": "pour refaire la commande", "en": "to redo the command", }, "Error detected, press enter to continue or": { "fr": "Erreur détectée, Entrée pour continuer ou", "en": "Error detected, press enter to continue or", }, "to stop": { "fr": "pour arrêter", "en": "to stop", }, "Clone done for Odoo": { "fr": "Clonage terminé pour Odoo", "en": "Clone done for Odoo", }, "Clone already done for Odoo": { "fr": "Clonage déjà fait pour Odoo", "en": "Clone already done for Odoo", }, "Switch already done for Odoo": { "fr": "Bascule déjà faite pour Odoo", "en": "Switch already done for Odoo", }, "Switch done with update for Odoo": { "fr": "Bascule terminée avec mise à jour pour Odoo", "en": "Switch done with update for Odoo", }, "Module upgrade done for Odoo": { "fr": "Mise à jour des modules terminée pour Odoo", "en": "Module upgrade done for Odoo", }, "Module upgrade already done for Odoo": { "fr": "Mise à jour des modules déjà faite pour Odoo", "en": "Module upgrade already done for Odoo", }, "Database upgrade done for Odoo": { "fr": "Migration de la base terminée pour Odoo", "en": "Database upgrade done for Odoo", }, "Database upgrade already done for Odoo": { "fr": "Migration de la base déjà faite pour Odoo", "en": "Database upgrade already done for Odoo", }, "Cloning to Odoo": { "fr": "Clonage vers Odoo", "en": "Cloning to Odoo", }, "from": { "fr": "depuis", "en": "from", }, "Duplicate module in Odoo": { "fr": "Module en double dans Odoo", "en": "Duplicate module in Odoo", }, "Duplicate module error detected, handle it": { "fr": "Erreur de module en double détectée, la traiter", "en": "Duplicate module error detected, handle it", }, "manually then press enter to continue.": { "fr": "manuellement puis Entrée pour continuer.", "en": "manually then press enter to continue.", }, "Missing module error detected, missing in": { "fr": "Erreur de module manquant détectée, manquant dans", "en": "Missing module error detected, missing in", }, "All of the list above": { "fr": "Toute la liste ci-dessus", "en": "All of the list above", }, "Add an extra custom one": { "fr": "Ajouter un module personnalisé", "en": "Add an extra custom one", }, "List the missing modules to delete,": { "fr": "Énumérer les modules manquants à supprimer,", "en": "List the missing modules to delete,", }, "separated by commas. The others will be": { "fr": "séparés par des virgules. Les autres seront", "en": "separated by commas. The others will be", }, "migrated": { "fr": "migrés", "en": "migrated", }, "Migration fix for Odoo": { "fr": "Correctif de migration pour Odoo", "en": "Migration fix for Odoo", }, "Migration fix done for Odoo": { "fr": "Correctif de migration terminé pour Odoo", "en": "Migration fix done for Odoo", }, "No migration fix to run for Odoo": { "fr": "Aucun correctif de migration à exécuter pour Odoo", "en": "No migration fix to run for Odoo", }, "Migration fix already done for Odoo": { "fr": "Correctif de migration déjà fait pour Odoo", "en": "Migration fix already done for Odoo", }, "List the module names to delete,": { "fr": "Énumérer les noms de modules à supprimer,", "en": "List the module names to delete,", }, "separated by commas": { "fr": "séparés par des virgules", "en": "separated by commas", }, "Missing module error": { "fr": "Erreur de module manquant", "en": "Missing module error", }, "Duplicate module error": { "fr": "Erreur de module en double", "en": "Duplicate module error", }, "Module error": { "fr": "Erreur de module", "en": "Module error", }, "Please validate the commits after the code": { "fr": "Veuillez valider les commits après la migration", "en": "Please validate the commits after the code", }, "migration.": { "fr": "du code.", "en": "migration.", }, "To show the repo status": { "fr": "Pour afficher l'état des dépôts", "en": "To show the repo status", }, "Please validate this path in config.conf": { "fr": "Veuillez valider ce chemin dans config.conf", "en": "Please validate this path in config.conf", }, "Database migration to Odoo": { "fr": "Migration de la base vers Odoo", "en": "Database migration to Odoo", }, "is now half migrated: replaying the command on": { "fr": "est maintenant à moitié migrée : rejouer la commande dessus", "en": "is now half migrated: replaying the command on", }, "it would never recover, so it is NOT offered.": { "fr": "ne s'en remettrait jamais, ce n'est donc PAS proposé.", "en": "it would never recover, so it is NOT offered.", }, "The clone step has been reset. Fix the": { "fr": "L'étape de clonage a été réinitialisée. Corrigez la", "en": "The clone step has been reset. Fix the", }, "cause, then relaunch the migration and answer": { "fr": "cause, puis relancez la migration et répondez", "en": "cause, then relaunch the migration and answer", }, "continue": { "fr": "continuer", "en": "continue", }, "will be dropped and rebuilt from the previous": { "fr": "sera supprimée et reconstruite depuis la version", "en": "will be dropped and rebuilt from the previous", }, "version before retrying.": { "fr": "précédente avant de réessayer.", "en": "version before retrying.", }, "Do you want to upgrade all": { "fr": "Voulez-vous tout mettre à jour", "en": "Do you want to upgrade all", }, "Press y/Y to upgrade all addons of the": { "fr": "y/Y pour mettre à jour tous les modules de la", "en": "Press y/Y to upgrade all addons of the", }, "Open the server with Selenium": { "fr": "Ouvrir le serveur avec Selenium", "en": "Open the server with Selenium", }, "Do you want to test this upgrade? Choose": { "fr": "Voulez-vous tester cette migration ? Choisissez", "en": "Do you want to test this upgrade? Choose", }, "or press enter to ignore it": { "fr": "ou Entrée pour ignorer", "en": "or press enter to ignore it", }, "Press enter to continue": { "fr": "Entrée pour continuer", "en": "Press enter to continue", }, "Re-update i18n, purge the data and the tables": { "fr": "Remise à jour de l'i18n, purge des données et des tables", "en": "Re-update i18n, purge the data and the tables", }, "except mail_test and mail_test_full": { "fr": "sauf mail_test et mail_test_full", "en": "except mail_test and mail_test_full", }, "A backup can be created": { "fr": "Une sauvegarde peut être créée", "en": "A backup can be created", }, "Press y/Y or type filename.zip to export, or": { "fr": "y/Y ou un nom fichier.zip pour exporter, ou", "en": "Press y/Y or type filename.zip to export, or", }, "enter to continue": { "fr": "Entrée pour continuer", "en": "enter to continue", }, "Test the migration, press y/Y": { "fr": "Tester la migration, y/Y", "en": "Test the migration, press y/Y", }, "Documentation for this version": { "fr": "Documentation de cette version", "en": "Documentation for this version", }, "Command not found": { "fr": "Commande non trouvée", "en": "Command not found", }, "Execute command": { "fr": "Exécution de la commande", "en": "Execute command", }, "Textual is missing from this interpreter:": { "fr": "Textual manque à cet interpréteur :", "en": "Textual is missing from this interpreter:", }, "Run it with": { "fr": "Le lancer avec", "en": "Run it with", }, "No leftover for theme": { "fr": "Aucun reste pour le thème", "en": "No leftover for theme", }, "attachment(s) still under": { "fr": "pièce(s) jointe(s) encore sous", "en": "attachment(s) still under", }, "view(s) whose key still names it": { "fr": "vue(s) dont la clé le nomme encore", "en": "view(s) whose key still names it", }, "Nothing was deleted: their content may be the only trace": { "fr": "Rien n'a été supprimé : leur contenu peut être la seule trace", "en": "Nothing was deleted: their content may be the only trace", }, "of a customization. Read before removing.": { "fr": "d'une personnalisation. Lire avant de retirer.", "en": "of a customization. Read before removing.", }, "Installed theme(s) on": { "fr": "Thème(s) installé(s) sur", "en": "Installed theme(s) on", }, "A theme carries view copies and SCSS through every": { "fr": "Un thème traîne des copies de vues et des SCSS à travers chaque", "en": "A theme carries view copies and SCSS through every", }, "version bump, and a bump can rename what they rely on.": { "fr": "palier de version, et un palier peut renommer ce dont ils dépendent.", "en": "version bump, and a bump can rename what they rely on.", }, "Uninstall them properly before migrating?": { "fr": "Les désinstaller proprement avant de migrer ?", "en": "Uninstall them properly before migrating?", }, "Kept. Nothing was uninstalled.": { "fr": "Conservés. Rien n'a été désinstallé.", "en": "Kept. Nothing was uninstalled.", }, "No customized SCSS is at risk in": { "fr": "Aucun SCSS personnalisé n'est en danger dans", "en": "No customized SCSS is at risk in", }, "customized SCSS use(s) a variable that": { "fr": "SCSS personnalisé(s) utilisent une variable que", "en": "customized SCSS use(s) a variable that", }, "no longer defines: the bundle will not compile.": { "fr": "ne définit plus : le bundle ne compilera pas.", "en": "no longer defines: the bundle will not compile.", }, "Each one is a copy frozen on an older version. Dropping it": { "fr": "Chacun est une copie figée sur une version antérieure. L'abandonner", "en": "Each one is a copy frozen on an older version. Dropping it", }, "restores the module file:": { "fr": "rend le fichier du module :", "en": "restores the module file:", }, "Read it first: what it holds beyond the stale variable is": { "fr": "Le lire d'abord : ce qu'il porte au-delà de la variable périmée est", "en": "Read it first: what it holds beyond the stale variable is", }, "a real customization, to re-apply as a small file.": { "fr": "une vraie personnalisation, à réappliquer en petit fichier.", "en": "a real customization, to re-apply as a small file.", }, "Read the customizations above before continuing.": { "fr": "Lire les personnalisations ci-dessus avant de continuer.", "en": "Read the customizations above before continuing.", }, "Missing:": { "fr": "Manquantes :", "en": "Missing:", }, "No module file of that name in": { "fr": "Aucun fichier de module de ce nom dans", "en": "No module file of that name in", }, "the target no longer ships it, so there is nothing to": { "fr": "la cible ne le livre plus, il n'y a donc rien sur quoi", "en": "the target no longer ships it, so there is nothing to", }, "fall back on. Read the copy before dropping it.": { "fr": "retomber. Lire la copie avant de l'abandonner.", "en": "fall back on. Read the copy before dropping it.", }, "The copy is identical to the module file.": { "fr": "La copie est identique au fichier du module.", "en": "The copy is identical to the module file.", }, "line(s): that is what resetting gives up.": { "fr": "ligne(s) : c'est ce que la réinitialisation abandonne.", "en": "line(s): that is what resetting gives up.", }, "What do you want to do with these customizations?": { "fr": "Que voulez-vous faire de ces personnalisations ?", "en": "What do you want to do with these customizations?", }, "Enter = nothing": { "fr": "Entrée = rien", "en": "Enter = nothing", }, "what the copy changed": { "fr": "ce que la copie a changé", "en": "what the copy changed", }, "reset them onto the module file": { "fr": "les réinitialiser sur le fichier du module", "en": "reset them onto the module file", }, "Full screen view unavailable.": { "fr": "Vue plein écran indisponible.", "en": "Full screen view unavailable.", }, "Saved before resetting": { "fr": "Sauvegardé avant réinitialisation", "en": "Saved before resetting", }, "Reset failed, nothing was changed.": { "fr": "La réinitialisation a échoué, rien n'a été modifié.", "en": "Reset failed, nothing was changed.", }, "Reset done.": { "fr": "Réinitialisation faite.", "en": "Reset done.", }, "This copy uses variables that": { "fr": "Cette copie utilise des variables que", "en": "This copy uses variables that", }, "no longer defines": { "fr": "ne définit plus", "en": "no longer defines", }, "The copy was written against an older version and frozen": { "fr": "La copie a été écrite contre une version antérieure et figée", "en": "The copy was written against an older version and frozen", }, "there. The module has since renamed what it relies on.": { "fr": "là. Le module a depuis renommé ce dont elle dépend.", "en": "there. The module has since renamed what it relies on.", }, "Resetting restores": { "fr": "La réinitialisation rend", "en": "Resetting restores", }, "(nothing: the target no longer ships this file)": { "fr": "(rien : la cible ne livre plus ce fichier)", "en": "(nothing: the target no longer ships this file)", }, "Reset command copied.": { "fr": "Commande de réinitialisation copiée.", "en": "Reset command copied.", }, "Resetting needs Odoo 13.0 or later; this checkout is on": { "fr": "La réinitialisation exige Odoo 13.0 ou plus ; ce checkout est sur", "en": "Resetting needs Odoo 13.0 or later; this checkout is on", }, "The prediction stands, the fix does not: run it again once": { "fr": "La prédiction tient, pas la correction : relancer une fois", "en": "The prediction stands, the fix does not: run it again once", }, "the bump is done, on the upgraded database.": { "fr": "le palier passé, sur la base montée de version.", "en": "the bump is done, on the upgraded database.", }, "Applying it from here fails with": { "fr": "L'appliquer d'ici échoue sur", "en": "Applying it from here fails with", }, "and changes nothing.": { "fr": "et ne change rien.", "en": "and changes nothing.", }, "Reset one of them onto its module view": { "fr": "Réinitialiser l'une d'elles sur sa vue module", "en": "Reset one of them onto its module view", }, "Drifted COW copies": { "fr": "Copies COW ayant dérivé", "en": "Drifted COW copies", }, "Which one(s) to reset onto the module view?": { "fr": "Laquelle ou lesquelles réinitialiser sur la vue module ?", "en": "Which one(s) to reset onto the module view?", }, "numbers separated by commas, a = all, empty =": { "fr": "numéros séparés par des virgules, a = toutes, vide =", "en": "numbers separated by commas, a = all, empty =", }, "Kept. Nothing was reset.": { "fr": "Conservées. Rien n'a été réinitialisé.", "en": "Kept. Nothing was reset.", }, "Unknown choice, nothing was reset.": { "fr": "Choix inconnu, rien n'a été réinitialisé.", "en": "Unknown choice, nothing was reset.", }, "Delete these leftovers, or keep them?": { "fr": "Effacer ces restes, ou les garder ?", "en": "Delete these leftovers, or keep them?", }, "Enter = keep": { "fr": "Entrée = garder", "en": "Enter = keep", }, "delete, after saving them": { "fr": "effacer, après les avoir sauvegardés", "en": "delete, after saving them", }, "Kept. Nothing was deleted.": { "fr": "Conservés. Rien n'a été effacé.", "en": "Kept. Nothing was deleted.", }, "Saved before deleting": { "fr": "Sauvegardé avant effacement", "en": "Saved before deleting", }, "Deletion failed, nothing was removed.": { "fr": "L'effacement a échoué, rien n'a été retiré.", "en": "Deletion failed, nothing was removed.", }, "attachment(s) deleted.": { "fr": "pièce(s) jointe(s) effacée(s).", "en": "attachment(s) deleted.", }, "Request every public URL of this database now?": { "fr": "Interroger maintenant toutes les URL publiques de cette base ?", "en": "Request every public URL of this database now?", }, "The sitemap listed no URL: nothing was tested.": { "fr": "Le sitemap n'a listé aucune URL : rien n'a été testé.", "en": "The sitemap listed no URL: nothing was tested.", }, "public URL(s) answered without error.": { "fr": "URL publique(s) ont répondu sans erreur.", "en": "public URL(s) answered without error.", }, "public URL(s) failed": { "fr": "URL publique(s) ont échoué", "en": "public URL(s) failed", }, "no answer": { "fr": "aucune réponse", "en": "no answer", }, "A page listed for search engines that does not answer is": { "fr": "Une page listée pour les moteurs de recherche qui ne répond pas est", "en": "A page listed for search engines that does not answer is", }, "a page your visitors do not reach either.": { "fr": "une page que vos visiteurs n'atteignent pas non plus.", "en": "a page your visitors do not reach either.", }, "The server never answered on": { "fr": "Le serveur n'a jamais répondu sur", "en": "The server never answered on", }, "Could not read": { "fr": "Impossible de lire", "en": "Could not read", }, "Starting Odoo on": { "fr": "Démarrage d'Odoo sur", "en": "Starting Odoo on", }, "port": { "fr": "port", "en": "port", }, "parent view(s) in cause": { "fr": "vue(s) parente(s) en cause", "en": "parent view(s) in cause", }, "Those parents are copies frozen on an older version;": { "fr": "Ces parents sont des copies figées sur une version antérieure ;", "en": "Those parents are copies frozen on an older version;", }, "resetting them onto the module view is the fix": { "fr": "les réinitialiser sur la vue module est le correctif", "en": "resetting them onto the module view is the fix", }, "No parent view named: nothing to offer.": { "fr": "Aucune vue parente nommée : rien à proposer.", "en": "No parent view named: nothing to offer.", }, "Copies to reset onto their module view": { "fr": "Copies à réinitialiser sur leur vue module", "en": "Copies to reset onto their module view", }, "Which one(s) to reset?": { "fr": "Laquelle ou lesquelles réinitialiser ?", "en": "Which one(s) to reset?", }, "Re-checked the": { "fr": "Revérification des", "en": "Re-checked the", }, "failing URL(s) after the reset": { "fr": "URL en échec après la réinitialisation", "en": "failing URL(s) after the reset", }, "Something already listens on port": { "fr": "Quelque chose écoute déjà sur le port", "en": "Something already listens on port", }, "it would be tested instead of this database.": { "fr": "il serait testé à la place de cette base.", "en": "it would be tested instead of this database.", }, "Enter =": { "fr": "Entrée =", "en": "Enter =", }, "No COW copy carries this key": { "fr": "Aucune copie COW ne porte cette clé", "en": "No COW copy carries this key", }, "already identical to the module view.": { "fr": "déjà identique à la vue module.", "en": "already identical to the module view.", }, "Odoo surfaces this when the module view is rewritten": { "fr": "Odoo le fait apparaître quand la vue module est réécrite", "en": "Odoo surfaces this when the module view is rewritten", }, "(a version bump) or when the page is rendered.": { "fr": "(un palier de version) ou quand la page est rendue.", "en": "(a version bump) or when the page is rendered.", }, "Before starting: what already answers, and what": { "fr": "Avant de commencer : ce qui répond déjà, et ce qui", "en": "Before starting: what already answers, and what", }, "does not. A page broken now will still be broken": { "fr": "ne répond pas. Une page cassée maintenant le sera encore", "en": "does not. A page broken now will still be broken", }, "after — and that is not the migration.": { "fr": "après — et ce ne sera pas la migration.", "en": "after — and that is not the migration.", }, "No child fails on this copy: it drifted without": { "fr": "Aucun enfant n'échoue sur cette copie : elle a dérivé sans", "en": "No child fails on this copy: it drifted without", }, "breaking anything yet.": { "fr": "encore rien casser.", "en": "breaking anything yet.", }, "These children no longer find their anchor in the copy": { "fr": "Ces enfants ne trouvent plus leur point d'ancrage dans la copie", "en": "These children no longer find their anchor in the copy", }, "The anchor exists in the module view": { "fr": "L'ancrage existe dans la vue module", "en": "The anchor exists in the module view", }, "but not in this copy, frozen on an older version.": { "fr": "mais pas dans cette copie, figée sur une version antérieure.", "en": "but not in this copy, frozen on an older version.", }, "Resetting restores the module arch; the customization the": { "fr": "Réinitialiser rend l'arch du module ; la personnalisation que", "en": "Resetting restores the module arch; the customization the", }, "copy carried is saved first, and is yours to re-apply as an": { "fr": "la copie portait est sauvegardée d'abord, à vous de la réappliquer en", "en": "copy carried is saved first, and is yours to re-apply as an", }, "INHERITING view with its own key.": { "fr": "vue HÉRITANTE avec sa propre clé.", "en": "INHERITING view with its own key.", }, "No module view carries this key: nothing to reset": { "fr": "Aucune vue module ne porte cette clé : rien sur quoi", "en": "No module view carries this key: nothing to reset", }, "onto.": { "fr": "réinitialiser.", "en": "onto.", }, "Browse the differences full screen": { "fr": "Parcourir les différences en plein écran", "en": "Browse the differences full screen", }, "The checkout is on Odoo": { "fr": "Le checkout est sur Odoo", "en": "The checkout is on Odoo", }, "and the database on": { "fr": "et la base sur", "en": "and the database on", }, "Opening it with the wrong version writes to it before": { "fr": "L'ouvrir avec la mauvaise version y écrit avant", "en": "Opening it with the wrong version writes to it before", }, "failing. Switch the checkout first.": { "fr": "d'échouer. Basculer le checkout d'abord.", "en": "failing. Switch the checkout first.", }, "Database cleanup on": { "fr": "Nettoyage de la base", "en": "Database cleanup on", }, "Cleaning": { "fr": "Nettoyage de", "en": "Cleaning", }, "pass": { "fr": "passe", "en": "pass", }, "purged": { "fr": "purgés", "en": "purged", }, "purged;": { "fr": "purgés ;", "en": "purged;", }, "could not be, and are left as they are": { "fr": "n'ont pas pu l'être, et restent en l'état", "en": "could not be, and are left as they are", }, "entries purged, nothing left.": { "fr": "entrées purgées, rien ne reste.", "en": "entries purged, nothing left.", }, "no such wizard in this version, skipped.": { "fr": "pas d'assistant pour cela dans cette version, ignoré.", "en": "no such wizard in this version, skipped.", }, "A database can carry leftovers nothing can remove.": { "fr": "Une base peut porter des restes que rien ne peut retirer.", "en": "A database can carry leftovers nothing can remove.", }, "This is a warning, not a failure.": { "fr": "C'est un avertissement, pas un échec.", "en": "This is a warning, not a failure.", }, "The cleanup produced no report.": { "fr": "Le nettoyage n'a produit aucun rapport.", "en": "The cleanup produced no report.", }, "Unreadable report": { "fr": "Rapport illisible", "en": "Unreadable report", }, "obsolete models": { "fr": "modèles obsolètes", "en": "obsolete models", }, "obsolete modules": { "fr": "modules obsolètes", "en": "obsolete modules", }, "obsolete columns": { "fr": "colonnes obsolètes", "en": "obsolete columns", }, "obsolete tables": { "fr": "tables obsolètes", "en": "obsolete tables", }, "obsolete data entries": { "fr": "entrées de données obsolètes", "en": "obsolete data entries", }, "obsolete menu entries": { "fr": "entrées de menu obsolètes", "en": "obsolete menu entries", }, "missing indexes": { "fr": "index manquants", "en": "missing indexes", }, "obsolete properties": { "fr": "propriétés obsolètes", "en": "obsolete properties", }, "entries would be purged": { "fr": "entrées seraient purgées", "en": "entries would be purged", }, "nothing was changed": { "fr": "rien n'a été modifié", "en": "nothing was changed", }, "Enter = 1": { "fr": "Entrée = 1", "en": "Enter = 1", }, "Enter = all, n = none": { "fr": "Entrée = tous, n = aucun", "en": "Enter = all, n = none", }, "Enter = delete, after saving them": { "fr": "Entrée = effacer, après les avoir sauvegardés", "en": "Enter = delete, after saving them", }, "Enter = neutralize now, reversible": { "fr": "Entrée = neutraliser maintenant, réversible", "en": "Enter = neutralize now, reversible", }, "Enter = reset them onto the module file": { "fr": "Entrée = les réinitialiser sur le fichier du module", "en": "Enter = reset them onto the module file", }, "Enter upgrades all addons of the": { "fr": "Entrée met à jour tous les modules de la", "en": "Enter upgrades all addons of the", }, "Open it at EVERY version bump, stop asking": { "fr": "L'ouvrir à CHAQUE palier de version, ne plus demander", "en": "Open it at EVERY version bump, stop asking", }, "Testing every bump, as chosen earlier.": { "fr": "Test à chaque palier, comme choisi plus tôt.", "en": "Testing every bump, as chosen earlier.", }, "numbers separated by commas, Enter = all, n =": { "fr": "numéros séparés par des virgules, Entrée = toutes, n =", "en": "numbers separated by commas, Enter = all, n =", }, "decide at the version bump": { "fr": "décider au palier de version", "en": "decide at the version bump", }, "keep": { "fr": "garder", "en": "keep", }, "The server did not serve the login page.": { "fr": "Le serveur n'a pas servi la page de connexion.", "en": "The server did not serve the login page.", }, "Wrong login or password for user": { "fr": "Identifiant ou mot de passe refusé pour l'utilisateur", "en": "Wrong login or password for user", }, "Could not read the menus": { "fr": "Impossible de lire les menus", "en": "Could not read the menus", }, "Apps opened as the test user": { "fr": "Applications ouvertes avec l'utilisateur test", "en": "Apps opened as the test user", }, "not openable this way (client or server": { "fr": "non ouvrables ainsi (action client ou", "en": "not openable this way (client or server", }, "action): nothing to render.": { "fr": "serveur) : rien à rendre.", "en": "action): nothing to render.", }, "opened with an empty domain: theirs": { "fr": "ouvertes avec un domaine vide : le leur", "en": "opened with an empty domain: theirs", }, "needs the browser to evaluate it.": { "fr": "demande le navigateur pour être évalué.", "en": "needs the browser to evaluate it.", }, "Every app opened its first page.": { "fr": "Chaque application a ouvert sa première page.", "en": "Every app opened its first page.", }, "Apps that failed to open": { "fr": "Applications qui n'ont pas pu s'ouvrir", "en": "Apps that failed to open", }, "reading the action": { "fr": "lecture de l'action", "en": "reading the action", }, "rendering the views": { "fr": "rendu des vues", "en": "rendering the views", }, "loading the first records": { "fr": "chargement des premiers enregistrements", "en": "loading the first records", }, "These are back-office failures: the public smoke test": { "fr": "Ce sont des échecs du back-office : le test de fumée public", "en": "These are back-office failures: the public smoke test", }, "cannot see them.": { "fr": "ne peut pas les voir.", "en": "cannot see them.", }, "Could not log in as": { "fr": "Connexion impossible en tant que", "en": "Could not log in as", }, "No": { "fr": "Aucun", "en": "No", }, "user in": { "fr": "utilisateur dans", "en": "user in", }, "the database was not neutralized, nothing to browse.": { "fr": "la base n'a pas été neutralisée, rien à parcourir.", "en": "the database was not neutralized, nothing to browse.", }, "Back office not browsed": { "fr": "Back-office non parcouru", "en": "Back office not browsed", }, "no test user: the database was not neutralized": { "fr": "pas d'utilisateur test : la base n'a pas été neutralisée", "en": "no test user: the database was not neutralized", }, "Could not tell whether the": { "fr": "Impossible de savoir si l'utilisateur", "en": "Could not tell whether the", }, "user exists in": { "fr": "existe dans", "en": "user exists in", }, "could not tell whether the test user exists": { "fr": "impossible de savoir si l'utilisateur test existe", "en": "could not tell whether the test user exists", }, "listing the model fields": { "fr": "inventaire des champs du modèle", "en": "listing the model fields", }, "model absent from the running registry": { "fr": "modèle absent du registre en cours", "en": "model absent from the running registry", }, "installed in the database, but its module code": { "fr": "installé dans la base, mais le code de son module", "en": "installed in the database, but its module code", }, "is not in this addons path.": { "fr": "n'est pas dans cet addons path.", "en": "is not in this addons path.", }, "Views naming a field the model no longer has": { "fr": "Vues nommant un champ que le modèle n'a plus", "en": "Views naming a field the model no longer has", }, "Public pages, then the back office as the test user": { "fr": "Les pages publiques, puis le back-office avec l'utilisateur test", "en": "Public pages, then the back office as the test user", }, "if the database was neutralized.": { "fr": "si la base a été neutralisée.", "en": "if the database was neutralized.", }, "Portal": { "fr": "Portail", "en": "Portal", }, "Portal pages opened as the test user": { "fr": "Pages du portail ouvertes avec l'utilisateur test", "en": "Portal pages opened as the test user", }, "not signed in": { "fr": "pas connecté", "en": "not signed in", }, "the page served was the login form": { "fr": "la page servie était le formulaire de connexion", "en": "the page served was the login form", }, "server log": { "fr": "journal du serveur", "en": "server log", }, "Purging modules reloads the whole registry: on a big": { "fr": "Purger les modules recharge tout le registre : sur un grand", "en": "Purging modules reloads the whole registry: on a big", }, "addons path this takes minutes, not seconds.": { "fr": "addons path cela prend des minutes, pas des secondes.", "en": "addons path this takes minutes, not seconds.", }, "Took": { "fr": "Durée :", "en": "Took", }, "seconds.": { "fr": "secondes.", "en": "seconds.", }, "The cleanup was still running after": { "fr": "Le nettoyage tournait encore après", "en": "The cleanup was still running after", }, "seconds and was stopped.": { "fr": "secondes et a été arrêté.", "en": "seconds and was stopped.", }, "the whole batch": { "fr": "le lot entier", "en": "the whole batch", }, "Still failing after": { "fr": "Échoue toujours après", "en": "Still failing after", }, "attempts: this one needs a developer.": { "fr": "tentatives : celle-ci demande un développeur.", "en": "attempts: this one needs a developer.", }, "Error detected. Choose, or ctrl+c to": { "fr": "Erreur détectée. Choisissez, ou ctrl+c pour", "en": "Error detected. Choose, or ctrl+c to", }, "stop": { "fr": "arrêter", "en": "stop", }, "Too many turns on this prompt: moving on.": { "fr": "Trop de tours sur cette invite : on passe.", "en": "Too many turns on this prompt: moving on.", }, "Please validate git commit on repos, press to": { "fr": "Veuillez valider les commits sur les dépôts, appuyez pour", "en": "Please validate git commit on repos, press to", }, "Check the migrated code, press to continue": { "fr": "Vérifiez le code migré, appuyez pour continuer", "en": "Check the migrated code, press to continue", }, "Please validate the repo is ready to run": { "fr": "Veuillez valider que le dépôt est prêt pour", "en": "Please validate the repo is ready to run", }, "press to continue": { "fr": "appuyez pour continuer", "en": "press to continue", }, "smoke_internal_ui.py is missing": { "fr": "smoke_internal_ui.py est absent", "en": "smoke_internal_ui.py is missing", }, "the test user is gone from a neutralized database: the back office was NOT checked": { "fr": "l'utilisateur test a disparu d'une base neutralisée : le back-office n'a PAS été vérifié", "en": "the test user is gone from a neutralized database: the back office was NOT checked", }, "Back office NOT browsed": { "fr": "Back-office NON parcouru", "en": "Back office NOT browsed", }, "Public pages, then the back office and /my as the": { "fr": "Les pages publiques, puis le back-office et /my avec", "en": "Public pages, then the back office and /my as the", }, "test user (neutralized database).": { "fr": "l'utilisateur test (base neutralisée).", "en": "test user (neutralized database).", }, "Public pages only:": { "fr": "Pages publiques seulement :", "en": "Public pages only:", }, "was not neutralized, so there is no test user to": { "fr": "n'a pas été neutralisée, il n'y a donc pas d'utilisateur test pour", "en": "was not neutralized, so there is no test user to", }, "sign in with.": { "fr": "s'y connecter.", "en": "sign in with.", }, "Migration state": { "fr": "État de la migration", "en": "Migration state", }, "started": { "fr": "démarrée", "en": "started", }, "last written": { "fr": "dernière écriture", "en": "last written", }, "current step": { "fr": "étape courante", "en": "current step", }, "Test results": { "fr": "Résultat des tests", "en": "Test results", }, "No tool has run yet.": { "fr": "Aucun outil n'a encore tourné.", "en": "No tool has run yet.", }, "Commands that failed": { "fr": "Commandes en échec", "en": "Commands that failed", }, "What was done, step by step": { "fr": "Ce qui a été fait, étape par étape", "en": "What was done, step by step", }, "runs": { "fr": "passages", "en": "runs", }, "nothing to report": { "fr": "rien à signaler", "en": "nothing to report", }, "findings to look at": { "fr": "des trouvailles à regarder", "en": "findings to look at", }, "the tool itself failed": { "fr": "l'outil lui-même a échoué", "en": "the tool itself failed", }, # Contexte fourni à Claude "Show the context given to Claude": { "fr": "🧠 Afficher le contexte fourni à Claude", "en": "🧠 Show the context given to Claude", }, "Context given to Claude": { "fr": "Contexte fourni à Claude", "en": "Context given to Claude", }, "Instructions": { "fr": "Instructions", "en": "Instructions", }, "Rules": { "fr": "Règles", "en": "Rules", }, "Skills": { "fr": "Skills", "en": "Skills", }, "Deployed commands": { "fr": "Commandes déployées", "en": "Deployed commands", }, "Git hooks": { "fr": "Hooks git", "en": "Git hooks", }, "missing": { "fr": "absent", "en": "missing", }, # Garde-fou du message de commit "the subject must start with a tag: %s": { "fr": "le sujet doit commencer par un tag : %s", "en": "the subject must start with a tag: %s", }, "the subject is %s characters, %s at most.\n" " Do not truncate it: at that length, write KEYWORDS that\n" " summarise rather than an amputated sentence. « proxmox: pmxcfs,\n" " storage, diagnosis » beats a sentence cut short.": { "fr": "le sujet fait %s caractères, %s au plus.\n" " Ne le tronquez pas : à cette longueur, écrivez des MOTS-CLÉS\n" " qui résument plutôt qu'une phrase amputée. « proxmox : pmxcfs,\n" " stockage, diagnostic » vaut mieux qu'une phrase coupée net.", "en": "the subject is %s characters, %s at most.\n" " Do not truncate it: at that length, write KEYWORDS that\n" " summarise rather than an amputated sentence. « proxmox: pmxcfs,\n" " storage, diagnosis » beats a sentence cut short.", }, "the subject opens on a quotation. A screen message is\n" " evidence: it belongs in the body. The subject names the cause.": { "fr": "le sujet s'ouvre sur une citation. Un message d'écran est une\n" " preuve : elle va dans le corps. Le sujet nomme la cause.", "en": "the subject opens on a quotation. A screen message is\n" " evidence: it belongs in the body. The subject names the cause.", }, "the marker is « --- EN --- ». The subject and the body under it\n" " are in English; « --- FR --- » opens the French translation.": { "fr": "le marqueur est « --- EN --- ». Le sujet et le corps qui le suit\n" " sont en anglais ; « --- FR --- » ouvre la traduction française.", "en": "the marker is « --- EN --- ». The subject and the body under it\n" " are in English; « --- FR --- » opens the French translation.", }, "the French section must open on the translated subject,\n" " under the same tag: %s": { "fr": "la section française doit s'ouvrir sur le sujet traduit,\n" " sous le même tag : %s", "en": "the French section must open on the translated subject,\n" " under the same tag: %s", }, "French subject: %s": { "fr": "sujet français : %s", "en": "French subject: %s", }, "the body is %s lines for one language, %s at most.\n" " The body says why it was necessary, then stops.\n" " The investigation, the dated measurements and the dead ends go\n" " to tasks/, which is not versioned.": { "fr": "le corps fait %s lignes pour une langue, %s au plus.\n" " Le corps dit pourquoi c'était nécessaire, puis s'arrête.\n" " L'enquête, les mesures datées et les impasses vont dans\n" " tasks/, qui n'est pas versionné.", "en": "the body is %s lines for one language, %s at most.\n" " The body says why it was necessary, then stops.\n" " The investigation, the dated measurements and the dead ends go\n" " to tasks/, which is not versioned.", }, "the body carries an IP address: %s.\n" " An address designates a machine. Name the CLASS of\n" " situation — « on a host behind a NAT » — not the machine.": { "fr": "le corps porte une adresse IP : %s.\n" " Une adresse désigne une machine. Nommez la CLASSE de\n" " situation — « sur un hôte derrière un NAT » — pas la machine.", "en": "the body carries an IP address: %s.\n" " An address designates a machine. Name the CLASS of\n" " situation — « on a host behind a NAT » — not the machine.", }, "the body carries an e-mail address: %s.": { "fr": "le corps porte une adresse de courriel : %s.", "en": "the body carries an e-mail address: %s.", }, "the body carries an account path: %s….\n" " Write ~/ or /home//.": { "fr": "le corps porte un chemin de compte : %s….\n" " Écrivez ~/ ou /home//.", "en": "the body carries an account path: %s….\n" " Write ~/ or /home//.", }, "the body carries a refused name: %s.\n" " Generalise — « on a production database » — or drop the\n" " sentence.": { "fr": "le corps porte un nom refusé : %s.\n" " Généralisez — « sur une base de production » — ou retirez la\n" " phrase.", "en": "the body carries a refused name: %s.\n" " Generalise — « on a production database » — or drop the\n" " sentence.", }, "commit-msg: no message file received": { "fr": "commit-msg : aucun fichier de message reçu", "en": "commit-msg: no message file received", }, "commit message off convention": { "fr": "message de commit hors convention", "en": "commit message off convention", }, "\n The rule: .claude/rules/04-code-conventions.md" "\n The manual: conf/template_claude_commands_commit.md" "\n Override for a legitimate case: git commit --no-verify\n": { "fr": "\n La règle : .claude/rules/04-code-conventions.md" "\n Le mode d'emploi : conf/template_claude_commands_commit.md" "\n Passer outre pour un cas légitime : git commit --no-verify\n", "en": "\n The rule: .claude/rules/04-code-conventions.md" "\n The manual: conf/template_claude_commands_commit.md" "\n Override for a legitimate case: git commit --no-verify\n", }, "up to date": { "fr": "à jour", "en": "up to date", }, "redeploy needed": { "fr": "à redéployer", "en": "redeploy needed", }, "not in the repository": { "fr": "absent du dépôt", "en": "not in the repository", }, "hook installed": { "fr": "installé", "en": "installed", }, "hook not installed": { "fr": "non installé", "en": "not installed", }, "%s identifying, %s to re-read — see .claude/rules/04-code-conventions.md": { "fr": "%s identifiant, %s à relire — voir .claude/rules/04-code-conventions.md", "en": "%s identifying, %s to re-read — see .claude/rules/04-code-conventions.md", }, "do the comments say how the code works, or where it came from": { "fr": "les commentaires disent-ils le fonctionnement, ou d'où ils viennent", "en": "do the comments say how the code works, or where it came from", }, "only the files added to the git index": { "fr": "seulement les fichiers ajoutés à l'index git", "en": "only the files added to the git index", }, "drop the narrative signals, keep the certain findings": { "fr": "laisser les signaux de récit, garder les trouvailles sûres", "en": "drop the narrative signals, keep the certain findings", }, "give a path, or --staged": { "fr": "donner un chemin, ou --staged", "en": "give a path, or --staged", }, # check_python_version.py partage « only the files added to the git # index » et « give a path, or --staged » avec check_comment_hygiene.py. "does this source parse under the repository Python": { "fr": "ce source parse-t-il sous le Python du dépôt", "en": "does this source parse under the repository Python", }, "no conf/python-erplibre-version: nothing checked": { "fr": "aucun conf/python-erplibre-version : rien vérifié", "en": "no conf/python-erplibre-version: nothing checked", }, "not checked (no Python %s): mise install python@%s": { "fr": "NON vérifié (aucun Python %s ici) : mise install python@%s", "en": "not checked (no Python %s): mise install python@%s", }, "%s file(s) refused by Python %s": { "fr": "%s fichier(s) refusé(s) par Python %s", "en": "%s file(s) refused by Python %s", }, "unknown result": { "fr": "résultat inconnu", "en": "unknown result", }, "before the first step": { "fr": "avant la première étape", "en": "before the first step", }, "No migration in progress.": { "fr": "Aucune migration en cours.", "en": "No migration in progress.", }, "show the migration state": { "fr": "afficher l'état de la migration", "en": "show the migration state", }, "Nothing to show yet.": { "fr": "Rien à montrer pour l'instant.", "en": "Nothing to show yet.", }, "(b = go back a step, t = show the migration state)": { "fr": "(b = revenir à une étape précédente," " t = afficher l'état de la migration)", "en": "(b = go back a step, t = show the migration state)", }, "Migration state (full screen)": { "fr": "État de la migration (plein écran)", "en": "Migration state (full screen)", }, "Export a backup?": { "fr": "Exporter une sauvegarde ?", "en": "Export a backup?", }, "or type filename.zip": { "fr": "ou tapez nomfichier.zip", "en": "or type filename.zip", }, "The login page itself failed": { "fr": "La page de connexion elle-même a échoué", "en": "The login page itself failed", }, "No CSRF token on the login page": { "fr": "Aucun jeton CSRF sur la page de connexion", "en": "No CSRF token on the login page", }, "after the reset": { "fr": "après la réinitialisation", "en": "after the reset", }, "The differential detection found nothing; resetting": { "fr": "La détection différentielle n'a rien trouvé ; réinitialisation", "en": "The differential detection found nothing; resetting", }, "the requested key(s) anyway.": { "fr": "de la ou des clés demandées malgré tout.", "en": "the requested key(s) anyway.", }, "lines": { "fr": "lignes", "en": "lines", }, "press l to show": { "fr": "l pour afficher", "en": "press l to show", }, "last": { "fr": "dernières", "en": "last", }, "Refresh": { "fr": "Rafraîchir", "en": "Refresh", }, "Logs": { "fr": "Journaux", "en": "Logs", }, "Panel": { "fr": "Panneau", "en": "Panel", }, "Wider": { "fr": "Élargir", "en": "Wider", }, "Narrower": { "fr": "Rétrécir", "en": "Narrower", }, "finished": { "fr": "terminée", "en": "finished", }, "duration": { "fr": "durée", "en": "duration", }, "Panels": { "fr": "Panneaux", "en": "Panels", }, "summary + list + detail": { "fr": "résumé + liste + détail", "en": "summary + list + detail", }, "list + detail": { "fr": "liste + détail", "en": "list + detail", }, "detail only": { "fr": "détail seul", "en": "detail only", }, "errors in the log": { "fr": "erreurs dans le journal", "en": "errors in the log", }, "Migration quality, step by step": { "fr": "Qualité de la migration, palier par palier", "en": "Migration quality, step by step", }, # --- Écran de qualité : Verdicts, Validation, Revue --- # --- Journal d'étape et bascule de version --- # --- Dérive du référentiel comptable --- "Did the last step add to the accounting data?": { "fr": "Le dernier palier a-t-il gonflé le référentiel comptable ?", "en": "Did the last step add to the accounting data?", }, "Accounting reference data, one step to the next": { "fr": "Référentiel comptable, d'un palier au suivant", "en": "Accounting reference data, one step to the next", }, "Nothing was added to the reference data.": { "fr": "Rien n'a été ajouté au référentiel.", "en": "Nothing was added to the reference data.", }, "Accounts in the chart": { "fr": "Comptes du plan comptable", "en": "Accounts in the chart", }, "Taxes": { "fr": "Taxes", "en": "Taxes", }, "Fiscal positions": { "fr": "Positions fiscales", "en": "Fiscal positions", }, "Account groups": { "fr": "Groupes de comptes", "en": "Account groups", }, "Journals": { "fr": "Journaux", "en": "Journals", }, "What it looks like": { "fr": "À quoi cela ressemble", "en": "What it looks like", }, "accounts carry no entry at all": { "fr": "comptes ne portent aucune écriture", "en": "accounts carry no entry at all", }, "taxes share a name with another": { "fr": "taxes portent le nom d'une autre", "en": "taxes share a name with another", }, "fiscal positions share a name with another": { "fr": "positions fiscales portent le nom d'une autre", "en": "fiscal positions share a name with another", }, "accounts fall under a group by code prefix": { "fr": "comptes tombent sous un groupe par préfixe de code", "en": "accounts fall under a group by code prefix", }, "Replay the step with the fix; do not operate the": { "fr": "Rejouer le palier avec le correctif ; ne pas opérer la", "en": "Replay the step with the fix; do not operate the", }, "delivered database.": { "fr": "base livrée.", "en": "delivered database.", }, "What a version bump adds to the accounting data.": { "fr": "Ce qu'une montée de version ajoute au référentiel comptable.", "en": "What a version bump adds to the accounting data.", }, "the step to compare against (default: the previous one)": { "fr": "le palier de comparaison (défaut : le précédent)", "en": "the step to compare against (default: the previous one)", }, "No previous step found: name it with --before.": { "fr": "Aucun palier précédent trouvé : le nommer avec --before.", "en": "No previous step found: name it with --before.", }, "A reloaded chart template adds every account it could not match by code. They carry no entry, and they bury the customer's own chart.": { "fr": "Un gabarit de plan rechargé ajoute chaque compte qu'il n'a pu apparier par son code. Ils ne portent aucune écriture, et noient le plan du client.", "en": "A reloaded chart template adds every account it could not match by code. They carry no entry, and they bury the customer's own chart.", }, "Reloaded taxes are not renamed '[old]': the duplicates are indistinguishable in the interface.": { "fr": "Les taxes rechargées ne sont pas renommées « [old] » : les doublons ne se distinguent pas dans l'interface.", "en": "Reloaded taxes are not renamed '[old]': the duplicates are indistinguishable in the interface.", }, "Each province then appears twice, under the same name.": { "fr": "Chaque province apparaît alors deux fois, sous le même nom.", "en": "Each province then appears twice, under the same name.", }, "Groups are matched to accounts by code PREFIX: a grid that appears reclassifies the customer's own accounts, and the trial balance in hierarchy mode follows.": { "fr": "Les groupes s'apparient aux comptes par PRÉFIXE de code : une grille qui apparaît reclasse les comptes du client, et la balance en mode hiérarchie suit.", "en": "Groups are matched to accounts by code PREFIX: a grid that appears reclassifies the customer's own accounts, and the trial balance in hierarchy mode follows.", }, "A journal added by a template reload competes with the customer's own.": { "fr": "Un journal ajouté par un rechargement concurrence celui du client.", "en": "A journal added by a template reload competes with the customer's own.", }, "findings": { "fr": "des trouvailles", "en": "findings", }, "the tool failed": { "fr": "l'outil a échoué", "en": "the tool failed", }, "capture unavailable": { "fr": "capture indisponible", "en": "capture unavailable", }, "last run": { "fr": "dernière exécution", "en": "last run", }, "never run from here yet": { "fr": "jamais lancée depuis ici", "en": "never run from here yet", }, "Pane up": { "fr": "Panneau ↑", "en": "Pane up", }, "Pane down": { "fr": "Panneau ↓", "en": "Pane down", }, "the tool output is not in the step log: it goes": { "fr": "la sortie de l'outil n'est pas dans le journal d'étape : elle part", "en": "the tool output is not in the step log: it goes", }, "to the terminal and dies with it.": { "fr": "sur le terminal et meurt avec lui.", "en": "to the terminal and dies with it.", }, "r offers to run": { "fr": "r propose de lancer", "en": "r offers to run", }, "first": { "fr": "d'abord", "en": "first", }, "step log": { "fr": "journal de l'étape", "en": "step log", }, "no log file for this step": { "fr": "aucun journal pour cette étape", "en": "no log file for this step", }, "lines in all": { "fr": "lignes en tout", "en": "lines in all", }, "this verdict is not in it": { "fr": "ce verdict n'y figure pas", "en": "this verdict is not in it", }, "the tool output is not in there: it goes to the": { "fr": "la sortie de l'outil n'y est pas : elle part sur le", "en": "the tool output is not in there: it goes to the", }, "terminal, which a pipe would make full-screen tools": { "fr": "terminal, qu'un tube ferait renoncer aux outils en", "en": "terminal, which a pipe would make full-screen tools", }, "give up. What precedes is what Odoo was writing.": { "fr": "plein écran. Ce qui précède est ce qu'Odoo écrivait.", "en": "give up. What precedes is what Odoo was writing.", }, "the checkout is on Odoo": { "fr": "le checkout est sur Odoo", "en": "the checkout is on Odoo", }, "this database is on": { "fr": "cette base est en", "en": "this database is on", }, "opening it with the wrong version writes before it fails.": { "fr": "l'ouvrir avec la mauvaise version y écrit avant d'échouer.", "en": "opening it with the wrong version writes before it fails.", }, "run": { "fr": "lancer", "en": "run", }, "first?": { "fr": "d'abord ?", "en": "first?", }, "left as is — the test will refuse and return 2.": { "fr": "laissé tel quel — le test refusera et rendra 2.", "en": "left as is — the test will refuse and return 2.", }, "run the test anyway?": { "fr": "lancer le test quand même ?", "en": "run the test anyway?", }, # --- Trous dans les manifestes Google Repo --- # --- Type de vue « tree » resté dans un module --- "Is any module still on a pre-18 view type?": { "fr": "Un module est-il resté sur un type de vue d'avant 18 ?", "en": "Is any module still on a pre-18 view type?", }, "View type tree, removed in Odoo 18": { "fr": "Type de vue tree, supprimé dans Odoo 18", "en": "View type tree, removed in Odoo 18", }, "nothing to do below 18.0 — tree is valid there": { "fr": "rien à faire sous la 18.0 — tree y est valide", "en": "nothing to do below 18.0 — tree is valid there", }, "No module carries it.": { "fr": "Aucun module ne le porte.", "en": "No module carries it.", }, "modules read": { "fr": "modules lus", "en": "modules read", }, "listed in the manifest, absent from disk": { "fr": "listés au manifeste, absents du disque", "en": "listed in the manifest, absent from disk", }, "listed in the manifest, unparsable": { "fr": "listés au manifeste, illisibles", "en": "listed in the manifest, unparsable", }, "Modules still carrying the removed tree view type.": { "fr": "Modules portant encore le type de vue tree, supprimé.", "en": "Modules still carrying the removed tree view type.", }, "Will every step find its addons?": { "fr": "Chaque palier trouvera-t-il ses addons ?", "en": "Will every step find its addons?", }, "Repositories missing from a step": { "fr": "Dépôts absents d'un palier", "en": "Repositories missing from a step", }, "Every repository is declared without a hole.": { "fr": "Chaque dépôt est déclaré sans trou.", "en": "Every repository is declared without a hole.", }, "missing from": { "fr": "absent de", "en": "missing from", }, "upstream has the branch": { "fr": "la branche existe en amont", "en": "upstream has the branch", }, "Add the entry to": { "fr": "Ajouter l'entrée dans", "en": "Add the entry to", }, "holes not settled": { "fr": "trous non départagés", "en": "holes not settled", }, "not asked: run with --upstream": { "fr": "pas demandé : relancer avec --upstream", "en": "not asked: run with --upstream", }, "upstream unreachable": { "fr": "amont injoignable", "en": "upstream unreachable", }, "holes are legitimate: no such branch upstream": { "fr": "trous légitimes : pas de telle branche en amont", "en": "holes are legitimate: no such branch upstream", }, "Repositories declared for some steps but not others.": { "fr": "Dépôts déclarés pour certains paliers et pas d'autres.", "en": "Repositories declared for some steps but not others.", }, "ask each remote whether the branch exists (network)": { "fr": "demander à chaque amont si la branche existe (réseau)", "en": "ask each remote whether the branch exists (network)", }, "Verdicts the migration recorded": { "fr": "Verdicts enregistrés par la migration", "en": "Verdicts the migration recorded", }, "recorded in": { "fr": "consignés dans", "en": "recorded in", }, "These come from the file, not the database:": { "fr": "Ils viennent du fichier, non de la base :", "en": "These come from the file, not the database:", }, "the exit code ignores them.": { "fr": "le code de sortie ne les compte pas.", "en": "the exit code ignores them.", }, # Les six questions de la revue : t() les reçoit par # variable, un scan des littéraux ne les voyait pas. "Did the migration reach the end?": { "fr": "La migration est-elle allée jusqu'au bout ?", "en": "Did the migration reach the end?", }, "Does Odoo load the database?": { "fr": "Odoo charge-t-il la base ?", "en": "Does Odoo load the database?", }, "What did the migration leave behind?": { "fr": "Qu'est-ce que la migration a laissé derrière ?", "en": "What did the migration leave behind?", }, "Is this copy safe to open?": { "fr": "Cette copie est-elle sans danger à ouvrir ?", "en": "Is this copy safe to open?", }, "Do the public pages still answer?": { "fr": "Les pages publiques répondent-elles encore ?", "en": "Do the public pages still answer?", }, "Is anything left that cleanup could not drop?": { "fr": "Reste-t-il ce que le nettoyage n'a pu supprimer ?", "en": "Is anything left that cleanup could not drop?", }, "Verdicts": { "fr": "Verdicts", "en": "Verdicts", }, "Validation": { "fr": "Validation", "en": "Validation", }, "Review": { "fr": "Revue de la migration", "en": "Review", }, "no verdict recorded": { "fr": "aucun verdict enregistré", "en": "no verdict recorded", }, "checks, all passed": { "fr": "tests, tous réussis", "en": "checks, all passed", }, "step": { "fr": "palier", "en": "step", }, "when": { "fr": "quand", "en": "when", }, "status": { "fr": "statut", "en": "status", }, "what it ran": { "fr": "ce qu'il a lancé", "en": "what it ran", }, "1 means a public page failed — not merely a finding.": { "fr": "1 signifie qu'une page publique a échoué — pas un simple constat.", "en": "1 means a public page failed — not merely a finding.", }, "1 means leftovers remain that it could not drop.": { "fr": "1 signifie qu'il reste des objets qu'il n'a pu supprimer.", "en": "1 means leftovers remain that it could not drop.", }, "press r to run it again": { "fr": "appuie sur r pour le relancer", "en": "press r to run it again", }, "The screen steps aside, the test takes the terminal,": { "fr": "L'écran s'efface, le test prend le terminal,", "en": "The screen steps aside, the test takes the terminal,", }, "and you come back with Enter.": { "fr": "et tu reviens avec Entrée.", "en": "and you come back with Enter.", }, "No known way to replay this one.": { "fr": "Aucun moyen connu de rejouer celui-ci.", "en": "No known way to replay this one.", }, "The migration recorded no verdict.": { "fr": "La migration n'a enregistré aucun verdict.", "en": "The migration recorded no verdict.", }, "Every recorded check returned zero.": { "fr": "Chaque test enregistré a rendu zéro.", "en": "Every recorded check returned zero.", }, "Where the traces live": { "fr": "Où vivent les traces", "en": "Where the traces live", }, "missing: nothing was written here": { "fr": "absent : rien n'a été écrit ici", "en": "missing: nothing was written here", }, "To read the verdicts by hand:": { "fr": "Pour lire les verdicts à la main :", "en": "To read the verdicts by hand:", }, "Verdicts live in lst_event of the progression file,": { "fr": "Les verdicts vivent dans lst_event du fichier de", "en": "Verdicts live in lst_event of the progression file,", }, "not in command_executed, which only lists what ran.": { "fr": "progression — command_executed ne liste que l'exécuté.", "en": "not in command_executed, which only lists what ran.", }, "Errors in the Odoo log": { "fr": "Erreurs dans le journal d'Odoo", "en": "Errors in the Odoo log", }, "This file does not exist.": { "fr": "Ce fichier n'existe pas.", "en": "This file does not exist.", }, "config.conf has an empty logfile=, so Odoo writes to": { "fr": "config.conf a un logfile= vide : Odoo écrit dans le", "en": "config.conf has an empty logfile=, so Odoo writes to", }, "the terminal and its output dies with it. To keep it:": { "fr": "terminal et sa sortie meurt avec lui. Pour la garder :", "en": "the terminal and its output dies with it. To keep it:", }, "last offending lines": { "fr": "dernières lignes fautives", "en": "last offending lines", }, "press r to run it": { "fr": "appuie sur r pour le lancer", "en": "press r to run it", }, "Read it in the Verdicts section above.": { "fr": "À lire dans la section Verdicts ci-dessus.", "en": "Read it in the Verdicts section above.", }, "What none of these can see": { "fr": "Ce qu'aucun d'eux ne voit", "en": "What none of these can see", }, "They all read the DATABASE. A module that kept a": { "fr": "Tous lisent la BASE. Un module resté sur un type de", "en": "They all read the DATABASE. A module that kept a", }, "pre-18 view type, or an image URL Odoo no longer": { "fr": "vue d'avant 18, ou une URL d'image qu'Odoo", "en": "pre-18 view type, or an image URL Odoo no longer", }, "accepts, breaks at runtime on a perfectly sound one.": { "fr": "refuse désormais, casse à l'exécution sur une base saine.", "en": "accepts, breaks at runtime on a perfectly sound one.", }, "exit code:": { "fr": "code de sortie :", "en": "exit code:", }, "Press Enter to go back to the screen…": { "fr": "Appuie sur Entrée pour revenir à l'écran…", "en": "Press Enter to go back to the screen…", }, "Pick a line below.": { "fr": "Choisis une ligne ci-dessous.", "en": "Pick a line below.", }, "Migration progression": { "fr": "Progression de la migration", "en": "Migration progression", }, "Odoo log": { "fr": "Journal d'Odoo", "en": "Odoo log", }, "steps, commands and their verdicts (lst_event)": { "fr": "paliers, commandes et leurs verdicts (lst_event)", "en": "steps, commands and their verdicts (lst_event)", }, "set logfile= in config.conf, else output is lost": { "fr": "poser logfile= dans config.conf, sinon la sortie est perdue", "en": "set logfile= in config.conf, else output is lost", }, "database not found": { "fr": "base introuvable", "en": "database not found", }, "attachment files missing from the filestore": { "fr": "fichiers de pièces jointes absents du filestore", "en": "attachment files missing from the filestore", }, "From start to finish": { "fr": "Du départ à l'arrivée", "en": "From start to finish", }, "not comparable: a database is missing": { "fr": "non comparable : une base manque", "en": "not comparable: a database is missing", }, "probable table rename(s)": { "fr": "renommage(s) de table probable(s)", "en": "probable table rename(s)", }, "table(s) lost rows": { "fr": "table(s) ont perdu des lignes", "en": "table(s) lost rows", }, "attachments": { "fr": "pièces jointes", "en": "attachments", }, "probably renamed to": { "fr": "probablement renommée en", "en": "probably renamed to", }, "steps": { "fr": "paliers", "en": "steps", }, "Migration": { "fr": "🚚 Migration", "en": "🚚 Migration", }, "Quality of a migration, step by step": { "fr": "📐 Qualité d'une migration, palier par palier", "en": "📐 Quality of a migration, step by step", }, "Quality": { "fr": "Qualité", "en": "Quality", }, "Already inside a running screen: open it in its own": { "fr": "Déjà dans un écran en cours : l'ouvrir dans son propre", "en": "Already inside a running screen: open it in its own", }, "process instead.": { "fr": "processus.", "en": "process instead.", }, "Missing files": { "fr": "Fichiers absents", "en": "Missing files", }, "every attachment file is present": { "fr": "tous les fichiers de pièces jointes sont présents", "en": "every attachment file is present", }, "Could not read their metadata.": { "fr": "Impossible de lire leurs métadonnées.", "en": "Could not read their metadata.", }, "by model and field": { "fr": "par modèle et par champ", "en": "by model and field", }, "one by one": { "fr": "un par un", "en": "one by one", }, "press m to list them": { "fr": "m pour en voir la liste", "en": "press m to list them", }, "Pick a step to see its missing files.": { "fr": "Choisissez un palier pour voir ses fichiers absents.", "en": "Pick a step to see its missing files.", }, "table(s) lost rows, unexplained": { "fr": "table(s) ont perdu des lignes, sans explication", "en": "table(s) lost rows, unexplained", }, "table(s) explained by an Odoo change": { "fr": "table(s) expliquées par un changement d'Odoo", "en": "table(s) explained by an Odoo change", }, "Cannot read the database: ": { "fr": "Lecture impossible de la base : ", "en": "Cannot read the database: ", }, "Cannot read the package file: ": { "fr": "Lecture impossible du fichier de packages : ", "en": "Cannot read the package file: ", }, "Modules missing from the default package": { "fr": "📦 Modules absents du package par défaut", "en": "📦 Modules missing from the default package", }, "Dependencies between modules": { "fr": "🔗 Dépendances entre les modules", "en": "🔗 Dependencies between modules", }, "Website copies that can no longer render": { "fr": "Copies de site qui ne savent plus se rendre", "en": "Website copies that can no longer render", }, "Every website copy still renders.": { "fr": "Chaque copie de site sait encore se rendre.", "en": "Every website copy still renders.", }, "No duplicate index.": { "fr": "Aucun index en double.", "en": "No duplicate index.", }, "attachments of fields and records already gone": { "fr": "pièces jointes de champs et d'enregistrements déjà disparus", "en": "attachments of fields and records already gone", }, "their field was already gone before this step": { "fr": "leur champ porteur avait déjà disparu avant ce palier", "en": "their field was already gone before this step", }, "their field was removed at this step": { "fr": "leur champ porteur a été retiré à ce palier", "en": "their field was removed at this step", }, "their model left the database": { "fr": "leur modèle a quitté la base", "en": "their model left the database", }, "the field is STILL there — look at these": { "fr": "le champ est TOUJOURS là — à regarder", "en": "the field is STILL there — look at these", }, "out of": { "fr": "sur", "en": "out of", }, "Every witness is an administrator: a model only": { "fr": "Tous les témoins sont administrateurs : un modèle que seuls les", "en": "Every witness is an administrator: a model only", }, "admins can read passes this test.": { "fr": "administrateurs peuvent lire passe ce test.", "en": "admins can read passes this test.", }, "Reads ir_rule only — masking coded in Python escapes it.": { "fr": "Ne lit qu'ir_rule — un masquage codé en Python lui échappe.", "en": "Reads ir_rule only — masking coded in Python escapes it.", }, "held no data of their own — nothing to lose": { "fr": "sans donnée propre — rien à perdre", "en": "held no data of their own — nothing to lose", }, "Configuration records a migration never recreates": { "fr": "Réglages qu'une migration ne recrée jamais", "en": "Configuration records a migration never recreates", }, "Every default configuration record is there.": { "fr": "Chaque réglage par défaut est en place.", "en": "Every default configuration record is there.", }, "No pricelist, and the pricelist feature is on.": { "fr": "Aucune liste de prix, alors que la fonctionnalité est active.", "en": "No pricelist, and the pricelist feature is on.", }, "Every quotation opens without one: raw price, no rule.": { "fr": "Tout devis s'ouvre sans liste : prix brut, aucune règle.", "en": "Every quotation opens without one: raw price, no rule.", }, "No bank reconciliation model, for": { "fr": "Aucun modèle de rapprochement bancaire, pour", "en": "No bank reconciliation model, for", }, "cash/bank journal(s).": { "fr": "journal(aux) de trésorerie.", "en": "cash/bank journal(s).", }, "Every statement line is matched by hand.": { "fr": "Chaque ligne de relevé se lettre à la main.", "en": "Every statement line is matched by hand.", }, "Use --apply to let Odoo recreate them.": { "fr": "Utiliser --apply pour laisser Odoo les recréer.", "en": "Use --apply to let Odoo recreate them.", }, "pricelists:": { "fr": "listes de prix :", "en": "pricelists:", }, "reconcile models:": { "fr": "modèles de rapprochement :", "en": "reconcile models:", }, "Odoo recreated them.": { "fr": "Odoo les a recréés.", "en": "Odoo recreated them.", }, "Still missing after the repair.": { "fr": "Il en manque encore après la réparation :", "en": "Still missing after the repair.", }, "duplicate index pair(s)": { "fr": "paire(s) d'index en double", "en": "duplicate index pair(s)", }, "safe to drop": { "fr": "sans risque à supprimer", "en": "safe to drop", }, "drop": { "fr": "supprimer", "en": "drop", }, "backed by a constraint — left alone": { "fr": "adossée(s) à une contrainte — laissée(s) en place", "en": "backed by a constraint — left alone", }, "neither name follows the convention — your call": { "fr": "sans convention reconnaissable — à vous de juger", "en": "neither name follows the convention — your call", }, "Use --apply to drop them.": { "fr": "Utiliser --apply pour les supprimer.", "en": "Use --apply to drop them.", }, "Duplicate indexes dropped.": { "fr": "Index en double supprimés.", "en": "Duplicate indexes dropped.", }, "Some duplicates are still there.": { "fr": "Des doublons subsistent.", "en": "Some duplicates are still there.", }, "website COW view(s) will survive the bump and then fail": { "fr": "vue(s) COW de site passeront le palier puis échoueront", "en": "website COW view(s) will survive the bump and then fail", }, "to render:": { "fr": "à se rendre :", "en": "to render:", }, "Repair rather than neutralize — the copy holds a page": { "fr": "Réparer plutôt que neutraliser — la copie porte une page", "en": "Repair rather than neutralize — the copy holds a page", }, "someone wrote:": { "fr": "écrite par quelqu'un :", "en": "someone wrote:", }, "Every website copy renders again.": { "fr": "Chaque copie de site sait de nouveau se rendre.", "en": "Every website copy renders again.", }, "Some copies still cannot render.": { "fr": "Des copies ne savent toujours pas se rendre.", "en": "Some copies still cannot render.", }, "anchor missing for view": { "fr": "ancrage absent pour la vue", "en": "anchor missing for view", }, "calls a template that is gone:": { "fr": "appelle un gabarit disparu :", "en": "calls a template that is gone:", }, "repair(s) available with --apply": { "fr": "réparation(s) possible(s) avec --apply", "en": "repair(s) available with --apply", }, "cannot be repaired automatically": { "fr": "ne se réparent pas toutes seules", "en": "cannot be repaired automatically", }, "Removing a call removes its block from the page.": { "fr": "Retirer un appel retire son bloc de la page.", "en": "Removing a call removes its block from the page.", }, "modules installed": { "fr": "modules installés", "en": "modules installed", }, "of them installed": { "fr": "installé(s)", "en": "of them installed", }, "nothing installed depends on it": { "fr": "rien d'installé n'en dépend", "en": "nothing installed depends on it", }, "Reading the modules and their dependencies…": { "fr": "Lecture des modules et de leurs dépendances…", "en": "Reading the modules and their dependencies…", }, "Modules and their dependencies": { "fr": "Modules et leurs dépendances", "en": "Modules and their dependencies", }, "unknown to this database": { "fr": "inconnu de cette base", "en": "unknown to this database", }, "state": { "fr": "état", "en": "state", }, "author": { "fr": "auteur", "en": "author", }, "application": { "fr": "application", "en": "application", }, "yes": { "fr": "oui", "en": "yes", }, "depends on": { "fr": "dépend de", "en": "depends on", }, "needed by": { "fr": "requis par", "en": "needed by", }, "absent": { "fr": "absent", "en": "absent", }, "press d to walk the dependencies": { "fr": "appuyez sur d pour parcourir les dépendances", "en": "press d to walk the dependencies", }, "installed on missing dependencies": { "fr": "installé sur des dépendances absentes", "en": "installed on missing dependencies", }, "broken dependency(ies)": { "fr": "dépendance(s) cassée(s)", "en": "broken dependency(ies)", }, "What it needs, directly": { "fr": "Ce dont il a besoin, directement", "en": "What it needs, directly", }, "What needs it, directly": { "fr": "Ce qui en a besoin, directement", "en": "What needs it, directly", }, "Everything it pulls in": { "fr": "Tout ce qu'il entraîne", "en": "Everything it pulls in", }, "Everything that falls with it": { "fr": "Tout ce qui tombe avec lui", "en": "Everything that falls with it", }, "all modules": { "fr": "tous les modules", "en": "all modules", }, "installed only": { "fr": "installés seulement", "en": "installed only", }, "not installed": { "fr": "non installés", "en": "not installed", }, "broken dependencies": { "fr": "dépendances cassées", "en": "broken dependencies", }, "in progress": { "fr": "en cours", "en": "in progress", }, "apps only": { "fr": "applications seulement", "en": "apps only", }, "left in a transient state": { "fr": "laissés dans un état de passage", "en": "left in a transient state", }, "Installed": { "fr": "Installés", "en": "Installed", }, "In progress": { "fr": "En cours", "en": "In progress", }, "Apps": { "fr": "Applications", "en": "Apps", }, "Dependencies": { "fr": "Dépendances", "en": "Dependencies", }, "Filter": { "fr": "Filtre", "en": "Filter", }, "Search": { "fr": "Chercher", "en": "Search", }, "module": { "fr": "module", "en": "module", }, "module name…": { "fr": "nom de module…", "en": "module name…", }, "Show every entry": { "fr": "📜 Tout afficher", "en": "📜 Show every entry", }, "List the known packages": { "fr": "📚 Lister les packages connus", "en": "📚 List the known packages", }, "Already repaired: the group exists.": { "fr": "Déjà réparé : le groupe existe.", "en": "Already repaired: the group exists.", }, "DMS access groups:": { "fr": "Groupes d'accès DMS :", "en": "DMS access groups:", }, "DMS documents in the database": { "fr": "Documents DMS dans la base", "en": "DMS documents in the database", }, "No DMS user to test visibility with.": { "fr": "Aucun utilisateur DMS pour éprouver la visibilité.", "en": "No DMS user to test visibility with.", }, "Nothing written. Re-run with --apply.": { "fr": "Rien d'écrit. Relancer avec --apply.", "en": "Nothing written. Re-run with --apply.", }, "Now visible to": { "fr": "Désormais visibles pour", "en": "Now visible to", }, "Visible to": { "fr": "Visibles pour", "en": "Visible to", }, "Would create one access group over": { "fr": "Créerait un groupe d'accès sur", "en": "Would create one access group over", }, "file(s)": { "fr": "fichier(s)", "en": "file(s)", }, "folder(s)": { "fr": "dossier(s)", "en": "folder(s)", }, "root folder(s)": { "fr": "dossier(s) racine", "en": "root folder(s)", }, "No DMS in this database, nothing to repair.": { "fr": "Pas de DMS dans cette base, rien à réparer.", "en": "No DMS in this database, nothing to repair.", }, "Every one of them is visible to someone.": { "fr": "Chacun est visible par quelqu'un.", "en": "Every one of them is visible to someone.", }, "No internal user to test visibility with.": { "fr": "Aucun utilisateur interne pour éprouver la visibilité.", "en": "No internal user to test visibility with.", }, "The data is there; a global rule hides all of it.": { "fr": "Les données sont là ; une règle globale les masque entièrement.", "en": "The data is there; a global rule hides all of it.", }, "checked against": { "fr": "éprouvés avec", "en": "checked against", }, "internal user(s)": { "fr": "utilisateur(s) interne(s)", "en": "internal user(s)", }, "model(s) nobody can see a single row of": { "fr": "modèle(s) dont personne ne voit une seule ligne", "en": "model(s) nobody can see a single row of", }, "model(s) with a global rule and some data,": { "fr": "modèle(s) avec une règle globale et des données,", "en": "model(s) with a global rule and some data,", }, "row(s)": { "fr": "ligne(s)", "en": "row(s)", }, "Against OpenUpgrade": { "fr": "Face à OpenUpgrade", "en": "Against OpenUpgrade", }, "NOT declared by OpenUpgrade": { "fr": "NON déclarés par OpenUpgrade", "en": "NOT declared by OpenUpgrade", }, "No OpenUpgrade analysis for this step.": { "fr": "Pas d'analyse OpenUpgrade pour ce palier.", "en": "No OpenUpgrade analysis for this step.", }, "became a per-company jsonb column": { "fr": "passés en colonne jsonb par société", "en": "became a per-company jsonb column", }, "computed now — the field remains, the column does not": { "fr": "devenus calculés — le champ demeure, la colonne non", "en": "computed now — the field remains, the column does not", }, "core module(s) analysed": { "fr": "module(s) cœur analysé(s)", "en": "core module(s) analysed", }, "declared obsolete": { "fr": "déclarés obsolètes", "en": "declared obsolete", }, "declared removed": { "fr": "déclarés supprimés", "en": "declared removed", }, "field(s) lost": { "fr": "champ(s) perdu(s)", "en": "field(s) lost", }, "model(s) lost": { "fr": "modèle(s) perdu(s)", "en": "model(s) lost", }, "moved to another module": { "fr": "déplacés vers un autre module", "en": "moved to another module", }, "renamed by Odoo": { "fr": "renommés par Odoo", "en": "renamed by Odoo", }, "their model went away too": { "fr": "leur modèle a disparu aussi", "en": "their model went away too", }, "in a module OpenUpgrade does not analyse": { "fr": "dans un module qu'OpenUpgrade n'analyse pas", "en": "in a module OpenUpgrade does not analyse", }, "model(s)": { "fr": "modèle(s)", "en": "model(s)", }, "other field name(s)": { "fr": "autre(s) nom(s) de champ", "en": "other field name(s)", }, "Filestore of": { "fr": "Filestore de", "en": "Filestore of", }, "file(s) missing": { "fr": "fichier(s) absent(s)", "en": "file(s) missing", }, "file(s) on disk": { "fr": "fichier(s) sur disque", "en": "file(s) on disk", }, "file(s) sit in nested filestores Odoo never reads.": { "fr": "fichier(s) échoué(s) dans des filestores imbriqués qu'Odoo ne lit jamais.", "en": "file(s) sit in nested filestores Odoo never reads.", }, "intact in another database's filestore": { "fr": "intacts dans le filestore d'une autre base", "en": "intact in another database's filestore", }, "its field no longer exists — nothing reads it": { "fr": "leur champ n'existe plus — rien ne les lit", "en": "its field no longer exists — nothing reads it", }, "nowhere to be found — truly lost": { "fr": "introuvables — réellement perdus", "en": "nowhere to be found — truly lost", }, "still in a backup zip": { "fr": "encore dans une sauvegarde zip", "en": "still in a backup zip", }, "stored attachment(s)": { "fr": "pièce(s) jointe(s) stockée(s)", "en": "stored attachment(s)", }, "stranded in a nested filestore Odoo never reads": { "fr": "échoués dans un filestore imbriqué qu'Odoo ne lit pas", "en": "stranded in a nested filestore Odoo never reads", }, "Files": { "fr": "Fichiers", "en": "Files", }, "Attachment files missing from the filestore": { "fr": "🗄 Fichiers de pièces jointes absents du filestore", "en": "🗄 Attachment files missing from the filestore", }, "Scanning filestores and backups…": { "fr": "Examen des filestores et des sauvegardes…", "en": "Scanning filestores and backups…", }, "Filestore restored:": { "fr": "Filestore restauré :", "en": "Filestore restored:", }, "file(s) in place": { "fr": "fichier(s) en place", "en": "file(s) in place", }, "Filestore restore looks wrong for": { "fr": "Restauration du filestore suspecte pour", "en": "Filestore restore looks wrong for", }, "landed in a nested filestore Odoo never reads": { "fr": "atterris dans un filestore imbriqué qu'Odoo ne lit jamais", "en": "landed in a nested filestore Odoo never reads", }, "To fix:": { "fr": "Pour corriger :", "en": "To fix:", }, "never landed at all": { "fr": "ne sont arrivés nulle part", "en": "never landed at all", }, "record still exists": { "fr": "l'enregistrement existe encore", "en": "record still exists", }, "record is gone — nothing will miss it": { "fr": "l'enregistrement a disparu — personne ne la cherchera", "en": "record is gone — nothing will miss it", }, "Delete these": { "fr": "Supprimer ces", "en": "Delete these", }, "Directory:": { "fr": "Dossier :", "en": "Directory:", }, "No nested filestore to tidy.": { "fr": "Pas de filestore imbriqué à ranger.", "en": "No nested filestore to tidy.", }, "Nothing to purge.": { "fr": "Rien à purger.", "en": "Nothing to purge.", }, "Nothing was deleted.": { "fr": "Rien n'a été supprimé.", "en": "Nothing was deleted.", }, "Nothing was moved.": { "fr": "Rien n'a été déplacé.", "en": "Nothing was moved.", }, "The purge failed.": { "fr": "La purge a échoué.", "en": "The purge failed.", }, "attachment row(s) deleted.": { "fr": "ligne(s) de pièce jointe supprimée(s).", "en": "attachment row(s) deleted.", }, "attachment row(s) for good?": { "fr": "ligne(s) de pièce jointe, définitivement ?", "en": "attachment row(s) for good?", }, "duplicate(s) removed": { "fr": "doublon(s) supprimé(s)", "en": "duplicate(s) removed", }, "file(s) to move up": { "fr": "fichier(s) à remonter", "en": "file(s) to move up", }, "moved up": { "fr": "remonté(s)", "en": "moved up", }, "pure duplicate(s) to delete": { "fr": "doublon(s) pur(s) à supprimer", "en": "pure duplicate(s) to delete", }, "🧹 Purge attachments whose field no longer exists": { "fr": "🧹 Purger les pièces jointes dont le champ n'existe plus", "en": "🧹 Purge attachments whose field no longer exists", }, "🧹 Tidy the nested filestore Odoo never reads": { "fr": "🧹 Ranger le filestore imbriqué qu'Odoo ne lit pas", "en": "🧹 Tidy the nested filestore Odoo never reads", }, "The purge ran but said nothing.": { "fr": "La purge a tourné sans rien annoncer.", "en": "The purge ran but said nothing.", }, "row(s) whose field is gone still hold their file": { "fr": "ligne(s) à champ disparu retiennent encore leur fichier", "en": "row(s) whose field is gone still hold their file", }, "file(s) sit in a nested filestore Odoo never reads.": { "fr": "fichier(s) échoué(s) dans un filestore imbriqué qu'Odoo ne lit jamais.", "en": "file(s) sit in a nested filestore Odoo never reads.", }, "such file(s) sit in OTHER databases filestores.": { "fr": "fichier(s) de ce genre dorment dans les filestores d'AUTRES bases.", "en": "such file(s) sit in OTHER databases filestores.", }, "Could not inspect the attachments: ": { "fr": "Inspection des pièces jointes impossible : ", "en": "Could not inspect the attachments: ", }, "Delete them?": { "fr": "Les supprimer ?", "en": "Delete them?", }, "No attachment points at a field that is gone.": { "fr": "Aucune pièce jointe ne pointe vers un champ disparu.", "en": "No attachment points at a field that is gone.", }, "attachment(s) point at a field that no longer exists": { "fr": "pièce(s) jointe(s) pointent vers un champ qui n'existe plus", "en": "attachment(s) point at a field that no longer exists", }, "Corrected.": { "fr": "Corrigé.", "en": "Corrected.", }, "No module update will fix this: the type is set once,": { "fr": "Aucune mise à jour de module ne corrigera cela : le type est posé une fois,", "en": "No module update will fix this: the type is set once,", }, "The correction failed.": { "fr": "La correction a échoué.", "en": "The correction failed.", }, "at creation. Re-run with --apply.": { "fr": "à la création. Relancer avec --apply.", "en": "at creation. Re-run with --apply.", }, "their inheritance": { "fr": "leur héritage", "en": "their inheritance", }, "view(s) whose stored type contradicts": { "fr": "vue(s) dont le type stocké contredit", "en": "view(s) whose stored type contradicts", }, "Fix views whose type contradicts their": { "fr": "Corriger les vues dont le type contredit leur", "en": "Fix views whose type contradicts their", }, "inheritance": { "fr": "héritage", "en": "inheritance", }, "Correct them?": { "fr": "Les corriger ?", "en": "Correct them?", }, "Uninstall the theme(s) the error names": { "fr": "Désinstaller le(s) thème(s) que l'erreur nomme", "en": "Uninstall the theme(s) the error names", }, "Every view agrees with what Odoo expects.": { "fr": "Toutes les vues s'accordent avec ce qu'Odoo attend.", "en": "Every view agrees with what Odoo expects.", }, "custom — nothing will ever rewrite it": { "fr": "faite main — rien ne la réécrira jamais", "en": "custom — nothing will ever rewrite it", }, "from a module — a module update also fixes it": { "fr": "d'un module — une mise à jour la répare aussi", "en": "from a module — a module update also fixes it", }, "renamed to ": { "fr": "a renommée en ", "en": "renamed to ", }, "view(s) still carry a tag Odoo 18": { "fr": "vue(s) portent encore une balise qu'Odoo 18", "en": "view(s) still carry a tag Odoo 18", }, "failed at": { "fr": "a échoué sur", "en": "failed at", }, "Census": { "fr": "Recensement", "en": "Census", }, "Compared against nothing — census only.": { "fr": "Comparé à rien — recensement seul.", "en": "Compared against nothing — census only.", }, "Default package:": { "fr": "Package par défaut :", "en": "Default package:", }, "Every suggested module is installed.": { "fr": "Tous les modules suggérés sont installés.", "en": "Every suggested module is installed.", }, "Installed modules by author": { "fr": "Modules installés, par auteur", "en": "Installed modules by author", }, "Modules of": { "fr": "Modules de", "en": "Modules of", }, "No default package known for this version": { "fr": "Aucun package par défaut connu pour cette version", "en": "No default package known for this version", }, "Odoo": { "fr": "Odoo", "en": "Odoo", }, "absent from the addons path — sync the repo first": { "fr": "hors du chemin des addons — synchroniser le dépôt d'abord", "en": "absent from the addons path — sync the repo first", }, "also needs": { "fr": "réclame aussi", "en": "also needs", }, "half-way — finish the pending update": { "fr": "à mi-chemin — finir la mise à jour en attente", "en": "half-way — finish the pending update", }, "installed": { "fr": "déjà en place", "en": "installed", }, "known": { "fr": "connus", "en": "known", }, "known to the database — install it": { "fr": "dans la base — à installer", "en": "known to the database — install it", }, "present but broken — fix the dependency": { "fr": "en panne de dépendance — à réparer", "en": "present but broken — fix the dependency", }, "suggested module(s)": { "fr": "module(s) suggéré(s)", "en": "suggested module(s)", }, "suggested module(s) not installed": { "fr": "module(s) suggéré(s) non installé(s)", "en": "suggested module(s) not installed", }, "unknown author": { "fr": "auteur inconnu", "en": "unknown author", }, "rows dropped, the table remains": { "fr": "lignes supprimées, la table demeure", "en": "rows dropped, the table remains", }, "retired from the database": { "fr": "retirée de la base", "en": "retired from the database", }, "but it gained nothing": { "fr": "mais elle n'a rien reçu", "en": "but it gained nothing", }, "there": { "fr": "là-bas", "en": "there", }, "lost": { "fr": "perdus", "en": "lost", }, "gained": { "fr": "gagnés", "en": "gained", }, "fields": { "fr": "champs", "en": "fields", }, "cow": { "fr": "copies COW", "en": "cow", }, "tables": { "fr": "tables", "en": "tables", }, "Details": { "fr": "Détails", "en": "Details", }, "summary": { "fr": "résumé", "en": "summary", }, "Clean the database before testing the pages?": { "fr": "Nettoyer la base avant de tester les pages ?", "en": "Clean the database before testing the pages?", }, "Auto-run: take the default answer after": { "fr": "Auto-exécution : prendre la réponse par défaut après", "en": "Auto-run: take the default answer after", }, "seconds?": { "fr": "secondes ?", "en": "seconds?", }, "Auto-run on: each prompt waits": { "fr": "Auto-exécution activée : chaque invite attend", "en": "Auto-run on: each prompt waits", }, "seconds, then takes its default.": { "fr": "secondes, puis prend son défaut.", "en": "seconds, then takes its default.", }, "(default)": { "fr": "(défaut)", "en": "(default)", }, "database_cleanup is not installed on this base;": { "fr": "database_cleanup n'est pas installé sur cette base ;", "en": "database_cleanup is not installed on this base;", }, "installing it first.": { "fr": "installation préalable.", "en": "installing it first.", }, "Could not install database_cleanup.": { "fr": "Impossible d'installer database_cleanup.", "en": "Could not install database_cleanup.", }, "Nothing to decide yet": { "fr": "Rien à décider pour l'instant", "en": "Nothing to decide yet", }, "the migration will offer to neutralize these copies": { "fr": "la migration proposera de neutraliser ces copies", "en": "the migration will offer to neutralize these copies", }, "at the version bump itself, showing what each one holds.": { "fr": "au moment du palier lui-même, en montrant ce que chacune" " contient.", "en": "at the version bump itself, showing what each one holds.", }, "Press to continue": { "fr": "Appuyez pour continuer", "en": "Press to continue", }, "(b = go back to a previous step)": { "fr": "(b = revenir à une étape précédente)", "en": "(b = go back to a previous step)", }, "Neutralize database, press to continue": { "fr": "Neutraliser la base, appuyez pour continuer", "en": "Neutralize database, press to continue", }, "Replay from which step? (empty to cancel)": { "fr": "Rejouer à partir de quelle étape ? (vide pour annuler)", "en": "Replay from which step? (empty to cancel)", }, "Rewound.": {"fr": "Rembobiné.", "en": "Rewound."}, "Relaunch the migration to resume from there.": { "fr": "Relancez la migration pour reprendre à partir de là.", "en": "Relaunch the migration to resume from there.", }, "Go back to a step": { "fr": "Revenir à une étape", "en": "Go back to a step", }, "Choose a step, Enter replays from there.": { "fr": "Choisissez une étape, Entrée rejoue à partir de là.", "en": "Choose a step, Enter replays from there.", }, # --- script/analyse : vues personnalisées --- "Customised views": { "fr": "Vues personnalisées", "en": "Customised views", }, "Views": {"fr": "Vues", "en": "Views"}, "why": {"fr": "pourquoi", "en": "why"}, "more": {"fr": "de plus", "en": "more"}, "From an installed theme": { "fr": "Posée par un thème installé", "en": "From an installed theme", }, "Website copy (COW)": { "fr": "Copie de site web (COW)", "en": "Website copy (COW)", }, "Made with Studio": {"fr": "Faite avec Studio", "en": "Made with Studio"}, "Imported or exported": { "fr": "Importée ou exportée", "en": "Imported or exported", }, "Created from the interface": { "fr": "Créée depuis l'interface", "en": "Created from the interface", }, "From a module, flagged as touched": { "fr": "D'un module, signalée comme retouchée", "en": "From a module, flagged as touched", }, "Straight from a module": { "fr": "Telle quelle depuis un module", "en": "Straight from a module", }, "Every view comes straight from a module.": { "fr": "Toutes les vues viennent telles quelles d'un module.", "en": "Every view comes straight from a module.", }, "Views that did not come straight from a module": { "fr": "Vues qui ne viennent pas telles quelles d'un module", "en": "Views that did not come straight from a module", }, "Website copies are user data: Odoo copies a view instead of editing it." " Whether they will survive the next version is another question, and" " these tools answer it:": { "fr": "Les copies de site web sont des données utilisateur : Odoo" " copie une vue au lieu de la modifier. Savoir si elles survivront à" " la prochaine version est une autre question, et ces outils y" " répondent :", "en": "Website copies are user data: Odoo copies a view instead of" " editing it. Whether they will survive the next version is another" " question, and these tools answer it:", }, "Flags say a view was touched, not how. They are incomplete both ways: a" " direct SQL write does not set arch_updated, and reset_arch clears it." " Comparing with the module source is what settles it.": { "fr": "Les drapeaux disent qu'une vue a été touchée, pas comment. Ils" " sont incomplets dans les deux sens : un write SQL direct n'arme pas" " arch_updated, et reset_arch l'efface. Seule la comparaison avec la" " source du module tranche.", "en": "Flags say a view was touched, not how. They are incomplete" " both ways: a direct SQL write does not set arch_updated, and" " reset_arch clears it. Comparing with the module source is what" " settles it.", }, "List the views of an Odoo database that did not come straight from a" " module, website copies included (read-only).": { "fr": "Lister les vues d'une base Odoo qui ne viennent pas telles" " quelles d'un module, copies de site web comprises (lecture seule).", "en": "List the views of an Odoo database that did not come straight" " from a module, website copies included (read-only).", }, "only show this category": { "fr": "n'afficher que cette catégorie", "en": "only show this category", }, "how many views to show (default: 20)": { "fr": "nombre de vues à afficher (défaut : 20)", "en": "how many views to show (default: 20)", }, "list every view": { "fr": "afficher toutes les vues", "en": "list every view", }, "which views to compare (default: flagged)": { "fr": "quelles vues comparer (défaut : celles qui sont signalées)", "en": "which views to compare (default: flagged)", }, "From a module, silently drifted": { "fr": "D'un module, dérivée en silence", "en": "From a module, silently drifted", }, "In --scope all, a difference is a lead, not a verdict:" " read_arch_from_file returns the raw file, while the database holds the" " arch AFTER load-time processing. Measured on a freshly installed 18.0" " database, 160 of its 974 views already differ this way.": { "fr": "En --scope all, un écart est une piste, pas un verdict :" " read_arch_from_file rend le fichier brut, alors que la base porte" " l'arch APRÈS traitement au chargement. Mesuré sur une base 18.0" " fraîchement installée, 160 de ses 974 vues diffèrent déjà ainsi.", "en": "In --scope all, a difference is a lead, not a verdict:" " read_arch_from_file returns the raw file, while the database holds" " the arch AFTER load-time processing. Measured on a freshly installed" " 18.0 database, 160 of its 974 views already differ this way.", }, "Compare with the module source? (Y/n): ": { "fr": "Comparer avec la source du module ? (O/n) : ", "en": "Compare with the module source? (Y/n): ", }, # --- Menu Analyse : les actions « aller plus loin ». Ce qui était # conseillé en options de ligne de commande est devenu des entrées : # dire « utilisez -v » à quelqu'un qui est dans un menu, c'est lui # demander d'en sortir pour obtenir ce que le menu pouvait offrir. "Browse the differences (TUI)": { "fr": "🖥 Naviguer dans les écarts (plein écran)", "en": "🖥 Browse the differences (TUI)", }, "Compare every view (slower, noisier)": { "fr": "🔬 Comparer toutes les vues (plus long, plus bruyant)", "en": "🔬 Compare every view (slower, noisier)", }, "Compare first, then browse.": { "fr": "Comparez d'abord, vous naviguerez ensuite.", "en": "Compare first, then browse.", }, "Compare the flagged views with the module source": { "fr": "🔍 Comparer les vues signalées avec la source du module", "en": "🔍 Compare the flagged views with the module source", }, "Count rows exactly (full scan)": { "fr": "🔢 Compter les lignes exactement (balayage complet)", "en": "🔢 Count rows exactly (full scan)", }, "Counting rows exactly, one scan per table…": { "fr": "Comptage exact des lignes, un balayage par table…", "en": "Counting rows exactly, one scan per table…", }, "Export as JSON": {"fr": "💾 Exporter en JSON", "en": "💾 Export as JSON"}, "Go further": {"fr": "🔎 Aller plus loin", "en": "🔎 Go further"}, "Loading the Odoo registry, this takes a moment…": { "fr": "Chargement du registre Odoo, cela prend un moment…", "en": "Loading the Odoo registry, this takes a moment…", }, "No view differs from its module source.": { "fr": "Aucune vue ne diffère de la source de son module.", "en": "No view differs from its module source.", }, "Show every table": { "fr": "📜 Afficher toutes les tables", "en": "📜 Show every table", }, "Show every view": { "fr": "📜 Afficher toutes les vues", "en": "📜 Show every view", }, "Written to: ": {"fr": "Écrit dans : ", "en": "Written to: "}, "Flags say a view was touched, not how: only comparing with the module" " source settles it.": { "fr": "Les drapeaux disent qu'une vue a été touchée, pas comment :" " seule la comparaison avec la source du module tranche.", "en": "Flags say a view was touched, not how: only comparing with the" " module source settles it.", }, "blocking": {"fr": "bloquants", "en": "blocking"}, "Studio and hand-made x_ fields": { "fr": "🧩 Champs x_ (Studio et faits à la main)", "en": "🧩 Studio and hand-made x_ fields", }, "Show every field": { "fr": "📜 Afficher tous les champs", "en": "📜 Show every field", }, "A database": {"fr": "💾 Une base de données", "en": "💾 A database"}, "A backup .zip, without restoring it": { "fr": "🗜 Une sauvegarde .zip, sans la restaurer", "en": "🗜 A backup .zip, without restoring it", }, "Path to the backup .zip (empty to cancel): ": { "fr": "Chemin de la sauvegarde .zip (vide pour annuler) : ", "en": "Path to the backup .zip (empty to cancel): ", }, "No such file: ": {"fr": "Fichier introuvable : ", "en": "No such file: "}, "from a backup": {"fr": "depuis une sauvegarde", "en": "from a backup"}, "Odoo backup .zip to inspect, without restoring it": { "fr": "sauvegarde Odoo .zip à examiner, sans la restaurer", "en": "Odoo backup .zip to inspect, without restoring it", }, "Not an Odoo backup (no manifest.json): ": { "fr": "Pas une sauvegarde Odoo (aucun manifest.json) : ", "en": "Not an Odoo backup (no manifest.json): ", }, "Cannot read the backup: ": { "fr": "Lecture impossible de la sauvegarde : ", "en": "Cannot read the backup: ", }, "This backup holds no dump.sql: ": { "fr": "Cette sauvegarde ne contient aucun dump.sql : ", "en": "This backup holds no dump.sql: ", }, # --- script/analyse : champs et modèles hors module --- "Nothing declares these in a file, so no module will " "recreate them. What a version upgrade keeps is what " "someone carried over.": { "fr": "Rien ne les déclare dans un fichier, donc aucun module " "ne les recréera. Ce qu'une montée de version conserve " "est ce que quelqu'un a reporté.", "en": "Nothing declares these in a file, so no module will " "recreate them. What a version upgrade keeps is what " "someone carried over.", }, "A stored field without its column stops the registry " "from loading, so the upgrade will not even start. Settle " "these before anything else.": { "fr": "Un champ stocké sans sa colonne empêche le registre de " "charger, donc la montée de version ne démarrera même " "pas. Réglez cela avant tout le reste.", "en": "A stored field without its column stops the registry " "from loading, so the upgrade will not even start. Settle " "these before anything else.", }, "Use -v to list them all, --json for the raw data.": { "fr": "Utilisez -v pour tout afficher, --json pour la donnée brute.", "en": "Use -v to list them all, --json for the raw data.", }, "List the fields and models added outside a module — " "Studio or by hand (read-only).": { "fr": "Lister les champs et modèles ajoutés hors module — " "Studio ou faits à la main (lecture seule).", "en": "List the fields and models added outside a module — " "Studio or by hand (read-only).", }, "how many to show (default: 30)": { "fr": "nombre à afficher (défaut : 30)", "en": "how many to show (default: 30)", }, "list every one": {"fr": "tout afficher", "en": "list every one"}, "Studio": {"fr": "Studio", "en": "Studio"}, "Made by hand": {"fr": "Fait à la main", "en": "Made by hand"}, "Declared by a module": { "fr": "Déclaré par un module", "en": "Declared by a module", }, "stored, but its column is missing": { "fr": "stocké, mais sa colonne manque", "en": "stored, but its column is missing", }, "points at a model that no longer exists": { "fr": "pointe vers un modèle qui n'existe plus", "en": "points at a model that no longer exists", }, "its model no longer exists": { "fr": "son modèle n'existe plus", "en": "its model no longer exists", }, "its table could not be resolved": { "fr": "sa table n'a pas pu être résolue", "en": "its table could not be resolved", }, "origin": {"fr": "provenance", "en": "origin"}, "Fields added outside a module": { "fr": "Champs ajoutés hors module", "en": "Fields added outside a module", }, "Custom fields": {"fr": "Champs personnalisés", "en": "Custom fields"}, "Custom models": {"fr": "Modèles personnalisés", "en": "Custom models"}, "No field or model was added outside a module.": { "fr": "Aucun champ ni modèle n'a été ajouté hors module.", "en": "No field or model was added outside a module.", }, "Blocking": {"fr": "Bloquant", "en": "Blocking"}, "To carry over by hand": { "fr": "À reporter à la main", "en": "To carry over by hand", }, # --- script/analyse : comparaison et navigation des écarts --- "Differences only": { "fr": "Écarts seuls", "en": "Differences only", }, "Ignore indentation": { "fr": "Ignorer l'indentation", "en": "Ignore indentation", }, "Copy": { "fr": "Copier", "en": "Copy", }, "Reset command": { "fr": "Commande de réinitialisation", "en": "Reset command", }, "module (file)": { "fr": "module (fichier)", "en": "module (file)", }, "database": { "fr": "base", "en": "database", }, "Difference copied.": { "fr": "Écart copié.", "en": "Difference copied.", }, "No Odoo configuration file found.": { "fr": "Aucun fichier de configuration Odoo trouvé.", "en": "No Odoo configuration file found.", }, "odoo_bin.sh not found.": { "fr": "odoo_bin.sh est introuvable.", "en": "odoo_bin.sh not found.", }, "The Odoo shell returned no result: ": { "fr": "Le shell Odoo n'a rien renvoyé : ", "en": "The Odoo shell returned no result: ", }, "The Odoo shell exceeded the timeout (s): ": { "fr": "Le shell Odoo a dépassé le délai imparti (s) : ", "en": "The Odoo shell exceeded the timeout (s): ", }, "Unreadable JSON from the Odoo shell: ": { "fr": "JSON illisible en sortie du shell Odoo : ", "en": "Unreadable JSON from the Odoo shell: ", }, "To restore a view to what its module declares — this " "WRITES to the database, so read the difference first:": { "fr": "Pour rendre à une vue ce que déclare son module — ceci " "ÉCRIT dans la base, lisez donc l'écart d'abord :", "en": "To restore a view to what its module declares — this " "WRITES to the database, so read the difference first:", }, "compare with the module source (opens an Odoo shell)": { "fr": "comparer avec la source du module (ouvre un shell Odoo)", "en": "compare with the module source (opens an Odoo shell)", }, "fail if the comparison could not be made": { "fr": "échouer si la comparaison n'a pas pu être faite", "en": "fail if the comparison could not be made", }, "browse the differences in a full-screen view": { "fr": "naviguer dans les écarts en plein écran", "en": "browse the differences in a full-screen view", }, "Flags say a view was touched, not how. They are incomplete " "both ways: a direct SQL write does not set arch_updated, " "and reset_arch clears it. Comparing with the module source " "is what settles it — add --diff.": { "fr": "Les drapeaux disent qu'une vue a été touchée, pas comment. " "Ils sont incomplets dans les deux sens : un write SQL " "direct n'arme pas arch_updated, et reset_arch l'efface. " "Seule la comparaison avec la source du module tranche — " "ajoutez --diff.", "en": "Flags say a view was touched, not how. They are incomplete " "both ways: a direct SQL write does not set arch_updated, " "and reset_arch clears it. Comparing with the module source " "is what settles it — add --diff.", }, "Database is Odoo": { "fr": "La base est en Odoo", "en": "Database is Odoo", }, "checkout is": { "fr": "le checkout est en", "en": "checkout is", }, "views were flagged but hold exactly what their module " "declares: only the comparison could tell.": { "fr": "vues étaient signalées mais portent exactement ce que " "déclare leur module : seule la comparaison pouvait le " "dire.", "en": "views were flagged but hold exactly what their module " "declares: only the comparison could tell.", }, "No reference arch, so nothing was compared: ": { "fr": "Aucune arch de référence, donc rien n'a été comparé : ", "en": "No reference arch, so nothing was compared: ", }, "Not a terminal: showing the text report instead.": { "fr": "Pas un terminal : affichage du rapport texte à la place.", "en": "Not a terminal: showing the text report instead.", }, "To restore this view to what its module declares:": { "fr": "Pour rendre à cette vue ce que déclare son module :", "en": "To restore this view to what its module declares:", }, # --- script/analyse : erreurs du socle --- "Invalid database name: ": { "fr": "Nom de base invalide : ", "en": "Invalid database name: ", }, "Cannot read from the database: ": { "fr": "Lecture impossible dans la base : ", "en": "Cannot read from the database: ", }, "is not an Odoo database.": { "fr": "n'est pas une base Odoo.", "en": "is not an Odoo database.", }, "psql is not installed or not in PATH.": { "fr": "psql n'est pas installé, ou absent du PATH.", "en": "psql is not installed or not in PATH.", }, "Query exceeded the timeout (s): ": { "fr": "La requête a dépassé le délai imparti (s) : ", "en": "Query exceeded the timeout (s): ", }, "Unreadable JSON from psql: ": { "fr": "JSON illisible en sortie de psql : ", "en": "Unreadable JSON from psql: ", }, "shared library, nothing to run here.": { "fr": "bibliothèque partagée, rien à lancer ici.", "en": "shared library, nothing to run here.", }, "Runnable tools in this directory:": { "fr": "Outils exécutables de ce répertoire :", "en": "Runnable tools in this directory:", }, "No analysis tool here yet.": { "fr": "Aucun outil d'analyse ici pour l'instant.", "en": "No analysis tool here yet.", }, "From the menu:": {"fr": "Depuis le menu :", "en": "From the menu:"}, "in the dump": {"fr": "dans le dump", "en": "in the dump"}, "Weight in the dump": { "fr": "Poids dans le dump", "en": "Weight in the dump", }, # --- script/analyse : poids du schéma --- "Schema analysis": { "fr": "Analyse du schéma", "en": "Schema analysis", }, "Database size": { "fr": "Poids de la base", "en": "Database size", }, "Tables": {"fr": "Tables", "en": "Tables"}, "Models": {"fr": "Modèles", "en": "Models"}, "rows": {"fr": "lignes", "en": "rows"}, "Models without table": { "fr": "Modèles sans table", "en": "Models without table", }, "abstract models have none, by design": { "fr": "les modèles abstraits n'en ont pas, par construction", "en": "abstract models have none, by design", }, "ir_model_relation is absent, so m2m tables cannot be told apart from" " orphans: the list below is unreliable.": { "fr": "ir_model_relation est absente : impossible de distinguer une" " table m2m d'une orpheline, la liste ci-dessous n'est pas fiable.", "en": "ir_model_relation is absent, so m2m tables cannot be told apart" " from orphans: the list below is unreliable.", }, "Heaviest tables": { "fr": "Tables les plus lourdes", "en": "Heaviest tables", }, "All tables, heaviest first": { "fr": "Toutes les tables, de la plus lourde à la plus légère", "en": "All tables, heaviest first", }, "use -v to list them all": { "fr": "utilisez -v pour toutes les afficher", "en": "use -v to list them all", }, "Every table belongs to an installed model.": { "fr": "Chaque table appartient à un modèle installé.", "en": "Every table belongs to an installed model.", }, "Orphan tables": { "fr": "Tables orphelines", "en": "Orphan tables", }, "No installed model claims these tables. They are usually left over from" " modules uninstalled without DROP TABLE, and every version upgrade" " carries them along.": { "fr": "Aucun modèle installé ne réclame ces tables. Ce sont le plus" " souvent des reliquats de modules désinstallés sans DROP TABLE, que" " chaque montée de version transporte avec elle.", "en": "No installed model claims these tables. They are usually left" " over from modules uninstalled without DROP TABLE, and every version" " upgrade carries them along.", }, "Check what they hold before dropping anything.": { "fr": "Regardez ce qu'elles contiennent avant de supprimer quoi que ce" " soit.", "en": "Check what they hold before dropping anything.", }, "Row counts are estimates from the last ANALYZE. Use --exact for real" " counts, at the cost of one full scan per table.": { "fr": "Les nombres de lignes sont estimés d'après le dernier ANALYZE." " Utilisez --exact pour un comptage réel, au prix d'un balayage" " complet par table.", "en": "Row counts are estimates from the last ANALYZE. Use --exact for" " real counts, at the cost of one full scan per table.", }, "Report the size of an Odoo database and the tables no installed model" " claims (read-only).": { "fr": "Rapporter le poids d'une base Odoo et les tables qu'aucun" " modèle installé ne réclame (lecture seule).", "en": "Report the size of an Odoo database and the tables no installed" " model claims (read-only).", }, "database to inspect": { "fr": "base à examiner", "en": "database to inspect", }, "count rows exactly: one full scan per table": { "fr": "compter les lignes exactement : un balayage complet par table", "en": "count rows exactly: one full scan per table", }, "how many tables to show (default: 20)": { "fr": "nombre de tables à afficher (défaut : 20)", "en": "how many tables to show (default: 20)", }, "list every table": { "fr": "afficher toutes les tables", "en": "list every table", }, "output JSON": {"fr": "sortie JSON", "en": "output JSON"}, "path to an Odoo config file": { "fr": "chemin d'un fichier de configuration Odoo", "en": "path to an Odoo config file", }, # Courriel "mail_menu": { "fr": "📧 Courriel - Lire et envoyer du courriel", "en": "📧 Mail - Read and send email", }, "mail_open_tui": { "fr": "Ouvrir le client courriel (TUI)", "en": "Open the mail client (TUI)", }, "mail_accounts_menu": {"fr": "Comptes", "en": "Accounts"}, "mail_sync_now": { "fr": "Synchroniser maintenant", "en": "Synchronise now", }, "mail_cache_menu": {"fr": "Cache", "en": "Cache"}, "mail_account_list": {"fr": "Lister les comptes", "en": "List accounts"}, "mail_account_add": {"fr": "Ajouter un compte", "en": "Add an account"}, "mail_account_delete": { "fr": "Supprimer un compte", "en": "Delete an account", }, "mail_account_template": { "fr": "Générer un modèle accounts.json", "en": "Generate an accounts.json template", }, "mail_account_test": { "fr": "Tester la connexion d'un compte", "en": "Test an account connection", }, "mail_cache_default_mode": { "fr": "Mode de cache par défaut", "en": "Default cache mode", }, "mail_cache_account_mode": { "fr": "Mode de cache d'un compte", "en": "Cache mode of one account", }, "mail_cache_size_purge": { "fr": "Taille du cache et purge", "en": "Cache size and purge", }, "mail_no_account": { "fr": "Aucun compte configuré. Ajoutez-en un d'abord.", "en": "No account configured. Add one first.", }, "mail_ask_name": { "fr": "Nom court du compte : ", "en": "Short account name: ", }, "mail_ask_email": {"fr": "Adresse courriel : ", "en": "Email address: "}, "mail_ask_display_name": { "fr": "Nom affiché (facultatif) : ", "en": "Display name (optional): ", }, "mail_ask_preset": {"fr": "Fournisseur : ", "en": "Provider: "}, "mail_ask_password": {"fr": "Mot de passe : ", "en": "Password: "}, "mail_ask_imap_host": {"fr": "Serveur IMAP : ", "en": "IMAP server: "}, "mail_ask_smtp_host": {"fr": "Serveur SMTP : ", "en": "SMTP server: "}, "mail_ask_account": {"fr": "Quel compte ? ", "en": "Which account? "}, "mail_ask_mode": { "fr": "Mode (clear / encrypted / ephemeral) : ", "en": "Mode (clear / encrypted / ephemeral): ", }, "mail_app_password_note": { "fr": "Ce fournisseur exige un mot de passe d'application.", "en": "This provider requires an app password.", }, "mail_account_saved": {"fr": "Compte enregistré.", "en": "Account saved."}, "mail_account_save": {"fr": "Enregistrer", "en": "Save"}, "mail_account_missing_fields": { "fr": "Nom, adresse et mot de passe sont requis.", "en": "Name, address and password are required.", }, "mail_account_add_unavailable": { "fr": "Ajout de compte indisponible dans ce contexte.", "en": "Adding an account is unavailable in this context.", }, "mail_account_deleted": { "fr": "Compte supprimé.", "en": "Account deleted.", }, "mail_connection_ok": { "fr": "Connexion réussie.", "en": "Connection succeeded.", }, "mail_connection_failed": { "fr": "Connexion échouée :", "en": "Connection failed:", }, "mail_template_written": { "fr": "Modèle écrit dans", "en": "Template written to", }, "mail_purge_confirm": { "fr": "Effacer tout le cache de ce compte ? (o/N) ", "en": "Erase this account's whole cache? (y/N) ", }, "mail_purged": {"fr": "Cache effacé.", "en": "Cache erased."}, "mail_no_vault": { "fr": "Aucun coffre disponible : installez pykeepass ou déverrouillez un trousseau système.", "en": "No vault available: install pykeepass or unlock a system keyring.", }, # Coffre KeePass, côté infrastructure partagée (`kdbx_manager`) : ces # messages servent à TOUT le CLI, pas seulement au courriel. "kdbx_vault_is": { "fr": "Coffre KeePass :", "en": "KeePass vault:", }, "kdbx_ask_password": { "fr": "Mot de passe du coffre (vide pour abandonner) : ", "en": "Vault password (empty to give up): ", }, "kdbx_wrong_password": { "fr": "Mot de passe incorrect pour ce coffre KeePass.", "en": "Wrong password for this KeePass vault.", }, "kdbx_give_up": { "fr": "Coffre non ouvert : on abandonne.", "en": "Vault not opened: giving up.", }, "mail_kdbx_none_configured": { "fr": "Aucun fichier kdbx n'est configuré.", "en": "No kdbx file is configured.", }, "mail_kdbx_menu_create": { "fr": "Créer un nouveau fichier .kdbx", "en": "Create a new .kdbx file", }, "mail_kdbx_menu_choose": { "fr": "Choisir un fichier existant", "en": "Choose an existing file", }, "mail_kdbx_menu_cancel": {"fr": "Annuler", "en": "Cancel"}, "mail_kdbx_ask_choice": {"fr": "Votre choix : ", "en": "Your choice: "}, "mail_kdbx_ask_path_new": { "fr": "Chemin du nouveau fichier kdbx", "en": "Path for the new kdbx file", }, "mail_kdbx_ask_path_existing": { "fr": "Chemin du fichier kdbx existant : ", "en": "Path to the existing kdbx file: ", }, "mail_kdbx_ask_password": { "fr": "Mot de passe du coffre : ", "en": "Vault password: ", }, "mail_kdbx_ask_password_confirm": { "fr": "Confirmez le mot de passe : ", "en": "Confirm the password: ", }, "mail_kdbx_password_mismatch": { "fr": "Les mots de passe ne correspondent pas.", "en": "Passwords do not match.", }, "mail_kdbx_path_not_found": { "fr": "Ce fichier n'existe pas :", "en": "This file does not exist:", }, "mail_kdbx_created": { "fr": "Fichier kdbx créé :", "en": "Kdbx file created:", }, "mail_kdbx_path_recorded": { "fr": "Fichier kdbx configuré :", "en": "Kdbx file configured:", }, "mail_no_password_stored": { "fr": "Aucun mot de passe enregistré pour ce compte.", "en": "No password stored for this account.", }, "mail_install_textual": { "fr": "Installez textual pour le client courriel (pip).", "en": "Install textual for the mail client (pip).", }, "mail_accounts": {"fr": "Comptes", "en": "Accounts"}, "mail_search": {"fr": "Rechercher…", "en": "Search…"}, "mail_search_clear": { "fr": "Effacer la recherche", "en": "Clear search", }, "mail_from": {"fr": "De :", "en": "From:"}, "mail_to": {"fr": "À :", "en": "To:"}, "mail_cc": {"fr": "Cc :", "en": "Cc:"}, "mail_subject": {"fr": "Objet :", "en": "Subject:"}, "mail_date": {"fr": "Date", "en": "Date"}, "mail_send": {"fr": "Envoyer", "en": "Send"}, "mail_attachments": {"fr": "Pièces jointes :", "en": "Attachments:"}, "mail_attachments_paths": { "fr": "Pièces jointes (chemins séparés par des points-virgules)", "en": "Attachments (semicolon-separated paths)", }, "mail_browse": {"fr": "Parcourir…", "en": "Browse…"}, "mail_browse_failed": { "fr": "Sélecteur de fichiers impossible :", "en": "File browser unavailable:", }, "mail_no_subject": {"fr": "(sans objet)", "en": "(no subject)"}, "mail_body_needs_network": { "fr": "Corps non téléchargé — connexion requise.", "en": "Body not downloaded — connection required.", }, "mail_body_error": { "fr": "Lecture du corps impossible :", "en": "Cannot read the body:", }, "mail_flag_error": { "fr": "Drapeau non transmis au serveur :", "en": "Flag not sent to the server:", }, "mail_syncing": {"fr": "Synchronisation de", "en": "Synchronising"}, "mail_new_messages": {"fr": "nouveaux messages", "en": "new messages"}, "mail_errors": {"fr": "erreurs", "en": "errors"}, "mail_folders_resynced": { "fr": "dossiers resynchronisés (UIDVALIDITY changé) :", "en": "folders resynchronised (UIDVALIDITY changed):", }, "mail_offline_cannot_send": { "fr": "Compte hors ligne : envoi impossible.", "en": "Account offline: cannot send.", }, "mail_sent_to": {"fr": "Envoyé à", "en": "Sent to"}, "mail_sent_not_filed": { "fr": "envoyé, mais pas classé dans Envoyés", "en": "sent, but not filed in Sent", }, "mail_nothing_to_reply_to": { "fr": "Aucun message sélectionné.", "en": "No message selected.", }, "mail_nothing_to_forward": { "fr": "Aucun message à transférer.", "en": "No message to forward.", }, "mail_attachment_not_found": { "fr": "Pièce jointe introuvable.", "en": "Attachment not found.", }, "mail_no_attachment": { "fr": "Ce message n'a pas de pièce jointe.", "en": "This message has no attachment.", }, "mail_save_failed": { "fr": "Enregistrement impossible :", "en": "Cannot save:", }, "mail_saved_to": {"fr": "Enregistré dans", "en": "Saved to"}, "mail_log_binding": {"fr": "Journal", "en": "Log"}, "mail_log_close": {"fr": "Fermer", "en": "Close"}, "mail_log_tail_heading": { "fr": "Journal (fin) :", "en": "Log (tail):", }, "mail_log_errors_heading": { "fr": "Erreurs de synchronisation (session en cours) :", "en": "Sync errors (current session):", }, "mail_log_missing": { "fr": "journal introuvable", "en": "log not found", }, "mail_log_empty": {"fr": "journal vide", "en": "log empty"}, "mail_log_unreadable": { "fr": "journal illisible", "en": "log unreadable", }, "mail_log_no_errors": { "fr": "Aucune erreur de synchronisation dans cette session.", "en": "No sync errors in this session.", }, "mail_layout_binding": {"fr": "Vue", "en": "View"}, "mail_layout_switched": {"fr": "Disposition :", "en": "Layout:"}, "mail_layout_columns": {"fr": "Colonnes", "en": "Columns"}, "mail_layout_split": {"fr": "Partagée", "en": "Split"}, "mail_layout_stacked": {"fr": "Empilée", "en": "Stacked"}, "mail_pane_grow_binding": {"fr": "Agrandir volet", "en": "Grow pane"}, "mail_pane_shrink_binding": { "fr": "Rétrécir volet", "en": "Shrink pane", }, "mail_pane_reset_binding": { "fr": "Tailles par défaut", "en": "Reset sizes", }, "mail_pane_reset_done": { "fr": "Tailles des volets réinitialisées.", "en": "Pane sizes reset.", }, "mail_pane_splitter_tooltip": { "fr": "Glisser pour redimensionner", "en": "Drag to resize", }, "mail_fullscreen_binding": {"fr": "Plein écran", "en": "Full screen"}, # -- Libellés des raccourcis de MailApp (suffixe _binding) ------------- # Ce sont les descriptions des `Binding` de `MailApp` : elles s'affichent # au pied d'écran ET, depuis la tâche 26, dans la fenêtre d'aide (`h`), # qui les lit directement dans `MailApp.BINDINGS`. Le français est repris # MOT POUR MOT de ce qui était écrit en dur avant cette tâche — le pied # d'écran d'un utilisateur francophone ne change pas. "mail_quit_binding": {"fr": "Quitter", "en": "Quit"}, "mail_sync_current_binding": {"fr": "Sync", "en": "Sync"}, "mail_sync_all_binding": {"fr": "Sync tout", "en": "Sync all"}, "mail_back_binding": {"fr": "Retour", "en": "Back"}, "mail_search_binding": {"fr": "Rechercher", "en": "Search"}, "mail_mark_seen_binding": {"fr": "Lu", "en": "Read"}, "mail_mark_unseen_binding": {"fr": "Non lu", "en": "Unread"}, "mail_save_attachment_binding": { "fr": "Enregistrer PJ", "en": "Save attachment", }, "mail_compose_binding": {"fr": "Écrire", "en": "Compose"}, "mail_reply_binding": {"fr": "Répondre", "en": "Reply"}, "mail_reply_all_binding": {"fr": "Répondre à tous", "en": "Reply all"}, "mail_forward_binding": {"fr": "Transférer", "en": "Forward"}, "mail_add_account_binding": { "fr": "Nouveau compte", "en": "New account", }, # -- Fenêtre d'aide (touche h) ----------------------------------------- # La liste des touches n'est PAS ici : elle est engendrée depuis # `MailApp.BINDINGS` (voir `HelpScreen`), avec les libellés ci-dessus. # Seul ce qu'une liste de touches ne peut pas dire est rédigé ici. "mail_help_binding": {"fr": "Aide", "en": "Help"}, "mail_help_close": {"fr": "Fermer", "en": "Close"}, "mail_help_title": { "fr": "Aide — client courriel", "en": "Help — mail client", }, "mail_help_keys_heading": { "fr": "Raccourcis clavier :", "en": "Keyboard shortcuts:", }, "mail_help_notes_heading": {"fr": "Bon à savoir :", "en": "Good to know:"}, "mail_help_mouse": { "fr": ( "Souris : glisser une barre entre deux volets les redimensionne." " Au clavier, + et - font de même sur le volet qui a le focus, et" " 0 remet les tailles par défaut. Les tailles sont retenues par" " disposition." ), "en": ( "Mouse: drag a bar between two panes to resize them. From the" " keyboard, + and - do the same to the focused pane, and 0 resets" " the sizes. Sizes are remembered per layout." ), }, "mail_help_layouts": { "fr": ( "Dispositions : v passe de colonnes à partagée, puis empilée, puis" " revient à colonnes." ), "en": ( "Layouts: v cycles columns, split, stacked, then back to columns." ), }, "mail_help_sync": { "fr": ( "Synchronisation : r synchronise le compte du dossier sélectionné" " (tous ses dossiers), R synchronise tous les comptes. La" " synchronisation automatique ne tourne QUE tant que le client est" " ouvert, à l'intervalle mail_refresh_sec (300 s par défaut ; 0 la" " désactive)." ), "en": ( "Sync: r syncs the account of the selected folder (all its" " folders), R syncs every account. The automatic refresh runs ONLY" " while the client is open, at the mail_refresh_sec interval (300 s" " by default; 0 disables it)." ), }, "mail_help_files": { "fr": ( "Fichiers : le journal est dans ~/.erplibre/mail.log (la touche l" " en montre la fin), les comptes dans" " ~/.erplibre/mail/accounts.json. Les mots de passe n'y sont JAMAIS" " écrits : ils vivent dans le coffre kdbx ou le trousseau du" " système." ), "en": ( "Files: the log lives in ~/.erplibre/mail.log (the l key shows its" " tail), the accounts in ~/.erplibre/mail/accounts.json. Passwords" " are NEVER written there: they live in the kdbx vault or in the" " system keyring." ), }, "mail_help_close_hint": { "fr": "Échap ferme cette fenêtre.", "en": "Esc closes this window.", }, # -- Exceptions internes au paquet courriel (préfixe mail_err_) -------- # Label traduit, données dynamiques (chemins, texte serveur, valeurs de # config) concaténées crues : jamais de traduction d'un message serveur # ou d'un chemin de fichier. # # Quelques messages ont la donnée dynamique AU MILIEU de la phrase : ils # sont donc assemblés à partir de deux clés (voire trois), dans un ordre # FIXE codé au site d'appel plutôt que par une seule clé avec un # emplacement — mail_err_unknown_security + mail_err_expected, # mail_err_key_wrong_length + mail_err_octets_unit, # mail_err_mode_prefix + mail_err_mode_requires_key(_no_vault), # mail_err_imap_connection_prefix / mail_err_smtp_connection_prefix + # mail_err_connection_refused_suffix, et mail_err_keyring_plaintext + # mail_err_keyring_plaintext_hint. L'ordre des mots vit donc dans le # code, pas dans les chaînes traduisibles : une langue à l'ordre des # mots différent devra remplacer ces paires par une convention à # emplacement (ex. `.format()`), pas par une simple concaténation. "mail_err_envelope_too_short": { "fr": "enveloppe trop courte", "en": "envelope too short", }, "mail_err_sealed_in_clear_mode": { "fr": "donnée chiffrée lue en mode clair : la clé du compte manque", "en": "encrypted data read in clear mode: the account key is missing", }, "mail_err_unknown_envelope": { "fr": "enveloppe inconnue :", "en": "unknown envelope:", }, "mail_err_key_wrong_length": { "fr": "la clé doit faire", "en": "the key must be", }, "mail_err_octets_unit": {"fr": "octets", "en": "bytes"}, "mail_err_cryptography_not_installed": { "fr": "le paquet cryptography n'est pas installé", "en": "the cryptography package is not installed", }, "mail_err_decrypt_refused": { "fr": "déchiffrement refusé : clé fausse ou donnée altérée", "en": "decryption refused: wrong key or corrupted data", }, "mail_err_envelope_unreadable": { "fr": "enveloppe illisible :", "en": "unreadable envelope:", }, "mail_err_mode_prefix": {"fr": "le mode", "en": "mode"}, "mail_err_mode_requires_key": { "fr": "exige une clé", "en": "requires a key", }, "mail_err_unknown_cache_mode": { "fr": "mode de cache inconnu :", "en": "unknown cache mode:", }, "mail_err_file_already_exists": { "fr": "le fichier existe déjà :", "en": "the file already exists:", }, "mail_err_invalid_secret_ref": { "fr": "référence de secret invalide :", "en": "invalid secret reference:", }, # Notes par fournisseur. Affichées à l'ajout d'un compte ET juste avant # de redemander un mot de passe après un refus : elles doivent donner # l'adresse EXACTE, pas un chemin de menu — Google et Apple déplacent # régulièrement ces pages, et Google cache la sienne. "mail_preset_note_gmail": { "fr": ( "Générez-le sur https://myaccount.google.com/apppasswords" " (16 caractères, les espaces sont acceptés). La validation en" " deux étapes doit être active, sinon la page est vide." ), "en": ( "Generate one at https://myaccount.google.com/apppasswords" " (16 characters, spaces are accepted). Two-step verification" " must be on, otherwise the page is empty." ), }, "mail_preset_note_outlook": { "fr": ( "Générez-le sur https://account.microsoft.com/security." " Microsoft ferme l'authentification simple sur les comptes" " grand public : sans mot de passe d'application, il faudra" " OAuth (phase 2, non implémentée)." ), "en": ( "Generate one at https://account.microsoft.com/security." " Microsoft is closing basic authentication on consumer" " accounts: without an app password this needs OAuth (phase 2," " not implemented)." ), }, "mail_preset_note_icloud": { "fr": ( "Générez-le sur https://account.apple.com, section « Connexion" " et sécurité ». L'authentification à deux facteurs doit être" " active." ), "en": ( 'Generate one at https://account.apple.com, under "Sign-In and' ' Security". Two-factor authentication must be on.' ), }, "mail_preset_note_generic": { "fr": "Saisissez les serveurs de votre fournisseur.", "en": "Enter your provider's servers.", }, "mail_ask_app_password": { "fr": "Mot de passe d'application : ", "en": "App password: ", }, "mail_err_password_not_ascii": { "fr": ( "le mot de passe contient un caractère non ASCII, que ce client" " IMAP ne sait pas transmettre — il n'a pas été envoyé au" " serveur" ), "en": ( "the password contains a non-ASCII character this IMAP client" " cannot transmit — it was never sent to the server" ), }, "mail_err_no_kdbx_configured": { "fr": "aucun fichier kdbx configuré", "en": "no kdbx file configured", }, "mail_err_kdbx_unreadable": { "fr": "le fichier kdbx n'a pas pu être ouvert", "en": "the kdbx file could not be opened", }, "mail_err_no_vault_available": { "fr": "aucun coffre disponible : ni kdbx, ni trousseau système", "en": "no vault available: neither kdbx nor system keyring", }, "mail_err_keyring_plaintext": { "fr": ( "le trousseau du système écrirait le mot de passe en clair" " (backend" ), "en": ( "the system keyring would store the password in plaintext (backend" ), }, "mail_err_keyring_plaintext_hint": { "fr": "Utilisez un fichier kdbx, ou déverrouillez un vrai trousseau.", "en": "Use a kdbx file, or unlock a real keyring.", }, "mail_err_unknown_security": { "fr": "sécurité inconnue :", "en": "unknown security:", }, "mail_err_expected": {"fr": "(attendu", "en": "(expected"}, "mail_err_account_needs_name": { "fr": "un compte doit avoir un nom", "en": "an account must have a name", }, "mail_err_invalid_account_name": { "fr": "nom de compte invalide :", "en": "invalid account name:", }, "mail_err_account_name_reason": { "fr": "(il sert de nom de dossier et de référence de coffre)", "en": "(it is used as a folder name and vault reference)", }, "mail_err_account_unreadable": { "fr": "compte illisible :", "en": "unreadable account:", }, "mail_err_unknown_preset": { "fr": "préréglage inconnu :", "en": "unknown preset:", }, "mail_err_not_valid_json": { "fr": "n'est pas du JSON valide :", "en": "is not valid JSON:", }, "mail_err_should_contain_json_object": { "fr": "devrait contenir un objet JSON", "en": "should contain a JSON object", }, "mail_err_duplicate_account_names": { "fr": "noms de compte en double :", "en": "duplicate account names:", }, "mail_err_already_exists_relaunch": { "fr": "existe déjà — relancez avec l'option de remplacement", "en": "already exists — rerun with the overwrite option", }, "mail_err_symlink_refused": { "fr": "est un lien symbolique : cache refusé", "en": "is a symlink: cache refused", }, "mail_err_owned_by_other_user": { "fr": "appartient à un autre utilisateur : cache refusé", "en": "belongs to another user: cache refused", }, "mail_err_cache_unreadable": { "fr": "cache illisible, purgez-le et resynchronisez :", "en": "unreadable cache, purge it and resynchronise:", }, "mail_err_mode_requires_key_no_vault": { "fr": "exige une clé : aucun coffre fourni", "en": "requires a key: no vault provided", }, "mail_err_cache_not_open": { "fr": "cache non ouvert : appelez open() d'abord", "en": "cache not open: call open() first", }, "mail_err_unknown_folder_fields": { "fr": "champs de dossier inconnus :", "en": "unknown folder fields:", }, "mail_err_unterminated_ampersand": { "fr": "séquence & non terminée", "en": "unterminated & sequence", }, "mail_err_server_replied": { "fr": ": le serveur a répondu", "en": ": the server replied", }, "mail_err_no_body_for_uid": { "fr": "aucun corps rendu pour l'UID", "en": "no body returned for UID", }, "mail_err_imap_connection_prefix": { "fr": "connexion IMAP à", "en": "IMAP connection to", }, "mail_err_smtp_connection_prefix": { "fr": "connexion SMTP à", "en": "SMTP connection to", }, "mail_err_connection_refused_suffix": { "fr": "refusée :", "en": "refused:", }, "mail_err_message_needs_recipient": { "fr": "un message doit avoir au moins un destinataire", "en": "a message must have at least one recipient", }, "mail_err_attachment_missing": { "fr": "pièce jointe introuvable :", "en": "attachment not found:", }, "mail_err_no_recipient_nothing_sent": { "fr": "aucun destinataire : rien n'a été envoyé", "en": "no recipient: nothing was sent", }, "mail_err_send_refused": {"fr": "envoi refusé :", "en": "send refused:"}, # QEMU — outils de développement des VM graphiques "Python IDE, ERPLibre project pre-configured": { "fr": "IDE Python, projet ERPLibre pré-configuré", "en": "Python IDE, ERPLibre project pre-configured", }, "ERPLibre mobile development (x86_64 only)": { "fr": "développement mobile ERPLibre (x86_64 seulement)", "en": "ERPLibre mobile development (x86_64 only)", }, "GNOME extensions": { "fr": "Extensions GNOME", "en": "GNOME extensions", }, "suggested extensions + extension manager": { "fr": "extensions suggérées + gestionnaire d'extensions", "en": "suggested extensions + extension manager", }, "Development tools for the graphical VMs:": { "fr": "Outils de développement des VM graphiques :", "en": "Development tools for the graphical VMs:", }, "Development tools (graphical VMs):": { "fr": "Outils de développement (VM graphiques) :", "en": "Development tools (graphical VMs):", }, "Development tools:": { "fr": "Outils de développement :", "en": "Development tools:", }, "Disk needed:": {"fr": "Disque nécessaire :", "en": "Disk needed:"}, "Numbers separated by spaces, [all], blank = none:": { "fr": "Numéros séparés par des espaces, [tous], vide = aucun :", "en": "Numbers separated by spaces, [all], blank = none:", }, "No graphical VM: these tools are not installed.": { "fr": "Aucune VM graphique : ces outils ne seront pas installés.", "en": "No graphical VM: these tools are not installed.", }, "Partly skipped (arch or desktop):": { "fr": "En partie écartés (architecture ou bureau) :", "en": "Partly skipped (arch or desktop):", }, "Installing PyCharm (long)": { "fr": "Installation de PyCharm (long)", "en": "Installing PyCharm (long)", }, "no JetBrains build for": { "fr": "aucune archive JetBrains pour", "en": "no JetBrains build for", }, "PyCharm: project config skipped": { "fr": "PyCharm : configuration du projet non écrite", "en": "PyCharm: project config skipped", }, "PyCharm installed:": { "fr": "PyCharm installé :", "en": "PyCharm installed:", }, "PyCharm not installed (see above)": { "fr": "PyCharm non installé (voir ci-dessus)", "en": "PyCharm not installed (see above)", }, "Installing Android Studio (long)": { "fr": "Installation d'Android Studio (long)", "en": "Installing Android Studio (long)", }, "Android Studio: Google publishes x86_64 only": { "fr": "Android Studio : Google ne publie que du x86_64", "en": "Android Studio: Google publishes x86_64 only", }, "SDK shared through ANDROID_HOME:": { "fr": "SDK partagé via ANDROID_HOME :", "en": "SDK shared through ANDROID_HOME:", }, "Android Studio installed:": { "fr": "Android Studio installé :", "en": "Android Studio installed:", }, "Android Studio not installed (see above)": { "fr": "Android Studio non installé (voir ci-dessus)", "en": "Android Studio not installed (see above)", }, "no nested KVM: the emulator will not run": { "fr": "pas de KVM imbriqué : l'émulateur ne démarrera pas", "en": "no nested KVM: the emulator will not run", }, "Suggested GNOME extensions": { "fr": "Extensions GNOME suggérées", "en": "Suggested GNOME extensions", }, "not in the repos, skipped:": { "fr": "absent des dépôts, ignoré :", "en": "not in the repos, skipped:", }, "Enable them from Extension Manager, or:": { "fr": "À activer depuis le gestionnaire d'extensions, ou :", "en": "Enable them from Extension Manager, or:", }, "GNOME Shell not found, site extensions skipped": { "fr": "GNOME Shell introuvable, extensions du site ignorées", "en": "GNOME Shell not found, site extensions skipped", }, "installed and enabled:": { "fr": "installée et activée :", "en": "installed and enabled:", }, "not available for this GNOME, skipped:": { "fr": "indisponible pour ce GNOME, ignorée :", "en": "not available for this GNOME, skipped:", }, "log out and back in to load them": { "fr": "se déconnecter puis se reconnecter pour les charger", "en": "log out and back in to load them", }, "open the project once and close PyCharm; the .idea it writes is what the install configures": { "fr": "ouvrir le projet une fois puis fermer PyCharm : le .idea qu'il écrit est ce que l'installation configure", "en": "open the project once and close PyCharm; the .idea it writes is what the install configures", }, "command": {"fr": "commande", "en": "command"}, "release feed unreachable: unified build, it will ask for a JetBrains account": { "fr": "flux des versions injoignable : build unifié, il demandera un compte JetBrains", "en": "release feed unreachable: unified build, it will ask for a JetBrains account", }, "Creating the PyCharm project (first open)": { "fr": "Création du projet PyCharm (première ouverture)", "en": "Creating the PyCharm project (first open)", }, "PyCharm missing, step skipped": { "fr": "PyCharm absent, étape sautée", "en": "PyCharm missing, step skipped", }, "no Xvfb here, open PyCharm by hand": { "fr": "pas de Xvfb ici : ouvrir PyCharm à la main", "en": "no Xvfb here, open PyCharm by hand", }, "ERPLibre mobile (build)": { "fr": "ERPLibre mobile (compilation)", "en": "ERPLibre mobile (build)", }, "APK debug + Vitest, validates the VM": { "fr": "APK debug + Vitest, valide la VM", "en": "APK debug + Vitest, validates the VM", }, "Building ERPLibre mobile (long)": { "fr": "Compilation d'ERPLibre mobile (long)", "en": "Building ERPLibre mobile (long)", }, "detailed log in the VM:": { "fr": "journal détaillé dans la VM :", "en": "detailed log in the VM:", }, "FAILED:": {"fr": "ÉCHEC :", "en": "FAILED:"}, "probable cause:": {"fr": "cause probable :", "en": "probable cause:"}, "no known pattern, last lines:": { "fr": "aucun motif connu, dernières lignes :", "en": "no known pattern, last lines:", }, "a failed mobile build marks the VM as failed": { "fr": "une compilation mobile en échec marque la VM en échec", "en": "a failed mobile build marks the VM as failed", }, "ERPLibre venv (everything below needs it)": { "fr": "venv ERPLibre (tout ce qui suit en dépend)", "en": "ERPLibre venv (everything below needs it)", }, "mobile repository (additive manifest)": { "fr": "dépôt mobile (manifeste additif)", "en": "mobile repository (additive manifest)", }, "prerequisites of the upstream installer": { "fr": "prérequis de l'installateur amont", "en": "prerequisites of the upstream installer", }, "Android SDK, licences, NDK": { "fr": "SDK Android, licences, NDK", "en": "Android SDK, licences, NDK", }, "SDK platform required by the project": { "fr": "plateforme SDK réclamée par le projet", "en": "SDK platform required by the project", }, "npm dependencies": { "fr": "dépendances npm", "en": "npm dependencies", }, "web bundle (vite build)": { "fr": "bundle web (vite build)", "en": "web bundle (vite build)", }, "native sync (capacitor)": { "fr": "synchronisation native (capacitor)", "en": "native sync (capacitor)", }, "debug APK (gradle)": { "fr": "APK debug (gradle)", "en": "debug APK (gradle)", }, "Vitest tests": {"fr": "tests Vitest", "en": "Vitest tests"}, "APK built:": {"fr": "APK construit :", "en": "APK built:"}, "browser debugging (no Android):": { "fr": "déverminage au navigateur (sans Android) :", "en": "browser debugging (no Android):", }, "no APK produced": { "fr": "aucun APK produit", "en": "no APK produced", }, "disk full": {"fr": "disque plein", "en": "disk full"}, "SDK platform missing": { "fr": "plateforme SDK absente", "en": "SDK platform missing", }, "SDK not found (ANDROID_HOME)": { "fr": "SDK introuvable (ANDROID_HOME)", "en": "SDK not found (ANDROID_HOME)", }, "SDK licences not accepted": { "fr": "licences SDK non acceptées", "en": "SDK licences not accepted", }, "NDK missing": {"fr": "NDK absent", "en": "NDK missing"}, "JDK required by the project missing": { "fr": "JDK réclamé par le projet absent", "en": "JDK required by the project missing", }, "Gradle running on too old a JDK": { "fr": "Gradle tourne sur un JDK trop ancien", "en": "Gradle running on too old a JDK", }, "SDK already there (upstream installer replays)": { "fr": "SDK déjà là (l'installateur amont se rejoue)", "en": "SDK already there (upstream installer replays)", }, "cross-compiled protoc run on the host": { "fr": "protoc compilé pour la cible, exécuté sur l'hôte", "en": "cross-compiled protoc run on the host", }, "JDK/Gradle mismatch": { "fr": "JDK et Gradle incompatibles", "en": "JDK/Gradle mismatch", }, "Gradle dependency unreachable (network?)": { "fr": "dépendance Gradle injoignable (réseau ?)", "en": "Gradle dependency unreachable (network?)", }, "Vitest tests failed": { "fr": "tests Vitest en échec", "en": "Vitest tests failed", }, "ERPLibre venv incomplete (no pip: python3-venv)": { "fr": "venv ERPLibre incomplet (pas de pip : python3-venv)", "en": "ERPLibre venv incomplete (no pip: python3-venv)", }, "mobile repository missing": { "fr": "dépôt mobile absent", "en": "mobile repository missing", }, "ERPLibre venv missing (incomplete install)": { "fr": "venv ERPLibre absent (installation incomplète)", "en": "ERPLibre venv missing (incomplete install)", }, "smoother, without X11:": { "fr": "plus fluide, sans X11 :", "en": "smoother, without X11:", }, "Android emulator": {"fr": "Émulateur Android", "en": "Android emulator"}, "Android emulator (start, tunnel, scrcpy)": { "fr": "📱 Émulateur Android (démarrer, tunnel, scrcpy)", "en": "📱 Android emulator (start, tunnel, scrcpy)", }, "An emulator is already running on this VM.": { "fr": "Un émulateur tourne déjà sur cette VM.", "en": "An emulator is already running on this VM.", }, "Only one per AVD; close it first:": { "fr": "Un seul par AVD ; le fermer d'abord :", "en": "Only one per AVD; close it first:", }, "Close it now? (y/N): ": { "fr": "Le fermer maintenant ? (o/N) : ", "en": "Close it now? (y/N): ", }, "Closed.": {"fr": "Fermé.", "en": "Closed."}, "Show a window?": { "fr": "Afficher une fenêtre ?", "en": "Show a window?", }, "No window - stream with scrcpy (smoother)": { "fr": "Sans fenêtre — flux par scrcpy (plus fluide)", "en": "No window - stream with scrcpy (smoother)", }, "Window over ssh -X (raw pixels, slower)": { "fr": "Fenêtre par ssh -X (pixels bruts, plus lent)", "en": "Window over ssh -X (raw pixels, slower)", }, "X11 compression is on (-XC); the screen is 540x1140.": { "fr": "La compression X11 est active (-XC) ; l'écran fait 540x1140.", "en": "X11 compression is on (-XC); the screen is 540x1140.", }, "Starting the emulator without a window...": { "fr": "Démarrage de l'émulateur sans fenêtre…", "en": "Starting the emulator without a window...", }, "Could not start it:": { "fr": "Démarrage impossible :", "en": "Could not start it:", }, "Started. Boot takes about a minute; log in the VM:": { "fr": "Démarré. L'amorçage prend environ une minute ; journal dans la VM :", "en": "Started. Boot takes about a minute; log in the VM:", }, "1. Emulator started, without a window.": { "fr": "1. Émulateur démarré, sans fenêtre.", "en": "1. Emulator started, without a window.", }, "If scrcpy will run on THIS machine, I can open it.": { "fr": "Si scrcpy tournera sur CETTE machine, je peux l'ouvrir.", "en": "If scrcpy will run on THIS machine, I can open it.", }, "Open the tunnel now? (y/N): ": { "fr": "Ouvrir le tunnel maintenant ? (o/N) : ", "en": "Open the tunnel now? (y/N): ", }, "Port already in use here:": { "fr": "Port déjà occupé ici :", "en": "Port already in use here:", }, "Close the other tunnel first:": { "fr": "Fermer l'autre tunnel d'abord :", "en": "Close the other tunnel first:", }, "Tunnel failed:": {"fr": "Tunnel en échec :", "en": "Tunnel failed:"}, "Tunnel open on localhost:": { "fr": "Tunnel ouvert sur localhost:", "en": "Tunnel open on localhost:", }, "Then:": {"fr": "Puis :", "en": "Then:"}, "To close it:": {"fr": "Pour le fermer :", "en": "To close it:"}, "Android emulator (adb 5555, then scrcpy)": { "fr": "Émulateur Android (adb 5555, puis scrcpy)", "en": "Android emulator (adb 5555, then scrcpy)", }, "Android emulator over adb + scrcpy": { "fr": "Émulateur Android par adb + scrcpy", "en": "Android emulator over adb + scrcpy", }, "1. In the VM, start the emulator WITHOUT a window:": { "fr": "1. Dans la VM, démarrer l'émulateur SANS fenêtre :", "en": "1. In the VM, start the emulator WITHOUT a window:", }, "2. Open the tunnel from YOUR workstation:": { "fr": "2. Ouvrir le tunnel depuis VOTRE poste :", "en": "2. Open the tunnel from YOUR workstation:", }, "3. Then, still on your workstation:": { "fr": "3. Puis, toujours sur votre poste :", "en": "3. Then, still on your workstation:", }, "scrcpy on Debian/Ubuntu:": { "fr": "scrcpy sur Debian/Ubuntu :", "en": "scrcpy on Debian/Ubuntu:", }, "Android emulator (Pixel)": { "fr": "Émulateur Android (Pixel)", "en": "Android emulator (Pixel)", }, "AVD viewable over ssh -X": { "fr": "AVD visible par ssh -X", "en": "AVD viewable over ssh -X", }, "Android emulator (AVD)": { "fr": "Émulateur Android (AVD)", "en": "Android emulator (AVD)", }, "no /dev/kvm: nested virtualisation is off on the host": { "fr": "pas de /dev/kvm : virtualisation imbriquée coupée sur l'hôte", "en": "no /dev/kvm: nested virtualisation is off on the host", }, "user added to the kvm group (effective at next login)": { "fr": "utilisateur ajouté au groupe kvm (effectif à la prochaine session)", "en": "user added to the kvm group (effective at next login)", }, "emulator and system image": { "fr": "émulateur et image système", "en": "emulator and system image", }, "Pixel profile, smallest screen": { "fr": "profil Pixel, plus petit écran", "en": "Pixel profile, smallest screen", }, "create the AVD": {"fr": "création de l'AVD", "en": "create the AVD"}, "AVD ready:": {"fr": "AVD prêt :", "en": "AVD ready:"}, "open it from your workstation:": { "fr": "à ouvrir depuis votre poste :", "en": "open it from your workstation:", }, "then install the APK:": { "fr": "puis installer l'APK :", "en": "then install the APK:", }, "ERPLibre mobile, Android SDK (long)": { "fr": "ERPLibre mobile, SDK Android (long)", "en": "ERPLibre mobile, Android SDK (long)", }, "Gradle task failed": { "fr": "tâche Gradle en échec", "en": "Gradle task failed", }, "project created, the install will configure it": { "fr": "projet créé, l'installation va le configurer", "en": "project created, the install will configure it", }, "no .idea: open PyCharm once, then": { "fr": "pas de .idea : ouvrir PyCharm une fois, puis", "en": "no .idea: open PyCharm once, then", }, "project": {"fr": "projet", "en": "project"}, "Instance": { "fr": "🛰 Instance", "en": "🛰 Instance", }, "Monitoring - a backup, a remote copy or a live instance": { "fr": "🛰 Monitoring - une sauvegarde, une copie distante ou une instance vivante", "en": "🛰 Monitoring - a backup, a remote copy or a live instance", }, "Inspect an instance.": { "fr": "Ausculter une instance.", "en": "Inspect an instance.", }, "A local backup .zip": { "fr": "Une sauvegarde .zip locale", "en": "A local backup .zip", }, "A remote backup (https + master password)": { "fr": "Une sauvegarde distante (https + mot de passe maître)", "en": "A remote backup (https + master password)", }, "A live remote instance": { "fr": "Une instance vivante distante", "en": "A live remote instance", }, "An API key": { "fr": "Une clé d'API", "en": "An API key", }, "A password": { "fr": "Un mot de passe", "en": "A password", }, "API key: ": { "fr": "Clé d'API : ", "en": "API key: ", }, "Password: ": { "fr": "Mot de passe : ", "en": "Password: ", }, "User login: ": { "fr": "Identifiant : ", "en": "User login: ", }, "Instance URL (ex. https://example.com): ": { "fr": "URL de l'instance (ex. https://exemple.com) : ", "en": "Instance URL (ex. https://example.com): ", }, "Database name on that instance: ": { "fr": "Nom de la base sur cette instance : ", "en": "Database name on that instance: ", }, "Cannot connect: ": { "fr": "Connexion impossible : ", "en": "Cannot connect: ", }, "Connected as uid": { "fr": "Connecté sous l'uid", "en": "Connected as uid", }, "The instance refused these credentials.": { "fr": "L'instance a refusé ces identifiants.", "en": "The instance refused these credentials.", }, "Monitoring only reads; refused method:": { "fr": "Le monitoring ne fait que lire ; méthode refusée :", "en": "Monitoring only reads; refused method:", }, "Database:": { "fr": "Base :", "en": "Database:", }, "Live instance:": { "fr": "Instance vivante :", "en": "Live instance:", }, "Database name (default=": { "fr": "Nom de la base (défaut=", "en": "Database name (default=", }, "Neutralize the database (Y/n)? ": { "fr": "Neutraliser la base (O/n) ? ", "en": "Neutralize the database (Y/n)? ", }, "The restore failed.": { "fr": "La restauration a échoué.", "en": "The restore failed.", }, "The download did not produce a usable file.": { "fr": "Le téléchargement n'a pas produit de fichier utilisable.", "en": "The download did not produce a usable file.", }, "db_restore only reads image_db/. Link it there": { "fr": "db_restore ne lit que image_db/. Y poser un lien", "en": "db_restore only reads image_db/. Link it there", }, "Using the file already in image_db: ": { "fr": "On prend le fichier déjà dans image_db : ", "en": "Using the file already in image_db: ", }, "Cannot link into image_db: ": { "fr": "Impossible de poser le lien dans image_db : ", "en": "Cannot link into image_db: ", }, "You can log in with test / test.": { "fr": "Vous pouvez vous connecter avec test / test.", "en": "You can log in with test / test.", }, "update_prod_to_dev did not finish: do not": { "fr": "update_prod_to_dev n'a pas fini : ne comptez pas", "en": "update_prod_to_dev did not finish: do not", }, "count on the test/test account.": { "fr": "sur le compte test/test.", "en": "count on the test/test account.", }, "database.is_neutralized is set.": { "fr": "database.is_neutralized est posé.", "en": "database.is_neutralized is set.", }, "database.is_neutralized is NOT set — Odoo does not": { "fr": "database.is_neutralized n'est PAS posé — Odoo ne considère pas", "en": "database.is_neutralized is NOT set — Odoo does not", }, "consider this database neutralised.": { "fr": "cette base comme neutralisée.", "en": "consider this database neutralised.", }, "scheduled actions are still active.": { "fr": "actions planifiées sont encore actives.", "en": "scheduled actions are still active.", }, "No scheduled action is active.": { "fr": "Aucune action planifiée n'est active.", "en": "No scheduled action is active.", }, "No mail server at all: Odoo falls back to smtp_server": { "fr": "Aucun serveur de courriel : Odoo retombe sur le smtp_server", "en": "No mail server at all: Odoo falls back to smtp_server", }, "from the config file. A blocking one is safer than none.": { "fr": "du fichier de configuration. Un serveur bouchon vaut mieux que rien.", "en": "from the config file. A blocking one is safer than none.", }, "payment provider(s) are neither disabled nor": { "fr": "fournisseur(s) de paiement ne sont ni désactivés ni", "en": "payment provider(s) are neither disabled nor", }, "in test mode.": { "fr": "en mode test.", "en": "in test mode.", }, "Run": { "fr": "Lancer", "en": "Run", }, "Enter to run it.": { "fr": "Entrée pour le lancer.", "en": "Enter to run it.", }, "Not available for this source.": { "fr": "Indisponible pour cette provenance.", "en": "Not available for this source.", }, "Migration leftovers": { "fr": "🚚 Restant de migration", "en": "🚚 Migration leftovers", }, "What a migration left behind, judged without needing the step-by-step databases.": { "fr": "Ce qu'une migration a laissé derrière elle, jugé sans avoir besoin des bases de palier.", "en": "What a migration left behind, judged without needing the step-by-step databases.", }, "It reads pg_catalog — indexes and real tables — which no RPC session exposes.": { "fr": "Il lit pg_catalog — les index et les vraies tables — qu'aucune session RPC n'expose.", "en": "It reads pg_catalog — indexes and real tables — which no RPC session exposes.", }, "Every view someone changed, and every website copy that shadows a module view.": { "fr": "Chaque vue que quelqu'un a modifiée, et chaque copie de site web qui masque une vue de module.", "en": "Every view someone changed, and every website copy that shadows a module view.", }, "Comparing a copy with the module view it hides is a join on arch_db, done in SQL.": { "fr": "Comparer une copie à la vue de module qu'elle masque est une jointure sur arch_db, faite en SQL.", "en": "Comparing a copy with the module view it hides is a join on arch_db, done in SQL.", }, "Fields and models added outside any module, and which of them have no column behind them.": { "fr": "Champs et modèles ajoutés hors de tout module, et lesquels n'ont aucune colonne derrière eux.", "en": "Fields and models added outside any module, and which of them have no column behind them.", }, "Telling a declared field from a real column means reading pg_attribute.": { "fr": "Distinguer un champ déclaré d'une vraie colonne demande de lire pg_attribute.", "en": "Telling a declared field from a real column means reading pg_attribute.", }, "What a migration left behind, read in one database.": { "fr": "Ce qu'une migration a laissé derrière elle, lu dans une seule base.", "en": "What a migration left behind, read in one database.", }, "Migration residue in": { "fr": "Restant de migration dans", "en": "Migration residue in", }, "base module version:": { "fr": "version du module base :", "en": "base module version:", }, "None of the checks found anything.": { "fr": "Aucun contrôle n'a rien trouvé.", "en": "None of the checks found anything.", }, "This reads one database on its own — it cannot see": { "fr": "Ceci ne lit qu'une base isolée — il ne peut pas voir", "en": "This reads one database on its own — it cannot see", }, "what an earlier step silently dropped.": { "fr": "ce qu'un palier antérieur a laissé tomber en silence.", "en": "what an earlier step silently dropped.", }, "could not read": { "fr": "lecture impossible", "en": "could not read", }, "no repair tool yet": { "fr": "pas encore d'outil de réparation", "en": "no repair tool yet", }, "Modules stuck between two states": { "fr": "Modules figés entre deux états", "en": "Modules stuck between two states", }, "A migration that stopped mid-flight leaves them there; Odoo will retry the transition at every start.": { "fr": "Une migration arrêtée en vol les laisse ainsi ; Odoo retentera la transition à chaque démarrage.", "en": "A migration that stopped mid-flight leaves them there; Odoo will retry the transition at every start.", }, "Languages whose active flag is NULL": { "fr": "Langues dont le drapeau actif est NULL", "en": "Languages whose active flag is NULL", }, "A boolean that is neither true nor false: the language is listed nowhere and cannot be re-enabled from the interface.": { "fr": "Un booléen qui n'est ni vrai ni faux : la langue n'est listée nulle part et ne peut plus être réactivée depuis l'interface.", "en": "A boolean that is neither true nor false: the language is listed nowhere and cannot be re-enabled from the interface.", }, "Indexes duplicated by the Odoo 17 renaming": { "fr": "Index doublés par le renommage d'Odoo 17", "en": "Indexes duplicated by the Odoo 17 renaming", }, "Odoo 17 changed the naming convention without dropping the old index: both are maintained on every write. This count is a cheap signal — the repair tool compares columns and uniqueness, and is the one to trust.": { "fr": "Odoo 17 a changé la convention de nommage sans supprimer l'ancien index : les deux sont entretenus à chaque écriture. Ce compte est un indicateur bon marché — l'outil de réparation compare les colonnes et l'unicité, c'est lui qui fait foi.", "en": "Odoo 17 changed the naming convention without dropping the old index: both are maintained on every write. This count is a cheap signal — the repair tool compares columns and uniqueness, and is the one to trust.", }, "Default pricelist missing while product is installed": { "fr": "Liste de prix par défaut absente alors que product est installé", "en": "Default pricelist missing while product is installed", }, "product.list0 was declared up to Odoo 16 only; nothing recreates it, and a quotation has no price list to pick.": { "fr": "product.list0 n'a été déclaré que jusqu'à Odoo 16 ; rien ne le recrée, et un devis n'a aucune liste de prix à choisir.", "en": "product.list0 was declared up to Odoo 16 only; nothing recreates it, and a quotation has no price list to pick.", }, "Views bound to a model that no longer exists": { "fr": "Vues liées à un modèle qui n'existe plus", "en": "Views bound to a model that no longer exists", }, "Opening one raises; the menu that leads to it is a dead end.": { "fr": "En ouvrir une lève une erreur ; le menu qui y mène est un cul-de-sac.", "en": "Opening one raises; the menu that leads to it is a dead end.", }, "Views inheriting a view that is gone": { "fr": "Vues héritant d'une vue disparue", "en": "Views inheriting a view that is gone", }, "The whole inheritance chain below them stops rendering.": { "fr": "Toute la chaîne d'héritage en dessous cesse de s'afficher.", "en": "The whole inheritance chain below them stops rendering.", }, "External ids pointing at a model that is gone": { "fr": "Identifiants externes pointant un modèle disparu", "en": "External ids pointing at a model that is gone", }, "Every module update that resolves one of them fails.": { "fr": "Chaque mise à jour de module qui en résout un échoue.", "en": "Every module update that resolves one of them fails.", }, "Attachments whose carrying field is gone": { "fr": "Pièces jointes dont le champ porteur a disparu", "en": "Attachments whose carrying field is gone", }, "Odoo raises a KeyError merely checking them, and nothing will ever read them again.": { "fr": "Odoo lève un KeyError rien qu'en les contrôlant, et plus rien ne les lira jamais.", "en": "Odoo raises a KeyError merely checking them, and nothing will ever read them again.", }, "A local database": { "fr": "Une base de données locale", "en": "A local database", }, "State of the instance": { "fr": "🩺 État de l'instance", "en": "🩺 State of the instance", }, "Neutralisation, scheduler, backups, queues and who is an administrator — read for the use you intend.": { "fr": "Neutralisation, cadenceur, sauvegardes, files et qui est administrateur — lu pour l'usage que vous en faites.", "en": "Neutralisation, scheduler, backups, queues and who is an administrator — read for the use you intend.", }, "Several checks read tables no RPC session exposes, and the lateness of a job is computed in SQL.": { "fr": "Plusieurs contrôles lisent des tables qu'aucune session RPC n'expose, et le retard d'une tâche se calcule en SQL.", "en": "Several checks read tables no RPC session exposes, and the lateness of a job is computed in SQL.", }, "A development copy (restored, neutralised)": { "fr": "Une copie de développement (restaurée, neutralisée)", "en": "A development copy (restored, neutralised)", }, "An instance in service": { "fr": "Une instance en service", "en": "An instance in service", }, "Anonymise a copy": { "fr": "🎭 Anonymiser une copie", "en": "🎭 Anonymise a copy", }, "Replace names, texts and numbers with meaningless ones so the copy can be shared. No AI: words from a list, numbers drawn at random, written by SQL.": { "fr": "Remplacer noms, textes et nombres par des valeurs sans intérêt, pour pouvoir partager la copie. Sans IA : des mots pris dans une liste, des nombres tirés au hasard, écrits en SQL.", "en": "Replace names, texts and numbers with meaningless ones so the copy can be shared. No AI: words from a list, numbers drawn at random, written by SQL.", }, "This one WRITES. It is offered only for a database you restored here — never for an instance in service.": { "fr": "Celle-ci ÉCRIT. Elle n'est offerte que pour une base restaurée ici — jamais pour une instance en service.", "en": "This one WRITES. It is offered only for a database you restored here — never for an instance in service.", }, "This DESTROYS the data of": { "fr": "Ceci DÉTRUIT les données de", "en": "This DESTROYS the data of", }, "there is no undo.": { "fr": "il n'y a pas de retour en arrière.", "en": "there is no undo.", }, "Type the database name to confirm (empty to cancel): ": { "fr": "Retapez le nom de la base pour confirmer (vide pour annuler) : ", "en": "Type the database name to confirm (empty to cancel): ", }, "Cancelled: nothing was written.": { "fr": "Annulé : rien n'a été écrit.", "en": "Cancelled: nothing was written.", }, "Nothing to anonymise: nothing to confirm.": { "fr": "Rien à anonymiser : rien à confirmer.", "en": "Nothing to anonymise: nothing to confirm.", }, "Hybrid: the default personal-data models, adjusted": { "fr": "Hybride : les modèles à données personnelles par défaut, ajustés", "en": "Hybrid: the default personal-data models, adjusted", }, "Whitelist: only the models I name": { "fr": "Liste blanche : seulement les modèles que je nomme", "en": "Whitelist: only the models I name", }, "Blacklist: every model except those I name": { "fr": "Liste noire : tous les modèles sauf ceux que je nomme", "en": "Blacklist: every model except those I name", }, "Models to ADD, comma separated (empty for none): ": { "fr": "Modèles à AJOUTER, séparés par des virgules (vide pour aucun) : ", "en": "Models to ADD, comma separated (empty for none): ", }, "Models to EXCLUDE, comma separated: ": { "fr": "Modèles à EXCLURE, séparés par des virgules : ", "en": "Models to EXCLUDE, comma separated: ", }, "A whitelist with no model would do nothing.": { "fr": "Une liste blanche sans modèle ne ferait rien.", "en": "A whitelist with no model would do nothing.", }, "Python file declaring MOTS (empty for the built-in): ": { "fr": "Fichier Python déclarant MOTS (vide pour la liste intégrée) : ", "en": "Python file declaring MOTS (empty for the built-in): ", }, "Nothing to anonymise with these lists.": { "fr": "Rien à anonymiser avec ces listes.", "en": "Nothing to anonymise with these lists.", }, "column(s)": { "fr": "colonne(s)", "en": "column(s)", }, "dry run, nothing written": { "fr": "marche à blanc, rien n'est écrit", "en": "dry run, nothing written", }, "text": { "fr": "texte", "en": "text", }, "numeric": { "fr": "nombre", "en": "numeric", }, "translated (jsonb)": { "fr": "traduit (jsonb)", "en": "translated (jsonb)", }, "unique": { "fr": "unique", "en": "unique", }, "Use --apply --confirm to write.": { "fr": "Utiliser --apply --confirm pour écrire.", "en": "Use --apply --confirm to write.", }, "Replace the data of a COPY with meaningless data.": { "fr": "Remplacer les données d'une COPIE par des données sans intérêt.", "en": "Replace the data of a COPY with meaningless data.", }, "comma separated, adds to the mode": { "fr": "séparés par des virgules, s'ajoutent au mode", "en": "comma separated, adds to the mode", }, "comma separated, removed from it": { "fr": "séparés par des virgules, retirés du mode", "en": "comma separated, removed from it", }, "python file declaring MOTS": { "fr": "fichier python déclarant MOTS", "en": "python file declaring MOTS", }, "repeat the database name; --apply refuses without it": { "fr": "répéter le nom de la base ; --apply refuse sans lui", "en": "repeat the database name; --apply refuses without it", }, "Refusing to write: --confirm must repeat": { "fr": "Écriture refusée : --confirm doit répéter", "en": "Refusing to write: --confirm must repeat", }, "Nothing was written:": { "fr": "Rien n'a été écrit :", "en": "Nothing was written:", }, "nothing to do.": { "fr": "rien à faire.", "en": "nothing to do.", }, "The dry run ended on an unexpected code:": { "fr": "La marche à blanc s'est terminée sur un code inattendu :", "en": "The dry run ended on an unexpected code:", }, "This file declares no MOTS:": { "fr": "Ce fichier ne déclare aucun MOTS :", "en": "This file declares no MOTS:", }, "Unknown mode:": { "fr": "Mode inconnu :", "en": "Unknown mode:", }, "Duplicate": { "fr": "Copie", "en": "Copy", }, "Duplicate a database": { "fr": "📑 Dupliquer une base de données", "en": "📑 Duplicate a database", }, "Name of the copy (default=": { "fr": "Nom de la copie (défaut=", "en": "Name of the copy (default=", }, "Neutralize the copy (Y/n)? ": { "fr": "Neutraliser la copie (O/n) ? ", "en": "Neutralize the copy (Y/n)? ", }, "The copy will keep its scheduled actions, its": { "fr": "La copie gardera ses actions planifiées, son", "en": "The copy will keep its scheduled actions, its", }, "outgoing mail and its payment providers.": { "fr": "courriel sortant et ses fournisseurs de paiement.", "en": "outgoing mail and its payment providers.", }, "The duplication failed.": { "fr": "La duplication a échoué.", "en": "The duplication failed.", }, "Cannot read the copy back: ": { "fr": "Impossible de relire la copie : ", "en": "Cannot read the copy back: ", }, "Duplicate a database, filestore included.": { "fr": "Dupliquer une base, filestore compris.", "en": "Duplicate a database, filestore included.", }, "the copy": { "fr": "la copie", "en": "the copy", }, "disable crons, outgoing mail and payment providers": { "fr": "désactiver les crons, le courriel sortant et les fournisseurs de paiement", "en": "disable crons, outgoing mail and payment providers", }, "The source and the copy cannot share a name.": { "fr": "La source et la copie ne peuvent pas porter le même nom.", "en": "The source and the copy cannot share a name.", }, "No such database: ": { "fr": "Base introuvable : ", "en": "No such database: ", }, "This database already exists: ": { "fr": "Cette base existe déjà : ", "en": "This database already exists: ", }, "cannot neutralise: that arrived in Odoo 16.": { "fr": "ne sait pas neutraliser : c'est arrivé avec Odoo 16.", "en": "cannot neutralise: that arrived in Odoo 16.", }, "Cannot find the virtualenv for this checkout.": { "fr": "Venv introuvable pour ce checkout.", "en": "Cannot find the virtualenv for this checkout.", }, "Cannot find the Odoo source for this checkout.": { "fr": "Sources Odoo introuvables pour ce checkout.", "en": "Cannot find the Odoo source for this checkout.", }, "neutralised": { "fr": "neutralisée", "en": "neutralised", }, "Done:": { "fr": "Fait :", "en": "Done:", }, "NOT neutralised: its crons run, its mail leaves and": { "fr": "PAS neutralisée : ses crons tournent, son courriel part et", "en": "NOT neutralised: its crons run, its mail leaves and", }, "its payment providers can charge.": { "fr": "ses fournisseurs de paiement peuvent débiter.", "en": "its payment providers can charge.", }, "Missing script: ": { "fr": "Script introuvable : ", "en": "Missing script: ", }, "Odoo's own neutralisation": { "fr": "la neutralisation d'Odoo lui-même", "en": "Odoo's own neutralisation", }, "This route does not set database.is_neutralized, does": { "fr": "Ce chemin ne pose pas database.is_neutralized, ne", "en": "This route does not set database.is_neutralized, does", }, "not disable crons, and leaves payment keys in place.": { "fr": "désactive pas les crons, et laisse les clés de paiement en place.", "en": "not disable crons, and leaves payment keys in place.", }, "column(s) hold identifier paths and are left": { "fr": "colonne(s) portent des chemins d'identifiants et sont laissées", "en": "column(s) hold identifier paths and are left", }, "alone:": { "fr": "intactes :", "en": "alone:", }, # VPN (script/todo/vpn_menu.py, script/vpn/) "VPN & tunnels": { "fr": "🔐 VPN et tunnels", "en": "🔐 VPN & tunnels", }, "VPN - Tunnels (L2TP/IPsec, WireGuard, OpenVPN...)": { "fr": "🚇 VPN - Tunnels (L2TP/IPsec, WireGuard, OpenVPN...)", "en": "🚇 VPN - Tunnels (L2TP/IPsec, WireGuard, OpenVPN...)", }, # Network — reverse proxy "Odoo reverse proxy (pages and websocket on one port)": { "fr": "🔀 Mandataire inverse Odoo (pages et websocket sur un port)", "en": "🔀 Odoo reverse proxy (pages and websocket on one port)", }, "Listen on:": { "fr": "Écoute :", "en": "Listen on:", }, "Local only (127.0.0.1)": { "fr": "🏠 Cette machine seulement (127.0.0.1)", "en": "🏠 This machine only (127.0.0.1)", }, "Whole network (0.0.0.0)": { "fr": "🌐 Tout le réseau (0.0.0.0)", "en": "🌐 Whole network (0.0.0.0)", }, "The proxy is reachable by every machine on the network.": { "fr": "Le mandataire est joignable par toute machine du réseau.", "en": "The proxy is reachable by every machine on the network.", }, "Ports read from": { "fr": "Ports lus dans", "en": "Ports read from", }, "is missing: Odoo ignores the X-Forwarded-* headers.": { "fr": "manque : Odoo ignore les en-têtes X-Forwarded-*.", "en": "is missing: Odoo ignores the X-Forwarded-* headers.", }, "no bus port listens, /websocket will fail.": { "fr": "aucun port de bus n'écoute, /websocket échouera.", "en": "no bus port listens, /websocket will fail.", }, "Ctrl+C stops the proxy.": { "fr": "Ctrl+C arrête le mandataire.", "en": "Ctrl+C stops the proxy.", }, "Local TLS certificates for testing (HTTPS)": { "fr": "🔐 Certificats TLS locaux pour les tests (HTTPS)", "en": "🔐 Local TLS certificates for testing (HTTPS)", }, "Protocol:": { "fr": "Protocole :", "en": "Protocol:", }, "local certificate": { "fr": "certificat local", "en": "local certificate", }, "No local certificate yet: issuing one.": { "fr": "Aucun certificat local : émission d'un certificat.", "en": "No local certificate yet: issuing one.", }, "Authority to import in the browser:": { "fr": "Autorité à importer dans le navigateur :", "en": "Authority to import in the browser:", }, "Server certificate:": { "fr": "Certificat serveur :", "en": "Server certificate:", }, "Names covered:": { "fr": "Noms couverts :", "en": "Names covered:", }, "Other names or addresses, comma separated (Enter: none): ": { "fr": "Autres noms ou adresses, séparés par des virgules (Entrée : aucun) : ", "en": "Other names or addresses, comma separated (Enter: none): ", }, "Import the authority once (Firefox: Settings › Certificates › Authorities › Import); a new server certificate needs no new import.": { "fr": "Importer l'autorité une seule fois (Firefox : Paramètres › Certificats › Autorités › Importer) ; un nouveau certificat serveur n'exige aucun nouvel import.", "en": "Import the authority once (Firefox: Settings › Certificates › Authorities › Import); a new server certificate needs no new import.", }, "VPN tunnels: connect, profiles, vault secrets": { "fr": "Tunnels VPN : connexion, profils, secrets du coffre", "en": "VPN tunnels: connect, profiles, vault secrets", }, "Connection": { "fr": "🔗 Connexion", "en": "🔗 Connection", }, "VPN - Connect a profile": { "fr": "🟢 VPN - Connecter un profil", "en": "🟢 VPN - Connect a profile", }, "VPN - Disconnect a profile": { "fr": "🔴 VPN - Déconnecter un profil", "en": "🔴 VPN - Disconnect a profile", }, "VPN - Status and diagnosis": { "fr": "🩺 VPN - État et diagnostic", "en": "🩺 VPN - Status and diagnosis", }, "Profiles & secrets": { "fr": "🗂 Profils et secrets", "en": "🗂 Profiles & secrets", }, "VPN - Add or edit a profile": { "fr": "📝 VPN - Ajouter ou modifier un profil", "en": "📝 VPN - Add or edit a profile", }, "VPN - Store secrets in the vault": { "fr": "🔑 VPN - Déposer les secrets dans le coffre", "en": "🔑 VPN - Store secrets in the vault", }, "VPN - Show the rendered configuration (dry-run)": { "fr": "🔍 VPN - Afficher la configuration rendue (à blanc)", "en": "🔍 VPN - Show the rendered configuration (dry-run)", }, "VPN - Delete a profile": { "fr": "🗑 VPN - Supprimer un profil", "en": "🗑 VPN - Delete a profile", }, "VPN - Install the client packages": { "fr": "📦 VPN - Installer les paquets client", "en": "📦 VPN - Install the client packages", }, "VPN - What can this machine do?": { "fr": "🧰 VPN - Ce que cette machine sait faire", "en": "🧰 VPN - What can this machine do?", }, "Which technology?": { "fr": "Quelle technologie ?", "en": "Which technology?", }, "VPN - Create a profile from a site preset": { "fr": "\U0001f3db VPN - Créer un profil à partir d'un préréglage de site", "en": "\U0001f3db VPN - Create a profile from a site preset", }, "VPN - Import an AnyConnect profile (.xml)": { "fr": "\U0001f4e5 VPN - Importer un profil AnyConnect (.xml)", "en": "\U0001f4e5 VPN - Import an AnyConnect profile (.xml)", }, "An AnyConnect profile usually sits in" " /opt/cisco/secureclient/vpn/profile/ (or .../anyconnect/profile/).": { "fr": ( "Un profil AnyConnect se trouve d'ordinaire dans" " /opt/cisco/secureclient/vpn/profile/ (ou" " .../anyconnect/profile/)." ), "en": ( "An AnyConnect profile usually sits in" " /opt/cisco/secureclient/vpn/profile/ (or" " .../anyconnect/profile/)." ), }, "Path to the .xml profile": { "fr": "Chemin du profil .xml", "en": "Path to the .xml profile", }, "Gateway": { "fr": "Passerelle", "en": "Gateway", }, "Connection group": { "fr": "Groupe de connexion", "en": "Connection group", }, "Presets written: ": { "fr": "Préréglages écrits : ", "en": "Presets written: ", }, "Next step: create a profile from one of them. The .xml carries no" " username and does not say whether the service authenticates by" " password or by web form.": { "fr": ( "Étape suivante : créer un profil à partir de l'un d'eux. Le" " .xml ne porte aucun identifiant et ne dit pas si le service" " authentifie par mot de passe ou par formulaire web." ), "en": ( "Next step: create a profile from one of them. The .xml carries" " no username and does not say whether the service" " authenticates by password or by web form." ), }, "SSO helper driving a real browser (empty: openconnect-sso from" " the PATH)": { "fr": ( "Greffon SSO pilotant un vrai navigateur (vide :" " openconnect-sso trouvé dans le PATH)" ), "en": ( "SSO helper driving a real browser (empty: openconnect-sso" " from the PATH)" ), }, "AnyConnect version announced to the gateway": { "fr": "Version AnyConnect annoncée à la passerelle", "en": "AnyConnect version announced to the gateway", }, "kdbx_no_terminal": { "fr": ( "Pas de terminal pour saisir le mot de passe du coffre :" " coffre non ouvert." ), "en": ("No terminal to type the vault password: vault left closed."), }, "Some gateways demand an embedded browser (SAML): openconnect stops on" " \u00ab No SSO handler \u00bb and a helper is needed for the web step. It is" " optional, and its upstream is no longer maintained.": { "fr": ( "Certaines passerelles exigent un navigateur intégré (SAML) :" " openconnect s'arrête sur « No SSO handler » et un greffon est" " nécessaire pour l'étape web. Il est facultatif, et son amont" " n'est plus entretenu." ), "en": ( "Some gateways demand an embedded browser (SAML): openconnect" " stops on « No SSO handler » and a helper is needed for the web" " step. It is optional, and its upstream is no longer" " maintained." ), }, "Found": { "fr": "Trouvé", "en": "Found", }, "Browse it? (Y/n)": { "fr": "Le parcourir ? (O/n)", "en": "Browse it? (Y/n)", }, "Install it as well? (y/N)": { "fr": "L'installer aussi ? (o/N)", "en": "Install it as well? (y/N)", }, "This profile is already connected.": { "fr": "Ce profil est déjà connecté.", "en": "This profile is already connected.", }, "Connect it again? (y/N)": { "fr": "Le reconnecter quand même ? (o/N)", "en": "Connect it again? (y/N)", }, "This profile is not connected. Disconnecting still clears the state" " a dead tunnel left behind.": { "fr": ( "Ce profil n'est pas connecté. Le déconnecter efface tout de" " même l'état qu'un tunnel mort a laissé." ), "en": ( "This profile is not connected. Disconnecting still clears the" " state a dead tunnel left behind." ), }, "The gateway decides what enters this tunnel. To force a network" " through it anyway, add it to the routes above \u2014 0.0.0.0/0 for all.": { "fr": ( "La passerelle décide de ce qui entre dans ce tunnel. Pour y" " forcer un réseau tout de même, l'ajouter aux routes" " ci-dessus — 0.0.0.0/0 pour tout." ), "en": ( "The gateway decides what enters this tunnel. To force a" " network through it anyway, add it to the routes above —" " 0.0.0.0/0 for all." ), }, "SSO helper": { "fr": "greffon SSO", "en": "SSO helper", }, "Connection group in the URL \u2014 of an AnyConnect" " profile (optional)": { "fr": ( "Groupe de connexion dans l'URL \u2014 d'un profil" " AnyConnect (facultatif)" ), "en": ( "Connection group in the URL \u2014 of an" " AnyConnect profile (optional)" ), }, "No site preset available.": { "fr": "Aucun préréglage de site disponible.", "en": "No site preset available.", }, "Drop a .json file in conf/vpn_presets/ (shared, nothing identifying)" " or in private/vpn/presets/ (git-ignored, where a site preset goes).": { "fr": ( "Poser un fichier .json dans conf/vpn_presets/ (partagé, rien" " d'identifiant) ou dans private/vpn/presets/ (ignoré par git," " c'est là qu'un préréglage de site va)." ), "en": ( "Drop a .json file in conf/vpn_presets/ (shared, nothing" " identifying) or in private/vpn/presets/ (git-ignored, where a" " site preset goes)." ), }, "Unreadable preset: ": { "fr": "Préréglage illisible : ", "en": "Unreadable preset: ", }, "Preset number (0 to go back)": { "fr": "Numéro du préréglage (0 pour revenir)", "en": "Preset number (0 to go back)", }, "An empty answer keeps the preset value.": { "fr": "Une réponse vide garde la valeur du préréglage.", "en": "An empty answer keeps the preset value.", }, "This profile already exists: the preset refreshes what it declares," " everything personal is kept.": { "fr": ( "Ce profil existe déjà : le préréglage rafraîchit ce qu'il" " déclare, tout ce qui est personnel est gardé." ), "en": ( "This profile already exists: the preset refreshes what it" " declares, everything personal is kept." ), }, "Cisco AnyConnect gateway with an authentication group": { "fr": "Passerelle Cisco AnyConnect avec groupe d'authentification", "en": "Cisco AnyConnect gateway with an authentication group", }, "Password characters the server compares (0: no limit)": { "fr": ( "Caractères du mot de passe que le serveur compare (0 : aucune" " limite)" ), "en": "Password characters the server compares (0: no limit)", }, "This gateway compares only the first {limit} characters of" " the password: store just those, a longer one is refused.": { "fr": ( "Cette passerelle ne compare que les {limit} premiers caractères" " du mot de passe : n'en déposer que ceux-là, un plus long est" " refusé." ), "en": ( "This gateway compares only the first {limit} characters of the" " password: store just those, a longer one is refused." ), }, "No VPN profile yet: create one first.": { "fr": "Aucun profil VPN : en créer un d'abord.", "en": "No VPN profile yet: create one first.", }, "all traffic": { "fr": "tout le trafic", "en": "all traffic", }, "Driver": { "fr": "Pilote", "en": "Driver", }, "PPP user (the one the server authenticates)": { "fr": "Utilisateur PPP (celui que le serveur authentifie)", "en": "PPP user (the one the server authenticates)", }, "MTU": { "fr": "MTU", "en": "MTU", }, "Local L2TP port": { "fr": "Port L2TP local", "en": "Local L2TP port", }, "Use the DNS pushed by the peer?": { "fr": "Utiliser les DNS poussés par le pair ?", "en": "Use the DNS pushed by the peer?", }, "DNS search domain (optional)": { "fr": "Domaine de recherche DNS (facultatif)", "en": "DNS search domain (optional)", }, "Server address (hostname or IP)": { "fr": "Adresse du serveur (nom d'hôte ou IP)", "en": "Server address (hostname or IP)", }, "Networks to reach, comma-separated": { "fr": "Réseaux à joindre, séparés par des virgules", "en": "Networks to reach, comma-separated", }, "Send ALL traffic through the tunnel?": { "fr": "Envoyer TOUT le trafic dans le tunnel ?", "en": "Send ALL traffic through the tunnel?", }, "Witness address reachable only through the tunnel (optional)": { "fr": "Adresse témoin joignable seulement par le tunnel (facultatif)", "en": "Witness address reachable only through the tunnel (optional)", }, "Advanced settings (MTU, L2TP port, DNS)? (y/N)": { "fr": "Réglages avancés (MTU, port L2TP, DNS) ? (o/N)", "en": "Advanced settings (MTU, L2TP port, DNS)? (y/N)", }, "Profile name (lowercase, digits, - or _)": { "fr": "Nom du profil (minuscules, chiffres, « - » ou « _ »)", "en": "Profile name (lowercase, digits, - or _)", }, "Profile number (0 to go back)": { "fr": "Numéro du profil (0 pour revenir)", "en": "Profile number (0 to go back)", }, "Profile saved: ": { "fr": "Profil enregistré : ", "en": "Profile saved: ", }, "Profile refused: ": { "fr": "Profil refusé : ", "en": "Profile refused: ", }, "Profile deleted.": { "fr": "Profil supprimé.", "en": "Profile deleted.", }, "Delete profile": { "fr": "Supprimer le profil", "en": "Delete profile", }, "Next step: store its secrets in the vault.": { "fr": "Étape suivante : déposer ses secrets dans le coffre.", "en": "Next step: store its secrets in the vault.", }, "Its vault entry is kept: delete it in KeePassXC.": { "fr": "Son entrée du coffre est conservée : la supprimer dans KeePassXC.", "en": "Its vault entry is kept: delete it in KeePassXC.", }, "Not deletable here: this profile comes from a shared configuration file.": { "fr": "Pas supprimable d'ici : ce profil vient d'un fichier de configuration partagé.", "en": "Not deletable here: this profile comes from a shared configuration file.", }, "Unknown driver: ": { "fr": "Pilote inconnu : ", "en": "Unknown driver: ", }, "Unknown choice.": { "fr": "Choix inconnu.", "en": "Unknown choice.", }, "The installation requires sudo.": { "fr": "L'installation demande sudo.", "en": "The installation requires sudo.", }, "Run this plan? (y/N): ": { "fr": "Exécuter ce plan ? (o/N) : ", "en": "Run this plan? (y/N): ", }, "No vault: nothing stored.": { "fr": "Pas de coffre : rien n'a été déposé.", "en": "No vault: nothing stored.", }, "Vault entry": { "fr": "Entrée du coffre", "en": "Vault entry", }, "An empty answer keeps the stored value.": { "fr": "Une réponse vide garde la valeur déjà en place.", "en": "An empty answer keeps the stored value.", }, "Secrets stored in the vault.": { "fr": "Secrets déposés dans le coffre.", "en": "Secrets stored in the vault.", }, "Confirm": { "fr": "Confirmer", "en": "Confirm", }, "The two entries differ, nothing stored.": { "fr": "Les deux saisies diffèrent, rien n'a été déposé.", "en": "The two entries differ, nothing stored.", }, "The vault MASTER password is stored in the configuration in clear text. Remove it and type it on demand.": { "fr": "Le mot de passe MAÎTRE du coffre est écrit en clair dans la configuration. Le retirer et le saisir à la demande.", "en": "The vault MASTER password is stored in the configuration in clear text. Remove it and type it on demand.", }, # VPN — pilotes de la phase 2 et 3 (WireGuard, OpenVPN, OpenConnect, sshuttle) "never mounted against a real server: only unit tests cover it": { "fr": ( "jamais monté contre un vrai serveur : seuls les tests" " unitaires le couvrent" ), "en": "never mounted against a real server: only unit tests cover it", }, "When the far side imposes it: a router, a firewall, Windows RRAS": { "fr": "Quand le site l'impose : un routeur, un pare-feu, Windows RRAS", "en": "When the far side imposes it: a router, a firewall, Windows RRAS", }, "When you control both ends: the fastest and the simplest": { "fr": "Quand on tient les deux bouts : le plus rapide et le plus simple", "en": "When you control both ends: the fastest and the simplest", }, "When the site handed you a .ovpn file": { "fr": "Quand le site a fourni un fichier .ovpn", "en": "When the site handed you a .ovpn file", }, "Cisco AnyConnect, Pulse, GlobalProtect, Fortinet appliances": { "fr": "Boîtiers Cisco AnyConnect, Pulse, GlobalProtect, Fortinet", "en": "Cisco AnyConnect, Pulse, GlobalProtect, Fortinet appliances", }, "When all you have is SSH access: nothing to install on the far side": { "fr": "Quand on n'a qu'un accès SSH : rien à installer en face", "en": "When all you have is SSH access: nothing to install on the far side", }, "IPsec pre-shared key (PSK)": { "fr": "Clé pré-partagée IPsec (PSK)", "en": "IPsec pre-shared key (PSK)", }, "PPP password": { "fr": "Mot de passe PPP", "en": "PPP password", }, "WireGuard private key of this machine": { "fr": "Clé privée WireGuard de cette machine", "en": "WireGuard private key of this machine", }, "WireGuard pre-shared key (optional)": { "fr": "Clé pré-partagée WireGuard (facultative)", "en": "WireGuard pre-shared key (optional)", }, "OpenVPN password": { "fr": "Mot de passe OpenVPN", "en": "OpenVPN password", }, "VPN password": { "fr": "Mot de passe du VPN", "en": "VPN password", }, "Address of this machine inside the tunnel (10.7.0.2/32)": { "fr": "Adresse de cette machine dans le tunnel (10.7.0.2/32)", "en": "Address of this machine inside the tunnel (10.7.0.2/32)", }, "Public key of the peer": { "fr": "Clé publique du pair", "en": "Public key of the peer", }, "WireGuard endpoint port": { "fr": "Port de l'endpoint WireGuard", "en": "WireGuard endpoint port", }, "DNS server inside the tunnel (optional)": { "fr": "Serveur DNS dans le tunnel (facultatif)", "en": "DNS server inside the tunnel (optional)", }, "PersistentKeepalive, in seconds": { "fr": "PersistentKeepalive, en secondes", "en": "PersistentKeepalive, in seconds", }, "Path to the .ovpn file provided by the site": { "fr": "Chemin du fichier .ovpn fourni par le site", "en": "Path to the .ovpn file provided by the site", }, "OpenVPN user (empty if the file authenticates by certificate)": { "fr": "Utilisateur OpenVPN (vide si le fichier authentifie par certificat)", "en": "OpenVPN user (empty if the file authenticates by certificate)", }, "VPN user": { "fr": "Utilisateur du VPN", "en": "VPN user", }, "Protocol (anyconnect, nc, pulse, gp, f5, fortinet, array)": { "fr": "Protocole (anyconnect, nc, pulse, gp, f5, fortinet, array)", "en": "Protocol (anyconnect, nc, pulse, gp, f5, fortinet, array)", }, "Authentication group / realm (optional)": { "fr": "Groupe d'authentification / royaume (facultatif)", "en": "Authentication group / realm (optional)", }, "Pinned server certificate (sha256:... , printed on first refusal)": { "fr": "Certificat serveur épinglé (sha256:… , imprimé au premier refus)", "en": "Pinned server certificate (sha256:... , printed on first refusal)", }, "HTTPS port": { "fr": "Port HTTPS", "en": "HTTPS port", }, "SSH port": { "fr": "Port SSH", "en": "SSH port", }, "SSH target (user@host, or a ~/.ssh/config alias)": { "fr": "Cible SSH (utilisateur@hôte, ou un alias de ~/.ssh/config)", "en": "SSH target (user@host, or a ~/.ssh/config alias)", }, "Also send DNS queries through the tunnel?": { "fr": "Envoyer aussi les requêtes DNS dans le tunnel ?", "en": "Also send DNS queries through the tunnel?", }, "Advanced settings? (y/N)": { "fr": "Réglages avancés ? (o/N)", "en": "Advanced settings? (y/N)", }, "No secret to store: this one authenticates over SSH.": { "fr": "Aucun secret à déposer : celui-là s'authentifie par SSH.", "en": "No secret to store: this one authenticates over SSH.", }, "Several technologies match: ": { "fr": "Plusieurs technologies correspondent : ", "en": "Several technologies match: ", }, "Authentication through a web form (SAML / SSO)?": { "fr": "Authentification par formulaire web (SAML / SSO) ?", "en": "Authentication through a web form (SAML / SSO)?", }, "Browser command for SSO (empty: show the URL to open yourself)": { "fr": "Programme navigateur pour le SSO (vide : afficher l'URL à ouvrir soi-même)", "en": "Browser command for SSO (empty: show the URL to open yourself)", }, "Vault permissions tightened to 0600, it was readable by others: ": { "fr": "Permissions du coffre resserrées à 0600, il était lisible par d'autres : ", "en": "Vault permissions tightened to 0600, it was readable by others: ", }, "already set": { "fr": "déjà en place", "en": "already set", }, "empty": { "fr": "vide", "en": "empty", }, "Still missing, the tunnel will not come up: ": { "fr": "Toujours manquant, le tunnel ne montera pas : ", "en": "Still missing, the tunnel will not come up: ", }, "No network routed yet: this tunnel will only reach the remote host. Connect once — the address you get tells you which network to add.": { "fr": "Aucun réseau routé pour l'instant : ce tunnel ne joindra que l'hôte distant. Monter une fois — l'adresse obtenue dira quel réseau ajouter.", "en": "No network routed yet: this tunnel will only reach the remote host. Connect once — the address you get tells you which network to add.", }, # Assistant LLM (script/todo/assistant_menu.py, script/todo/assistant/) "AI question - Ask a model, local or remote": { "fr": "🤖 Question IA - Interroger un modèle, local ou distant", "en": "🤖 AI question - Ask a model, local or remote", }, "A server, a gpt tool, a conversation.": { "fr": "Un serveur, un outil gpt, une conversation.", "en": "A server, a gpt tool, a conversation.", }, "Talk": { "fr": "Parler", "en": "Talk", }, "Free question": { "fr": "💬 Question libre", "en": "💬 Free question", }, "Known servers": { "fr": "🗄 Serveurs connus", "en": "🗄 Known servers", }, "Search for a server…": { "fr": "🔍 Chercher un serveur…", "en": "🔍 Search for a server…", }, "Server card": { "fr": "📇 Fiche du serveur", "en": "📇 Server card", }, "what it says it can do": { "fr": "ce qu'il annonce savoir faire", "en": "what it says it can do", }, "no local server — via api.openai.com": { "fr": "aucun serveur local — via api.openai.com", "en": "no local server — via api.openai.com", }, "no server yet": { "fr": "aucun serveur pour l'instant", "en": "no server yet", }, "reachable": { "fr": "joignable", "en": "reachable", }, "The history lives in memory and dies with this menu. /save writes it to a file.": { "fr": "L'historique vit en mémoire et meurt avec ce menu. /save l'écrit dans un fichier.", "en": "The history lives in memory and dies with this menu. /save writes it to a file.", }, "Commands start with a slash. /? lists them.": { "fr": "Les commandes commencent par une barre oblique. /? les liste.", "en": "Commands start with a slash. /? lists them.", }, "interrupted": { "fr": "interrompue", "en": "interrupted", }, "answer interrupted": { "fr": "réponse interrompue", "en": "answer interrupted", }, "/save to write it to a file": { "fr": "/save pour l'écrire dans un fichier", "en": "/save to write it to a file", }, "back to the menu": { "fr": "retour au menu", "en": "back to the menu", }, "clear the history (same server, same tool)": { "fr": "vider l'historique (même serveur, même outil)", "en": "clear the history (same server, same tool)", }, "change tool, history kept": { "fr": "changer d'outil, historique conservé", "en": "change tool, history kept", }, "change server, history CLEARED — the model is no longer the same": { "fr": "changer de serveur, historique VIDÉ — le modèle n'est plus le même", "en": "change server, history CLEARED — the model is no longer the same", }, "show again what was sent": { "fr": "réafficher ce qui a été envoyé", "en": "show again what was sent", }, 'multi-line entry, end with a single "." line': { "fr": "saisie multiligne, terminer par une ligne « . » seule", "en": 'multi-line entry, end with a single "." line', }, "write the conversation to a file": { "fr": "écrire la conversation dans un fichier", "en": "write the conversation to a file", }, "list the commands": { "fr": "lister les commandes", "en": "list the commands", }, "turns dropped": { "fr": "tours jetés", "en": "turns dropped", }, "Conversation written to": { "fr": "Conversation écrite dans", "en": "Conversation written to", }, "via api.openai.com (key from the vault)": { "fr": "via api.openai.com (clé du coffre)", "en": "via api.openai.com (key from the vault)", }, "This destination is a third party. Retype it to confirm:": { "fr": "Cette destination est un tiers. Retape-la pour confirmer :", "en": "This destination is a third party. Retype it to confirm:", }, "Destination not retyped — nothing was sent.": { "fr": "Destination non retapée — rien n'a été envoyé.", "en": "Destination not retyped — nothing was sent.", }, "third party": { "fr": "tiers", "en": "third party", }, "this machine": { "fr": "cette machine", "en": "this machine", }, "local network of this machine": { "fr": "🌐 Réseau local de cette machine", "en": "🌐 Local network of this machine", }, "local network": { "fr": "réseau local", "en": "local network", }, "No server answered on this machine.": { "fr": "Aucun serveur n'a répondu sur cette machine.", "en": "No server answered on this machine.", }, "The vault holds no OpenAI key: configure a server or a key.": { "fr": "Le coffre ne porte aucune clé OpenAI : configurer un serveur ou une clé.", "en": "The vault holds no OpenAI key: configure a server or a key.", }, "Here (127.0.0.1)": { "fr": "🏠 Ici (127.0.0.1)", "en": "🏠 Here (127.0.0.1)", }, "An address I type": { "fr": "🎯 Une adresse que je tape", "en": "🎯 An address I type", }, "Where should I look for a server?": { "fr": "Où chercher un serveur ?", "en": "Where should I look for a server?", }, "Add a server by hand": { "fr": "➕ Ajouter un serveur à la main", "en": "➕ Add a server by hand", }, "Host or IP": { "fr": "Hôte ou IP", "en": "Host or IP", }, "Port": { "fr": "Port", "en": "Port", }, "Name for this server": { "fr": "Nom pour ce serveur", "en": "Name for this server", }, "Answered, not identified": { "fr": "A répondu, non identifié", "en": "Answered, not identified", }, "Asks for a key — configure it against a server you named": { "fr": "Demande une clé — la configurer contre un serveur que tu as nommé", "en": "Asks for a key — configure it against a server you named", }, "Starting up — alive, answer not ready": { "fr": "En démarrage — vivant, réponse pas prête", "en": "Starting up — alive, answer not ready", }, "Type the server name in full to delete it:": { "fr": "Tape le nom du serveur en entier pour le supprimer :", "en": "Type the server name in full to delete it:", }, "Delete a server": { "fr": "🗑 Supprimer un serveur", "en": "🗑 Delete a server", }, "Choose the server to use": { "fr": "Choisir le serveur à utiliser", "en": "Choose the server to use", }, "in use": { "fr": "en usage", "en": "in use", }, "11 ports, instant": { "fr": "11 ports, instantané", "en": "11 ports, instant", }, "The QEMU VMs of this machine (virsh)": { "fr": "🖥 Les VM QEMU de cette machine (virsh)", "en": "🖥 The QEMU VMs of this machine (virsh)", }, "The hosts of ~/.ssh/config": { "fr": "🔑 Les hôtes de ~/.ssh/config", "en": "🔑 The hosts of ~/.ssh/config", }, "libvirt bridge": { "fr": "pont libvirt", "en": "libvirt bridge", }, "Sweep %s addresses × %s ports on %s?": { "fr": "Balayer %s adresses × %s ports sur %s ?", "en": "Sweep %s addresses × %s ports on %s?", }, "The /24 is an assumption: a prefix does not follow from an address.": { "fr": ( "Le /24 est une hypothèse : un préfixe ne se déduit pas" " d'une adresse." ), "en": ( "The /24 is an assumption: a prefix does not follow from an" " address." ), }, "Wider than a /24 is refused.": { "fr": "Plus large qu'un /24 est refusé.", "en": "Wider than a /24 is refused.", }, "Ctrl+C interrupts": { "fr": "Ctrl+C interrompt", "en": "Ctrl+C interrupts", }, "hosts": { "fr": "hôtes", "en": "hosts", }, "ports": { "fr": "ports", "en": "ports", }, "server recognized": { "fr": "serveur reconnu", "en": "server recognized", }, "servers recognized": { "fr": "serveurs reconnus", "en": "servers recognized", }, "hosts swept": { "fr": "hôtes balayés", "en": "hosts swept", }, "No server on %s (%s, %s, %ss).": { "fr": "Aucun serveur sur %s (%s, %s, %ss).", "en": "No server on %s (%s, %s, %ss).", }, # « host » et « port » sont déjà déclarées plus haut dans ce fichier, avec # ce français : les redéclarer ici les écraserait en silence. L'accord des # nombres les lit telles quelles. "model": { "fr": "modèle", "en": "model", }, "host swept": { "fr": "hôte balayé", "en": "host swept", }, "Look somewhere else": { "fr": "Chercher ailleurs", "en": "Look somewhere else", }, "Carry on with the OpenAI API (key from the vault)": { "fr": "Continuer avec l'API OpenAI (clé du coffre)", "en": "Carry on with the OpenAI API (key from the vault)", }, 'A local server: "ollama serve" listens on 11434.': { "fr": "Un serveur local : « ollama serve » écoute sur 11434.", "en": 'A local server: "ollama serve" listens on 11434.', }, "libvirt answers, no VM defined": { "fr": "libvirt répond, aucune VM définie", "en": "libvirt answers, no VM defined", }, "~/.ssh/config absent — nothing to probe": { "fr": "~/.ssh/config absent — rien à sonder", "en": "~/.ssh/config absent — nothing to probe", }, "Host without an address — listed as unknown": { "fr": "Hôte sans adresse — listé comme inconnu", "en": "Host without an address — listed as unknown", }, "Keep this server?": { "fr": "Garder ce serveur ?", "en": "Keep this server?", }, "Keep them all": { "fr": "Les garder tous", "en": "Keep them all", }, "Sweeping the network reaches machines you did not name.": { "fr": ( "Balayer le réseau atteint des machines que tu n'as pas nommées." ), "en": "Sweeping the network reaches machines you did not name.", }, "gpt tools": { "fr": "🧰 Outils gpt", "en": "🧰 gpt tools", }, "no gpt tool yet": { "fr": "aucun outil gpt pour l'instant", "en": "no gpt tool yet", }, "compatible": { "fr": "compatibles", "en": "compatible", }, "Which gpt tool?": { "fr": "Quel outil gpt ?", "en": "Which gpt tool?", }, "a requirement is contradicted": { "fr": "une exigence est contredite", "en": "a requirement is contradicted", }, "unreadable gpt files": { "fr": "fichiers gpt illisibles", "en": "unreadable gpt files", }, "details": { "fr": "détails", "en": "details", }, "What is about to be sent": { "fr": "Ce qui va être envoyé", "en": "What is about to be sent", }, "characters": { "fr": "caractères", "en": "characters", }, "What the filter checks": { "fr": "Ce que le filtre contrôle : adresses, courriels, chemins de compte. Pas les noms.", "en": "What the filter checks", }, "cancel": { "fr": "annuler", "en": "cancel", }, "Nothing has been sent.": { "fr": "Rien n'a été envoyé.", "en": "Nothing has been sent.", }, # Les noms et descriptions des gpts livrés (script/todo/assistant/gpt/). # L'anglais EST la clé, comme partout : un gpt non traduit # s'affiche en anglais au lieu de rien. L'emoji vit dans la # valeur, jamais dans la clé. "Unit test failure - the cause, and what to read next": { "fr": "🧪 Échec de test unitaire - la cause, et quoi lire ensuite", "en": "Unit test failure - the cause, and what to read next", }, "Read one failing test and name the cause, without proposing a patch": { "fr": "lire un test en échec et nommer la cause, sans proposer de correctif", "en": "Read one failing test and name the cause, without proposing a patch", }, "Manifest gaps - which tier loses which modules": { "fr": "🕳️ Trous de manifeste - quel palier perd quels modules", "en": "Manifest gaps - which tier loses which modules", }, "Read the reported holes and name the tier and the modules each loses": { "fr": "lire les trous rapportés et nommer le palier et les modules perdus", "en": "Read the reported holes and name the tier and the modules each loses", }, "Cloned module - find what it inherited": { "fr": "🧬 Module cloné - repérer ce dont il a hérité", "en": "Cloned module - find what it inherited", }, "Name what a cloned module inherited rather than what was written": { "fr": "nommer ce qu'un module cloné a hérité plutôt que ce qui a été écrit", "en": "Name what a cloned module inherited rather than what was written", }, "Comment hygiene - rewrite narrative as mechanism": { "fr": "🧹 Hygiène des commentaires - réécrire le récit en fonctionnement", "en": "Comment hygiene - rewrite narrative as mechanism", }, "Rewrite each flagged sentence so the code is the subject, present tense": { "fr": "réécrire chaque phrase signalée avec le code pour sujet, au présent", "en": "Rewrite each flagged sentence so the code is the subject, present tense", }, "Commit message - subject, bilingual body, Assisted-by": { "fr": "✍️ Message de commit - sujet, corps bilingue, Assisted-by", "en": "Commit message - subject, bilingual body, Assisted-by", }, "Turn the staged diff into a tagged subject and a bilingual body": { "fr": "faire du diff indexé un sujet tagué et un corps bilingue", "en": "Turn the staged diff into a tagged subject and a bilingual body", }, "Bilingual doc - write or repair a .base.md": { "fr": "🌍 Doc bilingue - écrire ou réparer un .base.md", "en": "Bilingual doc - write or repair a .base.md", }, "Produce or fix a .base.md, its header and its language blocks": { "fr": "produire ou réparer un .base.md, son en-tête et ses blocs de langue", "en": "Produce or fix a .base.md, its header and its language blocks", }, # Sessions Claude Code locales (script/todo/assistant/claude_sessions.py). "Claude Code - local sessions": { "fr": "🤖 Claude Code - sessions locales", "en": "🤖 Claude Code - local sessions", }, "List local sessions": { "fr": "📋 Lister les sessions locales", "en": "📋 List local sessions", }, "Ask a question to a session": { "fr": "❓ Poser une question à une session", "en": "❓ Ask a question to a session", }, "Resume a session in a new terminal": { "fr": "▶ Reprendre une session dans un nouveau terminal", "en": "▶ Resume a session in a new terminal", }, "live": { "fr": "vivantes", "en": "live", }, "held by pid %s": { "fr": "tenue par le pid %s", "en": "held by pid %s", }, "resumable, not running": { "fr": "reprenable, pas en cours", "en": "resumable, not running", }, "This session is open elsewhere. A branch would be lost.": { "fr": "Cette session est ouverte ailleurs. Une branche serait perdue.", "en": "This session is open elsewhere. A branch would be lost.", }, "Branch a copy (recommended)": { "fr": "Brancher une copie (recommandé)", "en": "Branch a copy (recommended)", }, "Write into the held session": { "fr": "Écrire dans la session tenue", "en": "Write into the held session", }, "Type the pid of the holder to write into it:": { "fr": "Tape le pid du détenteur pour y écrire :", "en": "Type the pid of the holder to write into it:", }, "No session on this machine.": { "fr": "Aucune session sur cette machine.", "en": "No session on this machine.", }, "claude is not on the PATH.": { "fr": "claude n'est pas dans le PATH.", "en": "claude is not on the PATH.", }, "No terminal can be opened here. Paste this command:": { "fr": "Aucun terminal ne peut être ouvert ici. Colle cette commande :", "en": "No terminal can be opened here. Paste this command:", }, "read-only: Read, Glob, Grep": { "fr": "lecture seule : Read, Glob, Grep", "en": "read-only: Read, Glob, Grep", }, # Catalogue gpt et porte du contexte (script/todo/assistant/gpt.py, # script/todo/assistant/context.py, capabilities.py) "No front-matter: a gpt opens with ---": { "fr": "Pas d'en-tête : un gpt s'ouvre par ---", "en": "No front-matter: a gpt opens with ---", }, "Front-matter is not closed": { "fr": "En-tête non fermé", "en": "Front-matter is not closed", }, "Front-matter is not a mapping": { "fr": "L'en-tête n'est pas un dictionnaire", "en": "Front-matter is not a mapping", }, "Front-matter is unreadable": { "fr": "En-tête illisible", "en": "Front-matter is unreadable", }, "Repeated key in front-matter:": { "fr": "Clé répétée dans l'en-tête :", "en": "Repeated key in front-matter:", }, "No schema version: gpt is required": { "fr": "Version de schéma absente : gpt est obligatoire", "en": "No schema version: gpt is required", }, "Schema too recent for this version of TODO": { "fr": "Schéma trop récent pour cette version de TODO", "en": "Schema too recent for this version of TODO", }, "No name": { "fr": "Nom absent", "en": "No name", }, "No description": { "fr": "Description absente", "en": "No description", }, "Missing marker ": { "fr": "Marqueur absent", "en": "Missing marker ", }, "Unknown key in front-matter:": { "fr": "Clé inconnue dans l'en-tête :", "en": "Unknown key in front-matter:", }, "name_fr belongs in the translations file": { "fr": "name_fr appartient au fichier des traductions", "en": "name_fr belongs in the translations file", }, "A gpt from outside the repository may not declare any command.": { "fr": "Un gpt hors du dépôt ne peut déclarer aucune commande.", "en": "A gpt from outside the repository may not declare any command.", }, "Overrides the one from": { "fr": "Écrase celui de", "en": "Overrides the one from", }, "Unreadable file:": { "fr": "Fichier illisible :", "en": "Unreadable file:", }, "A gpt may not be named *.base.md": { "fr": "Un gpt ne peut pas s'appeler *.base.md", "en": "A gpt may not be named *.base.md", }, "PyYAML is missing: the gpt catalogue stays closed, the free question works.": { "fr": "PyYAML manque : le catalogue gpt reste fermé, la question libre fonctionne.", "en": "PyYAML is missing: the gpt catalogue stays closed, the free question works.", }, "private/noms_interdits.txt is absent: no client, database, VM or host name can be recognized.": { "fr": "private/noms_interdits.txt est absent : aucun nom de client, de base, de VM ou d'hôte ne peut être reconnu.", "en": "private/noms_interdits.txt is absent: no client, database, VM or host name can be recognized.", }, "A finding blocks a send to a third party. No override.": { "fr": "Une trouvaille bloque un envoi vers un tiers. Aucun passe-droit.", "en": "A finding blocks a send to a third party. No override.", }, "finding to re-read before sending": { "fr": "trouvaille à relire avant d'envoyer", "en": "finding to re-read before sending", }, "findings to re-read before sending": { "fr": "trouvailles à relire avant d'envoyer", "en": "findings to re-read before sending", }, "… [cut]": { "fr": "… [coupé]", "en": "… [cut]", }, "a requirement could not be checked": { "fr": "une exigence n'a pas pu être vérifiée", "en": "a requirement could not be checked", }, "asks for %s of context, this server announces %s": { "fr": "demande %s de contexte, ce serveur en annonce %s", "en": "asks for %s of context, this server announces %s", }, "asks for %s B of parameters, this server announces %s B": { "fr": "demande %s B de paramètres, ce serveur en annonce %s B", "en": "asks for %s B of parameters, this server announces %s B", }, "asks for a local server, this one is %s": { "fr": "demande un serveur local, celui-ci est %s", "en": "asks for a local server, this one is %s", }, "asks for tool calling, this server does not announce it": { "fr": "demande l'appel d'outils, ce serveur ne l'annonce pas", "en": "asks for tool calling, this server does not announce it", }, "asks for vision, this server does not announce it": { "fr": "demande la vision, ce serveur ne l'annonce pas", "en": "asks for vision, this server does not announce it", }, "asks for JSON output, this server does not announce it": { "fr": "demande une sortie JSON, ce serveur ne l'annonce pas", "en": "asks for JSON output, this server does not announce it", }, "hosting could not be checked": { "fr": "l'hébergement n'a pas pu être vérifié", "en": "hosting could not be checked", }, "context_window could not be checked on this server": { "fr": "context_window n'a pas pu être vérifié sur ce serveur", "en": "context_window could not be checked on this server", }, "parameters could not be checked on this server": { "fr": "parameters n'a pas pu être vérifié sur ce serveur", "en": "parameters could not be checked on this server", }, "tool_calling could not be checked on this server": { "fr": "tool_calling n'a pas pu être vérifié sur ce serveur", "en": "tool_calling could not be checked on this server", }, "vision could not be checked on this server": { "fr": "vision n'a pas pu être vérifié sur ce serveur", "en": "vision could not be checked on this server", }, "json_output could not be checked on this server": { "fr": "json_output n'a pas pu être vérifié sur ce serveur", "en": "json_output could not be checked on this server", }, "A network I type (CIDR)": { "fr": "📡 Un réseau que je tape (CIDR)", "en": "📡 A network I type (CIDR)", }, "Network in CIDR form": { "fr": "Réseau en notation CIDR", "en": "Network in CIDR form", }, "Only part of that network was swept.": { "fr": "Une partie seulement de ce réseau a été balayée.", "en": "Only part of that network was swept.", }, "The networks of a machine over SSH": { "fr": "🛰 Les réseaux d'une machine en SSH", "en": "🛰 The networks of a machine over SSH", }, "Host reachable over SSH": { "fr": "Hôte joignable en SSH", "en": "Host reachable over SSH", }, "Reading the networks it carries…": { "fr": "Lecture des réseaux qu'elle porte…", "en": "Reading the networks it carries…", }, "That host did not answer, or carries no network.": { "fr": "Cet hôte n'a pas répondu, ou ne porte aucun réseau.", "en": "That host did not answer, or carries no network.", }, "read on %s, swept from here": { "fr": "lu sur %s, balayé d'ici", "en": "read on %s, swept from here", }, "Only the hosts that have already spoken (ip neigh)": { "fr": "Seulement les hôtes qui ont déjà parlé (ip neigh)", "en": "Only the hosts that have already spoken (ip neigh)", }, "nothing kept": { "fr": "rien de gardé", "en": "nothing kept", }, "kept": { "fr": "gardé", "en": "kept", }, # « models », « still waiting for » et « Type an address » servent aussi # ici et sont définies plus haut : les redéfinir écraserait la première # sans rien lever. # Transform data - fichiers externes "Transform data - Transform your data": { "fr": "🪄 Transform data - Transformer vos données", "en": "🪄 Transform data - Transform your data", }, "Source file": { "fr": "📁 Fichier source", "en": "📁 Source file", }, "Transform your data: read, describe, then copy.": { "fr": "Transformer vos données : lire, décrire, puis en tirer une copie.", "en": "Transform your data: read, describe, then copy.", }, "Source": { "fr": "📁 Source", "en": "📁 Source", }, "Anonymise an Odoo database or a backup": { "fr": "🎭 Anonymiser une base Odoo ou une sauvegarde", "en": "🎭 Anonymise an Odoo database or a backup", }, "The database ITSELF is modified; no copy.": { "fr": "La base ELLE-MÊME est modifiée ; aucune copie.", "en": "The database ITSELF is modified; no copy.", }, "Nothing was written; no backup was drawn.": { "fr": "Rien n'a été écrit ; aucune sauvegarde n'a été tirée.", "en": "Nothing was written; no backup was drawn.", }, "Backup name (Enter to accept): ": { "fr": "Nom de la sauvegarde (Entrée pour accepter) : ", "en": "Backup name (Enter to accept): ", }, "Backup written: ": { "fr": "Sauvegarde écrite : ", "en": "Backup written: ", }, "Database kept: ": { "fr": "Base conservée : ", "en": "Database kept: ", }, "Gone already, only in the register:": { "fr": "Déjà disparue(s), seulement au registre :", "en": "Gone already, only in the register:", }, "Use Database to drop one.": { "fr": "Passer par Database pour en détruire une.", "en": "Use Database to drop one.", }, "Advanced options? (y/N): ": { "fr": "Options avancées ? (o/N) : ", "en": "Advanced options? (y/N): ", }, "every sheet": { "fr": "toutes les feuilles", "en": "every sheet", }, "no column left untouched": { "fr": "aucune colonne laissée intacte", "en": "no column left untouched", }, "column(s) left untouched, chosen on screen": { "fr": "colonne(s) laissée(s) intacte(s), choisies à l'écran", "en": "column(s) left untouched, chosen on screen", }, "numbers replaced, widths kept": { "fr": "nombres remplacés, largeurs gardées", "en": "numbers replaced, widths kept", }, "numbers replaced within the measured extent": { "fr": "nombres remplacés dans l'étendue mesurée", "en": "numbers replaced within the measured extent", }, "text replaced": { "fr": "texte remplacé", "en": "text replaced", }, "the header row is left readable": { "fr": "la ligne d'en-tête reste lisible", "en": "the header row is left readable", }, "sheet(s) with no header row on screen": { "fr": "feuille(s) sans en-tête à l'écran : leur 1re ligne est de la donnée", "en": "sheet(s) with no header row on screen: their 1st row is data", }, "no seed: not reproducible": { "fr": "aucune graine : non reproductible", "en": "no seed: not reproducible", }, "Taken as given:": { "fr": "Pris tel quel :", "en": "Taken as given:", }, "Anonymise the logins too? (y/N): ": { "fr": "Anonymiser aussi les identifiants de connexion ? (o/N) : ", "en": "Anonymise the logins too? (y/N): ", }, "Keeping the digit count drops the measured extent.": { "fr": "Garder le nombre de chiffres abandonne l'étendue mesurée.", "en": "Keeping the digit count drops the measured extent.", }, "Not neutralized: this copy can send mail and run": { "fr": "Non neutralisée : cette copie peut envoyer du courriel et faire tourner", "en": "Not neutralized: this copy can send mail and run", }, "its crons from this machine.": { "fr": "ses crons depuis cette machine.", "en": "its crons from this machine.", }, "Databases produced": { "fr": "🗄 Bases produites", "en": "🗄 Databases produced", }, "External files: read, describe, then draw a copy.": { "fr": "Fichiers externes : lire, décrire, puis en tirer une copie.", "en": "External files: read, describe, then draw a copy.", }, "Environment": { "fr": "🧰 Environnement", "en": "🧰 Environment", }, "Open a file and read its report": { "fr": "📖 Ouvrir un fichier et lire son rapport", "en": "📖 Open a file and read its report", }, "Install the reading environment": { "fr": "📦 Installer l'environnement de lecture", "en": "📦 Install the reading environment", }, "What can this machine read?": { "fr": "🩺 Que sait lire cette machine ?", "en": "🩺 What can this machine read?", }, "Copies produced": { "fr": "🗂 Copies produites", "en": "🗂 Copies produced", }, "A dedicated environment is required to read this format.": { "fr": "Un environnement dédié est nécessaire pour lire ce format.", "en": "A dedicated environment is required to read this format.", }, "Create it now? (Y/n): ": { "fr": "Le créer maintenant ? (O/n) : ", "en": "Create it now? (Y/n): ", }, "The environment is ready.": { "fr": "L'environnement est prêt.", "en": "The environment is ready.", }, "Creation finished but the libraries are still missing.": { "fr": "Création terminée mais les bibliothèques manquent toujours.", "en": "Creation finished but the libraries are still missing.", }, "python -m venv exited with": { "fr": "python -m venv a rendu", "en": "python -m venv exited with", }, "Access files need a system package.": { "fr": "Les fichiers Access demandent un paquet système.", "en": "Access files need a system package.", }, "readable": { "fr": "lisible", "en": "readable", }, "not readable": { "fr": "non lisible", "en": "not readable", }, "Contents do not match the extension: read as ": { "fr": "Le contenu ne correspond pas à l'extension : lu comme ", "en": "Contents do not match the extension: read as ", }, "Encoding detected by ": { "fr": "Encodage détecté par ", "en": "Encoding detected by ", }, "Delimiter detected by ": { "fr": "Délimiteur détecté par ", "en": "Delimiter detected by ", }, "bom": { "fr": "BOM", "en": "BOM", }, "chardet": { "fr": "chardet", "en": "chardet", }, "sniffer": { "fr": "sniffer", "en": "sniffer", }, "mesure": { "fr": "mesure", "en": "measurement", }, "repli": { "fr": "repli", "en": "fallback", }, "sheet(s)": { "fr": "feuille(s)", "en": "sheet(s)", }, "chart sheet(s)": { "fr": "feuille(s) graphique", "en": "chart sheet(s)", }, "hidden": { "fr": "masquée", "en": "hidden", }, "formula(s)": { "fr": "formule(s)", "en": "formula(s)", }, "formula(s) holding a text literal": { "fr": "formule(s) portant un littéral texte", "en": "formula(s) holding a text literal", }, "distinct value(s)": { "fr": "valeur(s) distincte(s)", "en": "distinct value(s)", }, "VBA macros present": { "fr": "Macros VBA présentes", "en": "VBA macros present", }, "No VBA macro": { "fr": "Aucune macro VBA", "en": "No VBA macro", }, "pivot table(s)": { "fr": "tableau(x) croisé(s)", "en": "pivot table(s)", }, "chart(s) with cached series": { "fr": "graphique(s) à séries en cache", "en": "chart(s) with cached series", }, "image(s) and drawing(s)": { "fr": "image(s) et dessin(s)", "en": "image(s) and drawing(s)", }, "external link(s)": { "fr": "lien(s) externe(s)", "en": "external link(s)", }, "cell hyperlink(s)": { "fr": "hyperlien(s) de cellule", "en": "cell hyperlink(s)", }, "comment(s)": { "fr": "commentaire(s)", "en": "comment(s)", }, "comment author(s)": { "fr": "auteur(s) de commentaire", "en": "comment author(s)", }, "header(s)/footer(s)": { "fr": "en-tête(s)/pied(s)", "en": "header(s)/footer(s)", }, "validation(s)": { "fr": "validation(s)", "en": "validation(s)", }, "conditional format(s)": { "fr": "mise(s) en forme conditionnelle(s)", "en": "conditional format(s)", }, "Text outside cells": { "fr": "Texte hors cellules", "en": "Text outside cells", }, "Author": { "fr": "Auteur", "en": "Author", }, "Link targets": { "fr": "Cibles des liens", "en": "Link targets", }, "named range(s)": { "fr": "plage(s) nommée(s)", "en": "named range(s)", }, "Anonymisable": { "fr": "Anonymisable", "en": "Anonymisable", }, "word(s) in the pool": { "fr": "mot(s) dans le vivier", "en": "word(s) in the pool", }, "Left intact": { "fr": "Laissé intact", "en": "Left intact", }, "date(s)": { "fr": "date(s)", "en": "date(s)", }, "boolean(s)": { "fr": "booléen(s)", "en": "boolean(s)", }, "error value(s)": { "fr": "valeur(s) d'erreur", "en": "error value(s)", }, "binary value(s)": { "fr": "valeur(s) binaire(s)", "en": "binary value(s)", }, "This format stores no formula readable here.": { "fr": "Ce format ne stocke aucune formule lisible ici.", "en": "This format stores no formula readable here.", }, "saved query(ies)": { "fr": "requête(s) enregistrée(s)", "en": "saved query(ies)", }, "Access saved queries are readable here.": { "fr": "Les requêtes enregistrées d'Access sont lisibles ici.", "en": "Access saved queries are readable here.", }, "Install it by hand to read Access saved queries.": { "fr": "L'installer à la main pour lire les requêtes enregistrées d'Access.", "en": "Install it by hand to read Access saved queries.", }, "Saved queries cannot be counted here: install mdbtools to know whether this file holds any.": { "fr": "Les requêtes enregistrées ne peuvent pas être comptées ici : installer mdbtools pour savoir si ce fichier en porte.", "en": "Saved queries cannot be counted here: install mdbtools to know whether this file holds any.", }, "Saved queries are not carried over to the copy.": { "fr": "Les requêtes enregistrées ne sont pas reprises dans la copie.", "en": "Saved queries are not carried over to the copy.", }, "Saved queries are not readable in pure Python.": { "fr": "Les requêtes enregistrées ne sont pas lisibles en pur Python.", "en": "Saved queries are not readable in pure Python.", }, "Only 20 fallback words are available: randomwordfr is missing.": { "fr": "Seuls 20 mots de repli sont disponibles : randomwordfr est absent.", "en": "Only 20 fallback words are available: randomwordfr is missing.", }, "0 to cancel": { "fr": "0 pour annuler", "en": "0 to cancel", }, "Anonymise this file? (y/N): ": { "fr": "Anonymiser ce fichier ? (o/N) : ", "en": "Anonymise this file? (y/N): ", }, "Convert at the same time? (xlsx/csv/json/xml, empty = keep): ": { "fr": "Convertir en même temps ? (xlsx/csv/json/xml, vide = garder) : ", "en": "Convert at the same time? (xlsx/csv/json/xml, empty = keep): ", }, "Sheets to process (empty = all): ": { "fr": "Feuilles à traiter (vide = toutes) : ", "en": "Sheets to process (empty = all): ", }, "Columns to leave untouched (empty = none): ": { "fr": "Colonnes à laisser intactes (vide = aucune) : ", "en": "Columns to leave untouched (empty = none): ", }, "Numbers keep their digit count, so the column's measured extent no longer bounds them: a rate or a year can leave its range.": { "fr": "Les nombres gardent leur nombre de chiffres, donc l'étendue mesurée de la colonne ne les borne plus : un taux ou une année peut sortir de sa plage.", "en": "Numbers keep their digit count, so the column's measured extent no longer bounds them: a rate or a year can leave its range.", }, "draw a number of the same width; drops the extent": { "fr": "tirer un nombre de même largeur ; abandonne l'étendue", "en": "draw a number of the same width; drops the extent", }, "left in clear, numeric and unique:": { "fr": "laissée(s) en clair, numérique(s) et unique(s) :", "en": "left in clear, numeric and unique:", }, "Keep the digit count? (y/N): ": { "fr": "Garder le nombre de chiffres ? (o/N) : ", "en": "Keep the digit count? (y/N): ", }, "Replace numbers? (Y/n): ": { "fr": "Remplacer les nombres ? (O/n) : ", "en": "Replace numbers? (Y/n): ", }, "Replace text? (Y/n): ": { "fr": "Remplacer le texte ? (O/n) : ", "en": "Replace text? (Y/n): ", }, "Anonymise the header row too? (y/N): ": { "fr": "Anonymiser aussi la ligne d'en-tête ? (o/N) : ", "en": "Anonymise the header row too? (y/N): ", }, "Random seed (empty = not reproducible): ": { "fr": "Graine aléatoire (vide = non reproductible) : ", "en": "Random seed (empty = not reproducible): ", }, "Mapping table to reuse (empty = a new one): ": { "fr": "Table de correspondance à réutiliser (vide = nouvelle) : ", "en": "Mapping table to reuse (empty = a new one): ", }, "Keep the VBA macros in the copy? (y/N): ": { "fr": "Garder les macros VBA dans la copie ? (o/N) : ", "en": "Keep the VBA macros in the copy? (y/N): ", }, "Keep the charts in the copy? (y/N): ": { "fr": "Garder les graphiques dans la copie ? (o/N) : ", "en": "Keep the charts in the copy? (y/N): ", }, "Macros are kept, so the copy is named .xlsm: Excel refuses a .xlsx holding a VBA project.": { "fr": "Les macros sont gardées, donc la copie se nomme .xlsm : Excel refuse un .xlsx qui porte un projet VBA.", "en": "Macros are kept, so the copy is named .xlsm: Excel refuses a .xlsx holding a VBA project.", }, "The copy is written in UTF-8, whatever the source was.": { "fr": "La copie est écrite en UTF-8, quel qu'ait été l'encodage de la source.", "en": "The copy is written in UTF-8, whatever the source was.", }, "The kept VBA project quotes a source value; answer no to the macro question to write the copy.": { "fr": "Le projet VBA gardé cite une valeur de la source ; répondre non à la question des macros pour écrire la copie.", "en": "The kept VBA project quotes a source value; answer no to the macro question to write the copy.", }, "An integer column is saturated: the copy holds the same set of values, only reshuffled.": { "fr": "Une colonne d'entiers est saturée : la copie porte le même ensemble de valeurs, seulement redistribuées.", "en": "An integer column is saturated: the copy holds the same set of values, only reshuffled.", }, "Open the TUI for setup? (Y/n): ": { "fr": "Ouvrir l'interface TUI pour paramétrage ? (O/n) : ", "en": "Open the TUI for setup? (Y/n): ", }, "Transform — anonymisation scope": { "fr": "Transform — périmètre de l'anonymisation", "en": "Transform — anonymisation scope", }, "‹no label›": { "fr": "‹sans libellé›", "en": "‹no label›", }, "column label": { "fr": "libellé", "en": "column label", }, "column type": { "fr": "type", "en": "column type", }, "filled": { "fr": "remplies", "en": "filled", }, "distinct": { "fr": "distinctes", "en": "distinct", }, "examples": { "fr": "exemples", "en": "examples", }, "row no": { "fr": "ligne", "en": "row no", }, "first values": { "fr": "premières valeurs", "en": "first values", }, "measures": { "fr": "mesures", "en": "measures", }, "sig type": { "fr": "type", "en": "sig type", }, "off-col": { "fr": "hors-col", "en": "off-col", }, "shape": { "fr": "forme", "en": "shape", }, "Toggle the current row": { "fr": "Cocher ou décocher la ligne courante", "en": "Toggle the current row", }, "Leave this column untouched": { "fr": "Laisser cette colonne intacte", "en": "Leave this column untouched", }, "Clear this sheet": { "fr": "Rendre cette feuille à la mesure", "en": "Clear this sheet", }, "Accept": { "fr": "Accepter", "en": "Accept", }, "Fall back to text prompts": { "fr": "Revenir aux invites textuelles", "en": "Fall back to text prompts", }, "[x] untouched · [!] floored · * corrected · = from the batch table": { "fr": "[x] intacte · [!] planchéiée · * corrigée · = de la table du lot", "en": "[x] untouched · [!] floored · * corrected · = from the batch table", }, "[x] untouched · [!] floored, not answerable": { "fr": "[x] intacte · [!] planchéiée, non répondable", "en": "[x] untouched · [!] floored, not answerable", }, "This column is floored: no answer applies.": { "fr": "Cette colonne est planchéiée : aucune réponse n'y porte.", "en": "This column is floored: no answer applies.", }, "The screen needs textual; falling back to prompts.": { "fr": "L'écran demande textual ; retour aux invites.", "en": "The screen needs textual; falling back to prompts.", }, "Preview — nothing written yet": { "fr": "Aperçu — rien n'est encore écrit", "en": "Preview — nothing written yet", }, "Write? (Y/n): ": { "fr": "Écrire ? (O/n) : ", "en": "Write? (Y/n): ", }, "Destination": { "fr": "Destination", "en": "Destination", }, "Enter to accept, p to browse, or type a path: ": { "fr": "Entrée pour accepter, p pour parcourir, ou taper un chemin : ", "en": "Enter to accept, p to browse, or type a path: ", }, "Written: ": { "fr": "Écrit : ", "en": "Written: ", }, "cell(s) replaced": { "fr": "cellule(s) remplacée(s)", "en": "cell(s) replaced", }, "cell(s) left out of scope": { "fr": "cellule(s) laissée(s) hors portée", "en": "cell(s) left out of scope", }, "element(s) outside cells wiped": { "fr": "élément(s) hors cellules effacé(s)", "en": "element(s) outside cells wiped", }, "column(s) left alone: they hold identifiers": { "fr": "colonne(s) laissée(s) : elles portent des identifiants", "en": "column(s) left alone: they hold identifiers", }, "The original was not modified.": { "fr": "L'original n'a pas été modifié.", "en": "The original was not modified.", }, "These files would be overwritten: ": { "fr": "Ces fichiers seraient écrasés : ", "en": "These files would be overwritten: ", }, "This file already exists. Type its name in full to overwrite: ": { "fr": "Ce fichier existe déjà. Taper son nom en entier pour l'écraser : ", "en": "This file already exists. Type its name in full to overwrite: ", }, "Name does not match, nothing was written.": { "fr": "Le nom ne correspond pas, rien n'a été écrit.", "en": "Name does not match, nothing was written.", }, "Mapping table written: ": { "fr": "Table de correspondance écrite : ", "en": "Mapping table written: ", }, "This table re-identifies the copy; keep it in private/.": { "fr": "Cette table ré-identifie la copie ; la garder dans private/.", "en": "This table re-identifies the copy; keep it in private/.", }, "The file name is not anonymised; the default does not reuse it.": { "fr": "Le nom du fichier n'est pas anonymisé ; le défaut ne le reprend pas.", "en": "The file name is not anonymised; the default does not reuse it.", }, "Delete all copies in private/transform/? (y/N): ": { "fr": "Supprimer toutes les copies de private/transform/ ? (o/N) : ", "en": "Delete all copies in private/transform/? (y/N): ", }, "private/ is tracked by git — this file will show in « git status ».": { "fr": "private/ est suivi par git — ce fichier apparaîtra dans « git status ».", "en": "private/ is tracked by git — this file will show in « git status ».", }, "Cached formula results are dropped; the sheet recomputes on open.": { "fr": "Les résultats de formule en cache sont perdus ; la feuille recalcule à l'ouverture.", "en": "Cached formula results are dropped; the sheet recomputes on open.", }, "Document properties were cleared on the copy.": { "fr": "Les propriétés du document ont été vidées sur la copie.", "en": "Document properties were cleared on the copy.", }, "Pivot tables and chart caches are removed: they hold an unanonymised copy of the source.": { "fr": "Les tableaux croisés et les caches de graphique sont supprimés : ils portent une copie non anonymisée de la source.", "en": "Pivot tables and chart caches are removed: they hold an unanonymised copy of the source.", }, "Images and drawings are not carried over to the copy.": { "fr": "Les images et les dessins ne sont pas repris dans la copie.", "en": "Images and drawings are not carried over to the copy.", }, "Charts are not carried over to the copy.": { "fr": "Les graphiques ne sont pas repris dans la copie.", "en": "Charts are not carried over to the copy.", }, "Charts are kept: their caches are cleaned through private attributes.": { "fr": "Les graphiques sont conservés : leurs caches sont nettoyés par des attributs privés.", "en": "Charts are kept: their caches are cleaned through private attributes.", }, "External links were dropped; formulas that used them show #REF!.": { "fr": "Les liens externes sont retirés ; les formules qui s'en servaient affichent #REF!.", "en": "External links were dropped; formulas that used them show #REF!.", }, "Range and table names are kept so formulas resolve; they may hold identifying strings.": { "fr": "Les noms de plages et de tableaux sont conservés pour que les formules résolvent ; ils peuvent porter des chaînes identifiantes.", "en": "Range and table names are kept so formulas resolve; they may hold identifying strings.", }, "Sheet names are kept so formulas resolve; they may identify.": { "fr": "Les noms de feuille sont conservés pour que les formules résolvent ; ils peuvent identifier.", "en": "Sheet names are kept so formulas resolve; they may identify.", }, "The VBA project and its companions (form controls, ActiveX, VML shapes, ribbon, EMF images) are copied as they are and were not reviewed.": { "fr": "Le projet VBA et ce qui l'accompagne (contrôles de formulaire, ActiveX, formes VML, ruban, images EMF) sont recopiés tels quels et n'ont pas été relus.", "en": "The VBA project and its companions (form controls, ActiveX, VML shapes, ribbon, EMF images) are copied as they are and were not reviewed.", }, "Format not recognised: ": { "fr": "Format non reconnu : ", "en": "Format not recognised: ", }, "Recognised format, unreadable here — re-save it as .xlsx.": { "fr": "Format reconnu, illisible ici — le ré-enregistrer en .xlsx.", "en": "Recognised format, unreadable here — re-save it as .xlsx.", }, "Protected by a password, or not a workbook — unreadable here.": { "fr": "Protégé par un mot de passe, ou pas un classeur — illisible ici.", "en": "Protected by a password, or not a workbook — unreadable here.", }, "Empty file.": { "fr": "Fichier vide.", "en": "Empty file.", }, "Not readable: check the permissions.": { "fr": "Illisible : vérifier les droits.", "en": "Not readable: check the permissions.", }, "Not an ordinary file.": { "fr": "Pas un fichier ordinaire.", "en": "Not an ordinary file.", }, "The destination is the source file; nothing was written.": { "fr": "La destination est le fichier source ; rien n'a été écrit.", "en": "The destination is the source file; nothing was written.", }, "The destination directory exists and is not empty.": { "fr": "Le répertoire de destination existe et n'est pas vide.", "en": "The destination directory exists and is not empty.", }, "The selection matches no sheet; nothing was written.": { "fr": "La sélection ne correspond à aucune feuille ; rien n'a été écrit.", "en": "The selection matches no sheet; nothing was written.", }, "Nothing was anonymised: every region was excluded.": { "fr": "Rien n'a été anonymisé : toutes les régions ont été exclues.", "en": "Nothing was anonymised: every region was excluded.", }, "Nothing to anonymise in this file.": { "fr": "Rien à anonymiser dans ce fichier.", "en": "Nothing to anonymise in this file.", }, "Not enough room to write.": { "fr": "Pas assez de place pour écrire.", "en": "Not enough room to write.", }, # Transform data - correctifs de fuite "A source value survives in the copy; nothing was written: ": { "fr": "Une valeur de la source subsiste dans la copie ; rien n'a été écrit : ", "en": "A source value survives in the copy; nothing was written: ", }, "The mapping table would overwrite the source or the copy; nothing was written.": { "fr": "La table de correspondance écraserait la source ou la copie ; rien n'a été écrit.", "en": "The mapping table would overwrite the source or the copy; nothing was written.", }, "Sheets outside the selection are dropped from the copy; formulas that referenced them show #REF!.": { "fr": "Les feuilles hors de la sélection sont retirées de la copie ; les formules qui les référençaient affichent #REF!.", "en": "Sheets outside the selection are dropped from the copy; formulas that referenced them show #REF!.", }, "Chart sheets are dropped from the copy: their titles and series caches are not cells.": { "fr": "Les feuilles graphiques sont retirées de la copie : leurs titres et leurs caches de série ne sont pas des cellules.", "en": "Chart sheets are dropped from the copy: their titles and series caches are not cells.", }, "Object keys are kept as structure; they may identify.": { "fr": "Les clés d'objet sont conservées comme structure ; elles peuvent identifier.", "en": "Object keys are kept as structure; they may identify.", }, "Element and attribute names are kept as structure; they may identify.": { "fr": "Les noms de balise et d'attribut sont conservés comme structure ; ils peuvent identifier.", "en": "Element and attribute names are kept as structure; they may identify.", }, "The mapping table is unreadable, or is not a mapping table: ": { "fr": "La table de correspondance est illisible, ou n'est pas une table de correspondance : ", "en": "The mapping table is unreadable, or is not a mapping table: ", }, "Leave the mapping table question empty to create a new one.": { "fr": "Laisser vide la question de la table pour en créer une neuve.", "en": "Leave the mapping table question empty to create a new one.", }, "A table of that name exists; using a new one.": { "fr": "Une table de ce nom existe ; une neuve est prise.", "en": "A table of that name exists; using a new one.", }, "column(s) entirely in clear": { "fr": "colonne(s) entièrement en clair", "en": "column(s) entirely in clear", }, "column(s) without examples": { "fr": "colonne(s) sans exemple", "en": "column(s) without examples", }, "These cells are copied verbatim:": { "fr": "Ces cellules sont recopiées telles quelles :", "en": "These cells are copied verbatim:", }, "more, not listed": { "fr": "autres, non listées", "en": "more, not listed", }, "Correct the header rows to anonymise them.": { "fr": "Corriger les lignes d'en-tête pour les anonymiser.", "en": "Correct the header rows to anonymise them.", }, "Mapping table: ": { "fr": "Table de correspondance : ", "en": "Mapping table: ", }, "value(s) not verified, above the cap": { "fr": "valeur(s) non vérifiée(s), au-delà du plafond", "en": "value(s) not verified, above the cap", }, "Not produced here, left alone:": { "fr": "Non produit ici, laissé en place :", "en": "Not produced here, left alone:", }, "The library here cannot read this file: ": { "fr": "La bibliothèque ne sait pas lire ce fichier ici : ", "en": "The library here cannot read this file: ", }, "This target cannot hold the source's shape: ": { "fr": "Cette cible ne peut pas porter la forme de la source : ", "en": "This target cannot hold the source's shape: ", }, } def get_lang() -> str: global _current_lang if _current_lang is not None: return _current_lang # 1. Check env_var.sh file if os.path.exists(ENV_VAR_FILE): try: with open(ENV_VAR_FILE) as f: content = f.read() match = re.search( r'^EL_LANG=["\']?(\w+)["\']?', content, re.MULTILINE ) if match: lang = match.group(1) if lang in ("fr", "en"): _current_lang = lang return _current_lang except OSError: pass # 2. Check env var env_lang = os.environ.get("EL_LANG") if env_lang in ("fr", "en"): _current_lang = env_lang return _current_lang # 3. Default _current_lang = "fr" return _current_lang def set_lang(lang: str) -> None: global _current_lang _current_lang = lang # Persist to env_var.sh if os.path.exists(ENV_VAR_FILE): try: with open(ENV_VAR_FILE) as f: content = f.read() except OSError: return new_line = f'EL_LANG="{lang}"' if re.search(r"^EL_LANG=", content, re.MULTILINE): content = re.sub( r'^EL_LANG=["\']?\w*["\']?', new_line, content, count=1, flags=re.MULTILINE, ) else: content = content.rstrip("\n") + "\n" + new_line + "\n" with open(ENV_VAR_FILE, "w") as f: f.write(content) def lang_is_configured() -> bool: """Check if a language has been explicitly set.""" if os.path.exists(ENV_VAR_FILE): try: with open(ENV_VAR_FILE) as f: content = f.read() return bool(re.search(r"^EL_LANG=", content, re.MULTILINE)) except OSError: pass return False def t(key: str) -> str: entry = TRANSLATIONS.get(key) if entry is None: return key lang = get_lang() return entry.get(lang, entry.get("fr", key))