{
  "forms": {
    "upload_dir_error": "Erreur lors de la création du dossier d'upload",
    "file_create_error": "Erreur lors de la création du fichier",
    "multipart_stream_error": "Erreur dans le flux multipart",
    "file_write_error": "Erreur lors de l'écriture du fichier",
    "required": "Ce champ est obligatoire",
    "too_short": "Trop court (min {})",
    "too_long": "Trop long (max {})",
    "email_invalid": "Format d'adresse email invalide",
    "url_invalid": "Veuillez entrer une URL valide",
    "phone_invalid": "Numéro de téléphone invalide (chiffres, +, espaces, tirets autorisés, 7-15 chiffres)",
    "hash_error": "Erreur de hachage : {}",
    "password_empty": "Le mot de passe ne peut pas être vide",
    "filter_invalid_value": "Le filtre static/media a reçu une valeur invalide ({}) au lieu d'un chemin de fichier.",
    "number_invalid": "Nombre invalide",
    "number_required": "Requis",
    "integer_required": "Doit être un entier",
    "decimal_required": "Doit être au format décimal",
    "min_value": "Min {} requis",
    "max_value": "Max {} dépassé",
    "precision_max": "Précision max {} chiffres après virgule",
    "precision_min": "Précision min {} chiffres après virgule",
    "color_invalid": "Couleur invalide (format: #RRGGBB ou #RGB)",
    "color_no_hash": "La couleur doit commencer par #",
    "color_bad_hex": "Contient des caractères non hexadécimaux",
    "slug_invalid": "Slug invalide",
    "slug_no_dash": "Le slug ne doit pas commencer ou finir par un tiret",
    "uuid_invalid": "Format UUID invalide (attendu: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx)",
    "json_invalid": "JSON invalide : {}",
    "ipv4_only": "Seules les adresses IPv4 sont acceptées",
    "ipv6_only": "Seules les adresses IPv6 sont acceptées",
    "ip_invalid": "Adresse IP invalide",
    "date_invalid": "Format de date invalide",
    "date_too_old": "Trop ancien (min : {})",
    "date_too_far": "Trop loin (max : {})",
    "time_invalid": "Format de temps invalide",
    "file_required": "Veuillez sélectionner au moins un fichier",
    "file_extension_blocked": "Fichier '{}' non autorisé. Extensions : {}",
    "finalize_error": "Erreur lors de la finalisation du champ '{}': {}",
    "template_missing": "Template manquant: {}",
    "render_js_error": "Erreur rendu JS: {}",
    "tera_not_configured": "Tera non configuré",
    "config_not_found": "Configuration introuvable dans les extensions",
    "hint_slug": "Format : lettres-chiffres-tirets",
    "hint_uuid": "Format : xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
    "hint_json": "Format JSON valide requis",
    "hint_ip_v4": "Format IPv4 : 192.168.1.1",
    "hint_ip_v6": "Format IPv6 : 2001:0db8:85a3::8a2e:0370:7334",
    "hint_ip": "Format IPv4 ou IPv6",
    "validation_overflow": "Stack overflow détecté : récursion infinie dans la validation",
    "choice_invalid": "Choix invalide",
    "choice_invalid_value": "Choix invalide : {}",
    "select_required": "Veuillez sélectionner une option",
    "checkbox_required": "Veuillez sélectionner au moins une option",
    "multipart_error": "Erreur multipart",
    "body_error": "Erreur lecture du body",
    "aegis_query_error": "Échec parsing query string : {}",
    "aegis_urlencoded_error": "Échec parsing urlencoded : {}",
    "aegis_json_error": "Échec parsing JSON : {}",
    "auth_required": "Authentification requise",
    "role_insufficient": "Rôle insuffisant",
    "time_too_old": "Trop tôt (min : {})",
    "time_too_far": "Trop tard (max : {})",
    "datetime_too_old": "Trop tôt (min : {})",
    "datetime_too_far": "Trop tard (max : {})",
    "duration_invalid": "Durée invalide (nombre de secondes attendu)",
    "duration_too_short": "Durée minimale : {} secondes",
    "duration_too_long": "Durée maximale : {} secondes",
    "file_max_count": "Maximum {} fichiers autorisés",
    "file_too_large": "Fichier '{}' trop volumineux ({}MB > {}MB max)",
    "file_invalid_image": "Le fichier '{}' n'est pas une image valide",
    "image_too_wide": "L'image '{}' est trop large ({}px > {}px)",
    "image_too_tall": "L'image '{}' est trop haute ({}px > {}px)",
    "boolean_required": "Vous devez accepter ce champ",
    "slug_unicode_invalid": "Seules les lettres, chiffres, tirets et underscores sont autorisés",
    "unique_field_taken": "Ce {} est déjà utilisé.",
    "unique_value_taken": "La valeur du champ '{}' est déjà utilisée.",
    "unique_constraint_violated": "Une contrainte d'unicité a été violée.",
    "db_error": "Erreur DB : {}",
    "text_field_too_large": "Champ texte trop volumineux (max 1 Mo)",
    "upload_too_large": "Fichier trop volumineux (max {}Mo)"
  },
  "csrf": {
    "missing": "Token CSRF manquant",
    "invalid": "Token CSRF invalide",
    "invalid_or_missing": "Token CSRF invalide ou manquant",
    "forbidden": "Token CSRF invalide",
    "session_write_error": "Erreur d'écriture de session"
  },
  "error": {
    "source": "Source: {}",
    "AppError": "Erreur d'application",
    "build": "Erreur de build: {}",
    "internal": "Erreur interne",
    "forbidden": "Accès interdit",
    "not_found": "Ressource introuvable",
    "validation": "Erreur de validation: {}",
    "database": "Erreur base de données: {}",
    "io": "Erreur IO: {}",
    "template": "Erreur template: {}",
    "custom": "Erreur custom: {}",
    "title": {
      "not_found": "Page non trouvée",
      "forbidden": "Accès interdit",
      "validation": "Erreur de validation",
      "database": "Erreur base de données",
      "template": "Erreur de rendu de template",
      "internal": "Erreur serveur interne"
    },
    "path_not_found": "Le chemin demandé '{}' n'a pas été trouvé",
    "internal_occurred": "Une erreur interne est survenue",
    "context_occurred": "Erreur AppError survenue"
  },
  "title": {
    "template": "Erreur de template dans '{}'"
  },
  "build": {
    "validation_failed": "Échec de la validation du build : {}",
    "check_failed": "Échec du build avec {} erreur(s) de vérification",
    "template_failed": "Échec du chargement du template : {}",
    "db_missing": "Connexion à la base de données requise lorsque la feature 'orm' est activée",
    "component_not_ready": "Le composant '{}' n'est pas prêt"
  },
  "middleware": {
    "host_invalid": "Hôte invalide: '{}' (Hosts autorisés: {})",
    "host_debug": "Hôte invalide : '{}'. Ajoutez-le à RUNIQUE_ALLOWED_HOSTS.",
    "bad_request": "Mauvaise requête"
  },
  "html": {
    "404_title": "404",
    "404_text": "Page non trouvée",
    "500_title": "500",
    "500_text": "Une erreur est survenue sur le serveur",
    "500_notice": "Nos équipes ont été notifiées et travaillent sur le problème.",
    "429_title": "429",
    "429_text": "Trop de requêtes. Veuillez patienter un moment avant de réessayer.",
    "back_home": "Retour à l'accueil",
    "critical_error_title": "Erreur critique",
    "critical_error_text": "Le système de gestion d'erreurs a lui-même rencontré une erreur.",
    "critical_error_contact": "Cette situation ne devrait jamais se produire. Veuillez contacter l'administrateur système."
  },
  "debug": {
    "stack_trace_title": "Trace d'erreur détaillée",
    "stack_trace_tip": "L'erreur la plus haute (niveau 0) est généralement la cause racine. Les erreurs suivantes montrent comment l'erreur s'est propagée dans le code."
  },
  "flash": {
    "welcome": "Bienvenue {}, votre compte est créé !",
    "fix_errors": "Veuillez corriger les erreurs",
    "success_demo": "Ceci est un message de succès.",
    "info_demo": "Ceci est un message d'information.",
    "warning_demo": "Ceci est un message d'avertissement.",
    "error_demo": "Ceci est un message d'erreur."
  },
  "log": {
    "db_connecting": "Connexion à la base de données {}...",
    "db_connected": "Base de données connectée avec succès ({})",
    "db_failed": "Échec de la connexion à la base de données",
    "db_engine": "Moteur : {}",
    "template_render_error": "Erreur de rendu du template",
    "error_handler": "Erreur critique survenue",
    "error_handled": "Erreur traitée",
    "files_count": "ajout de fichiers JS au formulaire",
    "js_file_skip": "Fichier JS ignoré",
    "already_initialized": "Logger déjà initialisé"
  },
  "cli": {
    "creating_project": "Création du projet '{}'...",
    "admin_detected": "Admin détecté → démarrage du daemon",
    "add_admin_hint": "Ajoutez .with_admin(...) dans votre builder pour activer le panneau admin.",
    "daemon_error": "[Daemon] Erreur : {}",
    "cargo_run_failed": "Le serveur applicatif n'a pas démarré correctement (cargo run)",
    "file_not_found": "Fichier non trouvé : {}\\nAssurez-vous d'être à la racine de votre projet Runique.",
    "admin_not_found": "Fichier admin non trouvé : {}\\nCréez src/admin.rs avec la macro admin!{{}}.",
    "name_empty": "Le nom du projet ne peut pas être vide",
    "name_invalid": "Le nom du projet ne doit contenir que des lettres, chiffres, _ ou -",
    "name_dash": "Le nom du projet ne peut pas commencer par -",
    "folder_exists": "Le dossier '{}' existe déjà",
    "cargo_run_expect": "Échec du lancement de cargo run",
    "project_created": "Projet '{}' créé avec succès !",
    "getting_started": "Pour démarrer :",
    "cd_hint": "cd {}",
    "cargo_run_hint": "cargo run"
  },
  "daemon": {
    "modification_detected": "Modification détectée → régénération...",
    "unable_read": "Impossible de lire : {}",
    "parse_error": "Erreur d'analyse : {}",
    "no_resource": "Aucune ressource dans admin!{{}} — rien à générer",
    "with_admin_disabled": "with_admin désactivé → daemon arrêté",
    "operational": "Daemon opérationnel → src/admin/generated.rs",
    "generation_error": "Erreur de génération : {}",
    "watcher_error": "Erreur du watcher : {}",
    "unable_create": "Impossible de créer le watcher : {}",
    "unable_watch": "Impossible de surveiller {} : {}"
  },
  "macro": {
    "named_fields_only": "Structs à champs nommés uniquement",
    "structs_only": "Fonctionne uniquement sur des structs",
    "forms_field_required": "Struct '{}' doit avoir un champ 'Forms'",
    "field_no_name": "Champ sans nom",
    "model_form_named_only": "DeriveModelForm : structs avec champs nommés uniquement",
    "model_form_structs_only": "DeriveModelForm : structs uniquement"
  },
  "parser": {
    "string_expected": "Chaîne littérale attendue, trouvé : {}",
    "string_eof": "Chaîne littérale attendue, fin de fichier",
    "array_expected": "Tableau [...] attendu pour les permissions, trouvé : {}",
    "array_eof": "Tableau [...] attendu pour les permissions, fin de fichier",
    "role_required": "Au moins un rôle requis dans permissions: [...]",
    "punct_expected": "'{}' attendu, trouvé : {}",
    "punct_eof": "'{}' attendu, fin de fichier",
    "title_required": "admin!: 'title' est requis",
    "permissions_required": "admin!: 'permissions' est requis",
    "list_display_exclude_exclusive": "admin!: 'list_display' et 'list_exclude' sont mutuellement exclusifs"
  },
  "TemplateMessage": {
    "debug_info_title": "Informations de debug",
    "debug_field_title": "Titre",
    "debug_field_count": "Nombre de champs",
    "debug_error_count": "Erreurs",
    "debug_main_message": "Message principal",
    "debug_root_cause": "Cause racine",
    "debug_details": "Détails supplémentaires",
    "debug_request_info": "Informations de la requête",
    "debug_http_method": "Méthode HTTP",
    "debug_path": "Chemin",
    "debug_query_params": "Paramètres de requête",
    "debug_http_headers": "En-têtes HTTP",
    "debug_template_info": "Informations du template",
    "debug_template_name": "Nom du template",
    "debug_error_line": "Ligne de l'erreur",
    "debug_template_source": "Code source du template",
    "debug_available_templates": "Templates disponibles",
    "debug_stack_trace_title": "Trace d'erreur détaillée",
    "debug_stack_trace_tip": "L'erreur la plus haute (niveau 0) est généralement la cause racine. Les erreurs suivantes montrent comment l'erreur s'est propagée dans le code.",
    "debug_environment": "Environnement",
    "debug_debug_mode": "Mode debug",
    "debug_enabled": "Activé",
    "debug_disabled": "Désactivé",
    "debug_rust_version": "Version Rust",
    "debug_app_version": "Version App",
    "debug_status_code": "Code de statut",
    "debug_header_name": "Nom",
    "debug_header_value": "Valeur"
  },
  "admin": {
    "group": "Groupe",
    "groups": "Groupes",
    "resource": "Ressource",
    "resources": "Ressources",
    "can_create": "Créer",
    "can_read": "Lire",
    "can_update": "Modifier",
    "can_delete": "Supprimer",
    "can_update_own": "Modifier",
    "can_delete_own": "Supprimer",
    "name": "Nom",
    "username": "Nom d'utilisateur",
    "email": "Email",
    "staff": "Staff",
    "superuser": "Superutilisateur",
    "active": "Actif",
    "user": {
      "username_too_short": "Le nom d'utilisateur est trop court (min 3 car.)",
      "invalid_email": "Format d'adresse email invalide"
    },

    "login": {
      "title": "Connexion",
      "subtitle": "Connectez-vous pour accéder au panneau d'administration",
      "label_username": "Nom d'utilisateur",
      "label_password": "Mot de passe",
      "btn_submit": "Se connecter",
      "error_session": "Erreur lors de l'ouverture de session.",
      "error_credentials": "Identifiants incorrects ou droits insuffisants.",
      "error_locked": "Trop de tentatives. Compte temporairement verrouillé. Réessayez dans {} secondes."
    },
    "logout": {
      "success": "Déconnexion réussie."
    },
    "access": {
      "no_auth_handler": "Aucun handler d'authentification configuré. Appelez .auth(MyAuth) sur AdminConfig.",
      "insufficient_rights": "Droits insuffisants pour accéder à l'administration"
    },
    "dashboard": {
      "title": "Tableau de bord",
      "subtitle": "Vue d'ensemble de l'application",
      "card_resources": "Ressources",
      "th_resource": "Ressource",
      "th_key": "Clé",
      "th_permissions": "Permissions",
      "th_actions": "Actions",
      "btn_list": "Liste",
      "btn_create": "Créer",
      "see_list": "Voir la liste →",
      "empty_title": "Aucune ressource enregistrée",
      "empty_desc": "Déclarez vos ressources dans src/admin.rs avec le macro admin!{{}} puis lancez runique start"
    },
    "list": {
      "breadcrumb_admin": "Administration",
      "entries_count_one": "entrée",
      "entries_count_many": "entrées",
      "btn_create": "Créer",
      "th_id": "id",
      "th_actions": "Actions",
      "bool_true": "Oui",
      "bool_false": "Non",
      "btn_detail": "Détail",
      "btn_edit": "Modifier",
      "btn_delete": "Supprimer",
      "confirm_delete": "Vraiment supprimer ?",
      "empty_title": "Aucune entrée",
      "empty_desc": "Commencez par créer un élément.",
      "btn_create_first": "Créer le premier",
      "search_placeholder": "Rechercher..."
    },
    "create": {
      "title": "Créer",
      "breadcrumb": "Créer",
      "card_info": "Informations",
      "no_fields": "Aucun champ disponible pour le moment.",
      "btn_cancel": "Annuler",
      "btn_submit": "Créer",
      "success": "Entrée créée avec succès !"
    },
    "edit": {
      "title": "Modifier",
      "breadcrumb": "Modifier",
      "card_info": "Informations",
      "no_fields": "Aucun champ disponible pour le moment.",
      "btn_cancel": "Annuler",
      "btn_submit": "Enregistrer",
      "success": "Entrée mise à jour avec succès !"
    },
    "detail": {
      "title": "Détail",
      "breadcrumb": "Détail",
      "entry_label": "Entrée",
      "btn_list": "← Liste",
      "btn_edit": "Modifier",
      "btn_delete": "Supprimer",
      "confirm_delete": "Supprimer cette entrée ?"
    },
    "reset_password": {
      "btn": "Réinitialiser le mot de passe",
      "success_email": "Lien de réinitialisation envoyé à {}.",
      "success_link": "Lien de réinitialisation (mailer non configuré) : {}",
      "error_no_email": "Aucun champ email trouvé pour cet utilisateur.",
      "error_send": "Erreur lors de l'envoi de l'email : {}",
      "email_subject": "Réinitialisation de votre mot de passe",
      "email_title": "Réinitialisation du mot de passe",
      "email_greeting": "Bonjour,",
      "email_body": "Cliquez sur le lien ci-dessous pour réinitialiser votre mot de passe (valide 1 heure) :",
      "email_btn": "Réinitialiser mon mot de passe",
      "email_ignore": "Si vous n'avez pas demandé cette réinitialisation, ignorez ce message."
    },
    "user_created": {
      "email_subject": "Bienvenue — définissez votre mot de passe",
      "email_sent": "Email de bienvenue envoyé à {}.",
      "email_greeting": "Bienvenue,",
      "email_body": "Un compte a été créé pour vous. Cliquez sur le lien ci-dessous pour définir votre mot de passe :",
      "email_btn": "Définir mon mot de passe",
      "email_validity": "Ce lien est valide 1 heure. Si vous n'attendiez pas ce message, ignorez-le."
    },
    "delete": {
      "title": "Supprimer",
      "breadcrumb": "Supprimer",
      "heading": "Confirmer la suppression",
      "btn_cancel": "← Annuler",
      "btn_confirm": "Oui, supprimer définitivement",
      "success": "Entrée supprimée avec succès !",
      "not_found": "Ressource introuvable.",
      "warning": {
        "title": "Attention !",
        "desc": "Vous êtes sur le point de supprimer l'entrée",
        "of": "de la ressource",
        "irreversible": "Cette action est irréversible."
      }
    },
    "bulk": {
      "no_selection": "Aucun élément sélectionné.",
      "no_field_selected": "Aucun champ modifié.",
      "delete_success": "élément(s) supprimé(s).",
      "update_success": "élément(s) mis à jour."
    },
    "base": {
      "title": "Administration",
      "breadcrumb": "Admin",
      "toggle": "Réduire le menu",
      "logout_title": "Déconnexion"
    },
    "superuser_wizard": {
      "title": "=== Créer un superutilisateur ===",
      "algo_prompt": "[1/5] Algorithme de hachage",
      "algo_argon2": "Argon2 (recommandé)",
      "algo_bcrypt": "Bcrypt",
      "algo_scrypt": "Scrypt",
      "algo_custom": "Fournisseur personnalisé",
      "provider_path": "Chemin du fournisseur",
      "invalid_path": "Chemin invalide.",
      "username_prompt": "[2/5] Nom d'utilisateur",
      "username_empty": "Le nom d'utilisateur ne peut pas être vide.",
      "username_taken": "Un utilisateur avec ce nom existe déjà.",
      "email_prompt": "[3/5] Email",
      "email_invalid": "Email invalide.",
      "email_taken": "Un utilisateur avec cet email existe déjà.",
      "password_prompt": "[4/5] Mot de passe",
      "password_too_short": "Le mot de passe doit contenir au moins 10 caractères.",
      "confirm_prompt": "[5/5] Confirmer le mot de passe",
      "password_mismatch": "Les mots de passe ne correspondent pas. Veuillez réessayer.",
      "review_algo": "  Algorithme  : {}",
      "review_username": "  Utilisateur : {}",
      "review_email": "  Email       : {}",
      "review_password": "  Mot de passe : ••••••••",
      "review_action": "Action",
      "confirm_create": "Confirmer et créer",
      "change_algo": "Changer d'algorithme",
      "modify_password": "Modifier le mot de passe",
      "success": "✓ Superutilisateur créé avec succès !",
      "id_line": "  ID          : {}",
      "username_line": "  Utilisateur : {}",
      "email_line": "  Email       : {}"
    },
    "builtin": {
      "invalid_id": "Identifiant invalide.",
      "droit_resource_required": "Veuillez sélectionner au moins une ressource.",
      "droit_exists": "Le droit \"{}\" existe déjà.",
      "groupe_exists": "Un groupe nommé « {} » existe déjà.",
      "user_username_exists": "Le nom d'utilisateur « {} » est déjà pris.",
      "user_email_exists": "L'adresse e-mail « {} » est déjà utilisée."
    }
  },
  "reset": {
    "forgot_title": "Mot de passe oublié",
    "reset_title": "Nouveau mot de passe",
    "success_title": "Mot de passe réinitialisé",
    "email_label": "Adresse email",
    "new_password_label": "Nouveau mot de passe",
    "confirm_label": "Confirmer le mot de passe",
    "email_mismatch": "L'adresse email ne correspond pas au lien.",
    "invalid_link": "Lien invalide.",
    "invalid_or_expired": "Lien de réinitialisation invalide ou expiré.",
    "password_min_length": "Le mot de passe doit contenir au moins {} caractères.",
    "password_mismatch": "Les mots de passe ne correspondent pas.",
    "check_inbox": "Si cette adresse est associée à un compte, vous recevrez un email de réinitialisation.",
    "email_subject": "Réinitialisation de votre mot de passe",
    "email_body": "<p>Bonjour {},</p><p>Cliquez sur le lien suivant pour réinitialiser votre mot de passe (valide 1 heure) :</p><p><a href=\"{}\">{}</a></p>"
  },
  "makemigrations": {
    "scanning": "Scan des entités dans '{}'...",
    "found_schema": "-> Schéma trouvé : {}",
    "found_extend": "-> Extension trouvée pour la table framework : {}",
    "no_schema": "Aucune fonction schema() trouvée dans '{}'.",
    "schema_count": "{} schéma(s) trouvé(s).",
    "updated_lib": "Mis à jour {}",
    "no_changes": "Aucun changement détecté. Votre schéma est à jour.",
    "destructive_detected": "Changements destructifs détectés :",
    "destructive_require_force": "Utilisez --force pour appliquer ces changements destructifs.",
    "generated": "Généré : {}",
    "snapshot_updated": "Snapshot mis à jour : {}",
    "seaorm_alter": "Migration ALTER SeaORM générée : {}",
    "batch_up": "Batch up généré : {}",
    "batch_down": "Batch down généré : {}",
    "apply_hint": "Lancez 'sea-orm-cli migrate up' pour appliquer.",
    "extend_unknown_table": "extend!{{}} : \"{}\" n'est pas une table framework connue. Tables autorisées : {}. Pour étendre une table applicative, modifiez son model!{{}} directement.",
    "extend_invalid_syntax": "extend!{{}} : syntaxe invalide. Attendu : table: \"nom_table\", fields: {{ ... }}",
    "admin_positioned": "AdminTableMigration positionnée après la migration de '{}'",
    "files_ready": "{} fichier(s) prêt(s) à migrer."
  },
  "migrate": {
    "applying": "Application des migrations depuis '{}'...",
    "run_hint": "Commande : sea-orm-cli migrate up",
    "complete_up": "Migration terminé.",
    "complete": "Rollback terminé.",
    "available_for": "Fichiers de rollback disponibles pour '{}' :",
    "rolling_back_batch": "Rollback du batch : {}",
    "done": "Terminé : {}",
    "rolling_back": "Rollback : {}",
    "no_applied_dir": "Aucun répertoire applied/ trouvé.",
    "by_time_header": "by_time (batches complets) :",
    "none_available": "Aucun fichier de rollback disponible.",
    "usage": "Utilisation :",
    "usage_files": "runique migration down --files <table/timestamp> [<table/timestamp> ...]",
    "usage_batch": "runique migration down --batch <timestamp>",
    "no_down": "Aucune instruction down trouvée.",
    "executing": "Exécution : {}"
  },
  "permission": {
    "col.id": "ID",
    "col.can_create": "Créer",
    "col.can_delete": "Supprimer",
    "col.can_delete_own": "Supprimer (propre)",
    "col.can_read": "Lire",
    "col.can_update": "Modifier",
    "col.can_update_own": "Modifier (propre)",
    "col.groupes": "Groupes",
    "col.resource_key": "Ressource",
    "col.actions": "Actions"
  }
}
