{
  "time": {
    "current_time_label": "Heure actuelle :",
    "input_label": "Entrée (Unix ms/s ou date)",
    "input_placeholder": "1690000000 / 1690000000000 / 2026-04-22T00:00:00Z​",
    "convert": "Convertir",
    "copy_output": "Copier la sortie",
    "output": "Sortie",
    "err_parse_timestamp": "Impossible d'analyser l'horodatage.",
    "err_parse_date": "Impossible d'analyser la date string.",
    "copied": "Copié."
  },
  "json_diff": {
    "intro": "Différent au niveau de l'objet alimenté par jsondiffpatch (pas de diff en ligne simple). Les tableaux prennent en charge la détection de mouvement ; delta est une structure de patch pour ajouter/supprimer/mettre à jour des champs.",
    "left_json": "JSON gauche",
    "right_json": "JSON droit",
    "compute": "Calcul diff",
    "delta_title": "Delta (format jsondiffpatch)",
    "no_diff_comment": "// Aucune différence (même structure JSON)",
    "parse_failed": "Échec de l'analyse"
  },
  "ascii": {
    "th_dec": "Déc",
    "th_hex": "Hex​",
    "th_char": "Caractère",
    "th_note": "Remarque",
    "note_control": "Contrôle",
    "note_printable": "Imprimable"
  },
  "uuid": {
    "count_label": "Nombre (1–200)",
    "generate_uuid_v4": "Générer l'UUID v4",
    "copy_all": "Copier tout",
    "please_generate_first": "Veuillez d'abord générer.",
    "copied_all": "Tout copier.",
    "output": "Sortie",
    "output_placeholder": "Cliquez sur Générer."
  },
  "ulid": {
    "count_label": "Compte (1 à 100)",
    "generate": "Générer un ULID",
    "copy": "Copier",
    "placeholder": "ID à 26 caractères triés dans le temps"
  },
  "nanoid": {
    "length_label": "Longueur (4 à 64)",
    "alphabet_hint": "Alphabet personnalisé (vide = nanoid URL-safe par défaut)",
    "generate": "Générer",
    "copy": "Copier"
  },
  "units": {
    "css_title": "CSS : px ↔ rem",
    "root_px": "Taille de police racine (px)",
    "check_line": "Vérifiez : {px}px ÷ {root} = {rem} rem",
    "storage_title": "Taille des données",
    "iec_toggle": "Pas CEI (1024) : KiB / MiB / GiB",
    "bytes_label": "Nombre d'octets (entier)"
  },
  "color": {
    "picker": "Sélecteur de couleurs",
    "css": "CSS​",
    "hex": "HEX​",
    "rgb_title": "RVB (0–255)",
    "hsl_title": "HSL​",
    "h_label": "H (°)​",
    "s_label": "S (%)​",
    "l_label": "L (%)​",
    "copy_all_formats": "Copier tout formats",
    "copied_line": "Ligne HEX / RVB / HSL copiée."
  },
  "contrast": {
    "fg": "Premier plan (texte)",
    "bg": "Arrière-plan",
    "large_text_toggle": "Utiliser un seuil de texte volumineux (≥18 pt gras ou ≥24 pt normal)",
    "sample_text": "Exemple Aa 中文 123",
    "invalid_hex": "Utiliser #RRGGBB ou #RGB.",
    "ratio_label": "Contraste",
    "wcag_prefix": "WCAG 2.1 :"
  },
  "url_parse": {
    "parse": "Analyser",
    "err_invalid": "URL",
    "url_object_fields": "objet URL non valide champs",
    "search_params": "Requête (searchParams)",
    "key": "Clé",
    "value": "Valeur",
    "port_default": "(par défaut)",
    "page_intro": "Utilise une <api>URL</api> native et <usp>URLSearchParams</usp> ; aucune requête réseau."
  },
  "punycode": {
    "unicode_label": "Domaine Unicode / étiquettes (lignes ou séparés par des points)",
    "to_punycode": "→ Punycode / ASCII​",
    "puny_label": "Punycode (xn--…)​",
    "to_unicode": "→ Unicode​",
    "fail": "Échec"
  },
  "data_url": {
    "drop_label": "Fichier → URL de données",
    "drop_title": "Choisir ou déposer un fichier",
    "drop_desc": "Utilise FileReader.readAsDataURL ; non téléchargé.",
    "data_url": "URL des données",
    "copy": "Copier",
    "decode_download": "Décoder et télécharger",
    "err_format": "Données attendues :[mime][;base64],charge utile",
    "decode_failed": "Échec du décodage"
  },
  "mime_sniff": {
    "drop_label": "Lire l'en-tête du fichier",
    "drop_title": "Choisir ou déposer un fichier",
    "drop_desc": "Lit les 64 premiers octets pour un reniflement magique ; non téléchargé.",
    "guess_type": "Type deviné",
    "first_64_hex": "64 premiers octets (hex)"
  },
  "mime_types": {
    "search_ph": "Rechercher une extension ou MIME…",
    "col_ext": "Extension​",
    "col_mime": "MIME​",
    "col_note": "Remarque"
  },
  "html_format": {
    "format": "Format​",
    "minify_simple": "Minification simple (supprimer commentaires et espaces)",
    "output": "Sortie",
    "copy": "Copier",
    "fail": "Échec"
  },
  "svg_format": {
    "source": "Source SVG",
    "validate_indent": "Valider et indenter",
    "xml_parse_err": "Erreur d'analyse XML ; vérifier les balises.",
    "fail": "Échec"
  },
  "markdown": {
    "render_failed": "Échec du rendu",
    "label": "Source Markdown",
    "export_html": "Exporter HTML",
    "copy_md": "Copier Markdown",
    "preview": "Aperçu en direct"
  },
  "http_codes": {
    "search_ph": "Rechercher un code, un nom ou une description…",
    "col_code": "Code​",
    "col_name": "Nom",
    "col_desc": "Description​"
  },
  "ua_parse": {
    "fill_ua": "Remplir cet appareil UA",
    "hint": "Analyse légère des expressions régulières, pas une base de données complète de l'appareil ; les robots d'exploration/WebViews peuvent s'afficher comme Autre.",
    "browser": "Navigateur",
    "engine": "Moteur (grossier)",
    "os": "OS​",
    "mobile": "Mobile​",
    "yes": "Oui",
    "no": "Non"
  },
  "keycode": {
    "instructions": "Cliquez sur la zone ci-dessous, puis appuyez sur les touches (certains raccourcis sont bloqués par le navigateur).",
    "capture_aria": "Zone de capture de touches",
    "focus_hint": "Concentrez-vous ici, puis appuyez sur les touches…",
    "which_keycode": "qui / keyCode (hérité)",
    "modifiers": "Modificateurs"
  },
  "yaml_json": {
    "warning": "js-yaml exécute l'analyse des balises ; ne collez pas de gros YAML non fiables. Local uniquement.",
    "yaml_to_json": "YAML → JSON​",
    "json_to_yaml": "JSON → YAML​",
    "parse_failed": "Échec de l'analyse"
  },
  "toml_json": {
    "warning": "TOML Les types de date correspondent aux formulaires compatibles JSON ; ne collez pas de grandes configurations non fiables.",
    "toml_to_json": "TOML → JSON​",
    "json_to_toml": "JSON → TOML​",
    "parse_failed": "Échec de l'analyse"
  },
  "json_csv": {
    "json_label": "JSON (tableau d'objets)",
    "csv_label": "CSV (ligne d'en-tête)",
    "json_to_csv": "JSON → CSV​",
    "csv_to_json": "CSV → JSON​",
    "need_object_array": "JSON doit être un tableau d'objets.",
    "parse_failed": "Échec de l'analyse"
  },
  "jsonpath": {
    "expr_label": "Expression JSONPath",
    "hint": "Propulsé par jsonpath-plus (jq-like en partie).",
    "query": "Requête",
    "result_array": "Résultat (tableau)",
    "fail": "Échec"
  },
  "json_to_ts": {
    "root_name": "Nom de l'interface racine",
    "generate": "Types de génération",
    "typescript": "TypeScript​",
    "fail": "Échec"
  },
  "jmespath": {
    "expr_label": "Expression JMESPath",
    "hint": "Même JMESPath que l'AWS CLI / certains SDK ; enveloppez les littéraux JSON dans des backticks, par exemple",
    "query": "Requête",
    "result": "Résultat",
    "fail": "Échec"
  },
  "sql_format": {
    "dialect": "Dialecte",
    "dialect_sql": "SQL standard​",
    "beautify": "Embellir",
    "compress": "Compresser",
    "output": "Sortie",
    "format_failed": "Échec du format"
  },
  "gitignore": {
    "templates": "Modèles",
    "merge": "Fusion",
    "placeholder": "Mergé .gitignore",
    "copy": "Copier"
  },
  "compress": {
    "warn": "Utilise CompressionStream ; Brotli dépend du navigateur. La sortie est en base64 octets.",
    "algo": "Algorithme",
    "mode_compress": "Compresser",
    "mode_decompress": "Décompresser",
    "utf8_text": "Texte UTF-8",
    "run_text_compress": "Compresser le texte",
    "run_text_decompress": "Décompresser (attend le texte UTF-8)",
    "file_label": "Ou fichier (octets bruts)",
    "file_title": "Choisir fichier",
    "file_desc": "Compresser/décompresser binaire.",
    "b64_label": "Résultat / entrée Base64",
    "copy_b64": "Copier Base64",
    "from_b64_compress": "Depuis Base64 → compresser",
    "from_b64_decompress": "Depuis Base64 → décompresser",
    "unsupported_algo": "Cet algorithme n'est pas pris en charge ; essayez Chrome/Edge ou gzip/deflate.",
    "done_bytes": "Terminé ({n} octets)",
    "fail": "Échec",
    "b64_invalid": "Base64 invalide"
  },
  "cron": {
    "label": "Cron (min heure jour mois dow)",
    "hint": "Texte humain via cronstrue ; expr complexe suit la bibliothèque.",
    "natural_language": "Langage naturel",
    "cannot_parse": "Impossible d'analyser cette expression."
  },
  "chmod": {
    "oct_label": "Octal (par exemple 644, 755)",
    "to_rwx": "→ rwx​",
    "rwx_label": "rwxrwxrwx​",
    "to_octal": "→ octal​",
    "err_oct_range": "Octal doit être compris entre 0 et 777.",
    "err_rwx": "rwx doit être composé de 9 caractères de r w x - (setuid simplifié)."
  },
  "cidr": {
    "label": "IPv4 / CIDR​",
    "calc": "Calculer",
    "err": "Erreur",
    "network": "Réseau",
    "broadcast": "Diffusion",
    "mask": "Masque de sous-réseau",
    "first_host": "Premier hôte",
    "last_host": "Dernier hôte",
    "total_addrs": "Nombre total d'adresses",
    "usable_hosts": "Hôtes utilisables (/31,/32 simplifié)"
  },
  "ipv6": {
    "label": "Adresse IPv6 ou CIDR",
    "parse": "Analyser",
    "err": "Erreur",
    "correct_form": "Normalisé (forme correcte)",
    "canonical_form": "Développement complet (forme canonique)",
    "prefix_len": "Longueur du préfixe",
    "subnet_start": "Début du sous-réseau",
    "subnet_end": "Fin du sous-réseau",
    "addr_count": "Nombre d'adresses"
  },
  "ieee754": {
    "label": "Nombre (décimal)",
    "need_finite": "Entrez un nombre fini nombre.",
    "float64": "Float64​",
    "float32": "Float32​",
    "hex_be": "Hex (big-endian)​",
    "detail_64": "signe {sign} · exp {exp} (biais 1023) · frac {frac}",
    "detail_32": "signe {sign} · exp {exp} (biais 127) · frac {frac}"
  },
  "num_base": {
    "from_radix": "Base source (2–36)",
    "digits": "Chiffres",
    "convert": "Convertir",
    "common_bases": "Bases communes",
    "parse_err": "Impossible d'analyser entier pour cette base."
  },
  "iban": {
    "label": "IBAN (espaces ok)",
    "check": "Vérification mod 97",
    "ok": "Somme de contrôle OK (mod 97 = 1). Normalisé : {n}",
    "bad": "Échec de la somme de contrôle (reste {r}). Normalisé : {n}"
  },
  "luhn": {
    "label": "Chiffres (espaces ok)",
    "check": "Vérification Luhn",
    "pass": "Luhn valide (mod 10)",
    "fail": "Échec"
  },
  "phone": {
    "default_country": "Pays par défaut (ISO 3166-1 alpha-2 ; utilisé sans +)",
    "number": "Numéro de téléphone",
    "parse": "Analyser",
    "unparsed": "Impossible d'analyser (essayez de changer le pays par défaut).",
    "err": "Erreur",
    "line_e164": "E.164 : {v}",
    "line_intl": "International : {v}",
    "line_nat": "National : {v}",
    "line_country": "Pays : {c} (par défaut {d})",
    "line_type": "Tapez : {v}",
    "line_valid": "Valide : {v}",
    "yes": "Oui",
    "no": "Non",
    "dash": "—​"
  },
  "letter_codes": {
    "input": "Entrée (A – Z, 0–9 ; utilisez / pour l'espace en Morse)",
    "nato": "alphabet OTAN",
    "morse": "Code Morse",
    "braille": "Braille (A à Z, chiffres)"
  },
  "barcode": {
    "format": "Format​",
    "content": "Contenu (longueur/jeu de caractères valide par symbologie)",
    "download_png": "Télécharger PNG",
    "cannot_generate": "Impossible de générer"
  },
  "video_common": {
    "intro": "Le noyau ffmpeg (~ 30 Mo) se charge après avoir sélectionné un fichier multimédia. Le traitement reste dans votre navigateur ; rien n'est téléchargé. {mb} Mo maximum recommandé par fichier.",
    "core_loading": "Chargement du processeur vidéo…",
    "core_reload": "Recharger le composant",
    "load_btn_loading": "Chargement…",
    "load_btn_ready": "Noyau prêt",
    "load_btn_idle": "Charger le noyau ffmpeg",
    "media_file": "Fichier vidéo ou audio",
    "no_file": "Aucun fichier sélectionné.",
    "converting": "Traitement…",
    "download": "Télécharger {name}",
    "log": "Enregistrer",
    "load_failed": "Échec du chargement du noyau ffmpeg. Vérifiez votre réseau et réessayez.",
    "load_failed_wasm": "ffmpeg-core.wasm (~ 32 Mo) ne s'est pas chargé. Essayez de désactiver le proxy/VPN ou de changer de réseau.",
    "ffmpeg_exit": "ffmpeg s'est terminé avec le code {c}. Essayez d'abord un autre format de sortie ou Video Compress.",
    "convert_failed": "Échec du traitement",
    "progress": "Environ {n} %",
    "err_file_too_large": "Le fichier dépasse la limite de {mb} Mo. Coupez ou compressez d’abord."
  },
  "video_convert": {
    "page_intro": "Convertissez entre MP4, WebM, MKV, GIF, M4A, WAV et plus encore. Certains codecs sont limités en wasm ; essayez une autre sortie ou utilisez d'abord Video Compress.",
    "out_ext": "Format de sortie",
    "convert_go": "Démarrer la conversion"
  },
  "video_to_mp4": {
    "page_intro": "Exporter vers MP4 (H.264/AAC choisi par ffmpeg). Idéal pour le partage et la lecture mobile. En cas d'échec, essayez d'abord Video Compress pour réencoder."
  },
  "video_mov_to_mp4": {
    "page_intro": "Convertissez QuickTime / iPhone MOV en MP4. D'autres entrées vidéo sont également acceptées ; la sortie est toujours MP4."
  },
  "video_mkv_to_mp4": {
    "page_intro": "Convertissez Matroska (.mkv) en MP4 pour les lecteurs qui ne prennent pas en charge MKV. La sortie est toujours MP4."
  },
  "video_webm_to_mp4": {
    "page_intro": "Convertissez les enregistrements d'écran ou les téléchargements WebM en MP4. La sortie est toujours MP4."
  },
  "video_avi_to_mp4": {
    "page_intro": "Convertissez l'ancien AVI en MP4. La sortie est toujours MP4 ; les codecs très anciens peuvent devoir d'abord être compressés/réencodés."
  },
  "video_to_webm": {
    "page_intro": "Exporter WebM (VP8/VP9 + Opus/Vorbis). Idéal pour les intégrations Web ; la prise en charge de la lecture varie selon l'appareil."
  },
  "video_to_mkv": {
    "page_intro": "Exporter le conteneur MKV. Utile pour l'archivage ; MP4 est généralement meilleur pour le partage."
  },
  "video_trim": {
    "page_intro": "Coupe par heure de début/fin en secondes. Rapide = copie de flux (rapide, alignée sur les images clés) ; Précis = réencoder (coupes plus lentes et plus serrées).",
    "duration_label": "Durée ≈ {sec} s",
    "start_sec": "Début(s)",
    "end_sec": "Fin(s)",
    "mode_label": "Mode​",
    "mode_copy": "Rapide (copie de flux)",
    "mode_encode": "Précis (réencodage)",
    "trim_go": "Découper et télécharger"
  },
  "video_compress": {
    "page_intro": "Réduisez la taille du fichier en réduisant la résolution et en augmentant le CRF (plus élevé = plus petit, qualité inférieure ; typique 23-32).",
    "height_label": "Hauteur maximale",
    "height_option": "{h}p​",
    "crf_label": "CRF (maintenant {crf})",
    "crf_hint": "CRF plus élevé = compression plus forte.",
    "compress_go": "Compresser et télécharger"
  },
  "video_to_gif": {
    "page_intro": "Convertissez la vidéo en GIF. FPS/largeur plus élevés = fichiers plus gros et exécutions plus lentes.",
    "fps_label": "FPS​",
    "width_label": "Largeur (px)",
    "convert_go": "Créer un GIF"
  },
  "video_extract_audio": {
    "page_intro": "Supprimez la piste audio de la vidéo. M4A est plus petit ; WAV n'est pas compressé.",
    "format_label": "Format de sortie",
    "format_m4a": "M4A (AAC)​",
    "format_wav": "WAV (PCM)​",
    "format_hint": "L'encodage MP3 peut être indisponible dans wasm ; préférez M4A.",
    "extract_go": "Extraire l'audio"
  },
  "x509_view": {
    "intro": "Collez PEM (avec BEGIN/END) ou DER Base64 ; Empreinte digitale SHA-256 via Web Crypto, local uniquement.",
    "cert": "Certificat",
    "parse": "Analyser",
    "parsing": "Analyse…",
    "fingerprint": "Empreinte digitale SHA-256 (hexadécimale)",
    "structured": "Informations structurées",
    "parse_failed": "Échec de l'analyse"
  },
  "jwt": {
    "warning": "Décode Base64URL et formate JSON uniquement. <strong>La signature n'est pas vérifiée</strong> – pas pour les décisions d'authentification. Ne collez pas de jetons sensibles dans des environnements non fiables.",
    "input_label": "Chaîne JWT",
    "decode": "Décoder",
    "err_empty": "Entrez un JWT.",
    "err_parts": "Besoin d'au moins header.payload.",
    "err_header_json": "L'en-tête n'est pas un JSON valide.",
    "err_payload_json": "La charge utile n'est pas un JSON valide."
  },
  "base64": {
    "text_label": "Texte",
    "text_to_base64": "Texte → Base64",
    "base64_to_text": "Base64 → Texte",
    "base64_field": "Base64​",
    "base64_from_file": "Base64 à partir du fichier",
    "select_or_drop_file": "Sélectionner ou déposer un fichier",
    "base64_from_file_desc": "Octets bruts codés ; non téléchargé.",
    "url_safe": "URL-safe (Base64URL)​",
    "data_url": "Sortie sous forme d'URL de données",
    "encoded_file": "Encodé : {name}",
    "copy": "Copier",
    "copied": "Copié.",
    "base64_to_download": "Décoder pour télécharger",
    "decode_failed": "Échec du décodage"
  },
  "base32": {
    "original_utf8": "Original (UTF-8)​",
    "text_to_base32": "Texte → Base32",
    "base32_to_text": "Base32 → Texte",
    "base32_rfc4648": "Base32 (RFC 4648, sans remplissage)",
    "copy": "Copier",
    "copied_base32": "Copié Base32.",
    "decode_failed": "Échec du décodage"
  },
  "base58": {
    "text_utf8": "Texte (UTF-8)",
    "text_to_base58": "Texte → Base58",
    "base58_to_text": "Base58 → Texte",
    "base58_field": "Base58​",
    "decode_failed": "Échec du décodage"
  },
  "url_encode": {
    "input": "Entrée",
    "output": "Sortie",
    "encode": "Encoder",
    "decode": "Décoder",
    "copy_output": "Copier la sortie",
    "copied": "Copié.",
    "decode_failed": "Échec du décodage"
  },
  "hex": {
    "text_utf8": "Texte (UTF-8)",
    "text_to_hex": "Texte → Hex",
    "hex_to_text": "Hex → Texte",
    "hex_field": "Hex (les espaces, les nouvelles lignes et les 0x sont supprimés lors du décodage)",
    "copy": "Copier",
    "copied_hex": "Hex copié.",
    "err_hex_odd_length": "La longueur de l'hexagone doit être paire (espaces et 0x ignorés).",
    "err_utf8_decode": "Impossible de décoder en tant qu'entités UTF-8"
  },
  "escape": {
    "mode": "Mode​",
    "html_entity_mode": "HTML",
    "json_string_mode": "Échappement de chaîne JSON",
    "input": "Entrée",
    "encode_or_escape": "Encoder/échapper",
    "decode_or_restore": "Décoder/restaurer",
    "json_decode_not_string": "La valeur JSON n'est pas une chaîne.",
    "decode_failed": "Échec du décodage",
    "output": "Sortie",
    "copied_output": "Sortie copiée.",
    "copy_output": "Copier la sortie",
    "failed": "Échec",
    "page_intro": "Comme les outils d'échappement/d'entité courants : HTML utilise des entités de caractères de base ; Le mode JSON échappe aux chaînes analysables par <jp>JSON.parse</jp>."
  },
  "hash": {
    "select_file": "Sélectionnez le fichier",
    "select_or_drop_file": "Sélectionner ou déposer un fichier",
    "hash_local_desc": "Digest calculé localement ; non téléchargé.",
    "please_select_file": "Veuillez d'abord sélectionner un fichier.",
    "computing": "Informatique…",
    "compute_digest": "Résumé du calcul",
    "copy": "Copier",
    "computed_file": "Calculé : {name} ({size} octets)",
    "compute_failed": "Échec du calcul",
    "md5_label": "MD5​",
    "sha256_label": "SHA-256​",
    "dash": "—​"
  },
  "hmac": {
    "hash_algorithm": "Algorithme de hachage",
    "secret_key": "Clé secrète",
    "message": "Message​",
    "compute_hmac_hex": "Calcul HMAC (hex)",
    "output": "Sortie",
    "copy": "Copier",
    "failed": "Échec",
    "dash": "—​"
  },
  "aes": {
    "aes_pbkdf2_note": "AES-256-GCM : sel aléatoire + PBKDF2 ({iter} itérations, SHA-256) dérive la clé dans votre navigateur uniquement.",
    "passphrase": "Phrase secrète",
    "plaintext": "Texte brut",
    "encrypt": "Crypter",
    "decrypt": "Déchiffrer",
    "processing": "Traitement…",
    "please_input_passphrase": "Veuillez saisir une phrase secrète.",
    "encrypt_success": "Chiffré.",
    "encrypt_failed": "Échec du chiffrement",
    "cipher_base64": "Texte chiffré (Base64 : données salt ∥ IV ∥)",
    "cipher_too_short": "Le texte chiffré est trop court ou corrompu.",
    "decrypt_success": "Déchiffré.",
    "decrypt_failed_bad_key": "Échec du déchiffrement (phrase secrète incorrecte ou données incorrectes).",
    "copied_cipher": "Texte chiffré copié.",
    "copy_cipher": "Copier le texte chiffré"
  },
  "password": {
    "select_charset": "Sélectionnez au moins un jeu de caractères.",
    "length_4_to_256": "Longueur (4–256)",
    "upper_az": "Majuscules A–Z",
    "lower_az": "Minuscules a–z",
    "digits": "Chiffres",
    "symbols": "Symboles",
    "generate": "Générer",
    "copy": "Copier",
    "copied": "Copié.",
    "result": "Résultat",
    "placeholder_click_generate": "Cliquez sur Générer",
    "footnote": "Utilise crypto.getRandomValues ; le jeu de symboles est un petit sous-ensemble convivial : cochez les cases selon vos besoins."
  },
  "crc32": {
    "text_utf8": "Texte (UTF-8)",
    "compute_crc32": "Calculez CRC32",
    "label_from_file": "Ou à partir du fichier",
    "title_drop": "Sélectionner ou déposer un fichier",
    "desc_local": "IEEE CRC-32 sur des octets bruts ; non téléchargé.",
    "crc32_title": "CRC32​",
    "label_current_text": "texte actuel",
    "copy_hex": "Copier hexadécimal",
    "copied_hex_value": "Valeur hexadécimale copiée.",
    "msg_computed": "Calcul : {label} ({bytes} octets)",
    "read_failed": "Échec de lecture",
    "decode_failed": "Échec",
    "dash": "—​"
  },
  "xor": {
    "warning": "XOR est symétrique et n'offre aucune authentification : ne l'utilisez pas pour un véritable secret ; très bien pour les CTF, les démos ou l'obscurcissement léger.",
    "encrypt_section": "Crypter",
    "decrypt_section": "Déchiffrer",
    "plaintext_utf8": "Texte brut (UTF-8)",
    "key_utf8_cyclic": "Clé (UTF-8, répétée)",
    "output_format": "Format de sortie",
    "opt_hex": "Hex​",
    "opt_b64": "Base64​",
    "xor_to_cipher": "XOR → texte chiffré",
    "cipher_label": "Texte chiffré",
    "cipher_input_label": "Texte chiffré ({mode})",
    "xor_to_plain": "XOR → texte brut",
    "plaintext_result": "Texte brut",
    "err_key_empty": "La clé ne peut pas être vide",
    "err_hex_odd": "La longueur hexadécimale doit être paire",
    "failed": "Échec"
  },
  "vigenere": {
    "intro": "Vigenère : seuls A–Z / a–z sont transformés ; les autres personnages sont conservés. Les non-lettres de la clé sont ignorées.",
    "text": "Texte",
    "key_english": "Clé (lettres)",
    "encrypt": "Crypter",
    "decrypt": "Déchiffrer",
    "result": "Résultat",
    "err_key_letters": "La clé doit contenir au moins une lettre de A à Z",
    "error_generic": "Erreur"
  },
  "rsa": {
    "intro": "Utilise le navigateur <link>Web Crypto</link> RSA-OAEP ; uniquement pour les messages courts ou l'encapsulation de clés symétriques. Nécessite un contexte sécurisé (HTTPS ou localhost).",
    "generate_keypair": "Générer une paire de clés",
    "pub_pem": "Clé publique (SPKI PEM)",
    "priv_pem": "Clé privée (PKCS#8 PEM)",
    "encrypt_section": "Crypter",
    "plaintext_utf8": "Texte brut (UTF-8)",
    "encrypt_public": "Chiffrer avec une clé publique",
    "cipher_section": "Texte chiffré et décryptage",
    "cipher_b64": "Texte chiffré (Base64)",
    "decrypt_private": "Décrypter avec une clé privée",
    "decrypted": "Décrypté",
    "msg_generated": "RSA-OAEP 2048 bits généré (SHA-256) ; la clé privée reste uniquement en mémoire ; ne la partagez pas.",
    "msg_generate_fail": "La génération a échoué (certains environnements nécessitent un contexte sécurisé : HTTPS ou localhost).",
    "err_need_public_pem": "Générez ou collez d'abord la clé publique PEM.",
    "err_plain_too_long": "Texte en clair trop long : RSA-OAEP (2048 / SHA-256) fait généralement moins d'environ {max} octets ; actuel {current}. Utilisez un chiffrement symétrique (par exemple AES-256-GCM) pour envelopper les clés.",
    "encrypt_failed": "Échec du chiffrement",
    "err_need_private_pem": "Générez ou collez d'abord la clé privée PEM.",
    "decrypt_failed": "Échec du décryptage",
    "err_pem_parse": "Impossible d'analyser PEM ; vérifiez les blocs BEGIN/END."
  },
  "qr_generate": {
    "content_label": "Contenu (texte / URL / Wi‑Fi)",
    "size_px": "Taille (px)",
    "margin": "Marge",
    "foreground": "Premier plan",
    "background": "Arrière-plan",
    "generate_preview": "Générer un aperçu",
    "busy": "Générateur…",
    "download_png": "Télécharger PNG",
    "preview": "Aperçu",
    "qr_alt": "Code QR",
    "err_empty": "Le contenu ne peut pas être vide",
    "err_generate": "La génération a échoué",
    "error_correction": "Correction d'erreur",
    "low_contrast": "Le contraste du premier plan et de l’arrière-plan est faible ; certains scanners peuvent ne pas reconnaître le code.",
    "live_preview": "Aperçu en direct",
    "templates": "Modèles",
    "template_url": "URL​",
    "template_wifi": "Wi-Fi",
    "template_email": "E-mail",
    "template_tel": "Téléphone",
    "scan_hint": "Charge utile actuelle : {length} caractères. Le contenu plus court est analysé de manière plus fiable."
  },
  "qr_decode": {
    "drop_label": "Image avec code QR",
    "drop_title": "Sélectionnez ou déposez PNG / JPG…",
    "drop_desc": "Décodé localement avec jsQR ; non téléchargé.",
    "empty_hint": "Aucune image sélectionnée pour le moment.",
    "parse_result": "Résultat",
    "copy": "Copier",
    "err_canvas": "Canevas indisponible",
    "err_not_found": "Aucun QR trouvé (essayez une image plus claire et plus contrastée).",
    "err_decode": "Échec du décodage",
    "err_load_image": "Impossible de charger l'image",
    "dash": "—​"
  },
  "text_case": {
    "mode_label": "Transformer",
    "mode_upper": "UPPERCASE​",
    "mode_lower": "minuscule",
    "mode_title": "Cas du titre (mots)",
    "mode_sentence": "Cas de la phrase (heuristique)",
    "mode_camel": "camelCase​",
    "mode_constant": "CONSTANT_CASE​",
    "mode_kebab": "kebab-case​",
    "mode_snake": "snake_case​",
    "source": "Source​",
    "result": "Résultat",
    "copy_result": "Copier le résultat",
    "placeholder_source": "Coller ou saisir…"
  },
  "text_lines": {
    "sort_asc": "Trier les lignes (↑)",
    "sort_desc": "Trier les lignes (↓)",
    "dedupe": "Dédupliquer les lignes",
    "remove_empty": "Supprimer les lignes vides",
    "trim_lines": "Couper chaque ligne",
    "reverse": "Ordre inverse des lignes",
    "input": "Entrée",
    "result": "Résultat",
    "copy_result": "Copier le résultat",
    "placeholder_input": "Un élément par ligne ou coller une liste…",
    "placeholder_result": "Utilisez les boutons ci-dessus…"
  },
  "text_stats": {
    "label": "Texte",
    "placeholder": "Coller le contenu ; mise à jour des statistiques en direct…",
    "lines": "Lignes",
    "chars_code_units": "Caractères (unités de code)",
    "chars_no_ws": "Caractères (pas d'espaces)",
    "words_ws": "Mots (séparation des espaces)",
    "graphemes": "Groupes de graphèmes (Intl, environ « caractères »)",
    "bytes_utf8": "UTF-8 octets",
    "footnote": "« Mots » répartis en espaces ; pour CJK etc. préférez les graphèmes. Toutes les statistiques s'exécutent localement."
  },
  "text_replace": {
    "find": "Rechercher",
    "replace_with": "Remplacer par",
    "use_regex": "Utiliser une expression régulière",
    "flags": "Le mode Flags",
    "source": "Source​",
    "result": "Résultat",
    "copy": "Copier",
    "footnote": "Literal remplace toutes les correspondances globalement ; le mode regex suit String.replace – évasion mentale et drapeaux (commun : g, i, m)."
  },
  "text_split_join": {
    "delimiter": "Délimiteur",
    "placeholder_delimiter": "par ex. , ou | ou personnalisé",
    "split_lines": "Split → un élément par ligne",
    "join_lines": "Join ← lignes avec délimiteur",
    "copy_result": "Copier le résultat",
    "help": "Split : coupe le texte par délimiteur en lignes. Joindre : lire l'entrée ligne par ligne et insérer le délimiteur entre les lignes.",
    "placeholder_input": "Split : coller une ligne séparée par des virgules ; Rejoindre : un élément par ligne…",
    "placeholder_output": "Cliquez sur diviser ou rejoindre…",
    "input": "Entrée",
    "output": "Sortie"
  },
  "text_regex": {
    "warn_truncated": "Seuls les premiers caractères {max} sont mis en correspondance et mis en surbrillance.",
    "pattern": "Modèle",
    "flags": "Le mode Flags",
    "flags_ph": "gimsuy​",
    "invalid": "Expression régulière invalide",
    "text": "Texte",
    "match_count": "{count} correspondance(s)",
    "list_omitted": "… autres correspondances omises"
  },
  "text_diff": {
    "text_a": "Texte A",
    "text_b": "Texte B",
    "line_diff": "Ligne diff"
  },
  "text_lorem": {
    "paragraphs": "Paragraphes (1 à 50)",
    "generate": "Générer",
    "copy": "Copier",
    "placeholder": "Cliquez sur Générer"
  },
  "text_rot13": {
    "label": "Texte (A à Z pivote de 13 ; réexécutez pour annuler)",
    "action": "ROT13​"
  },
  "text_strip_html": {
    "warning": "Utilise DOMParser pour les nœuds de texte ; les scripts ne sont pas exécutés ; évitez néanmoins de coller d'énormes fichiers HTML non fiables.",
    "html": "HTML​",
    "plain": "Texte brut",
    "extract": "Extraire le texte brut",
    "placeholder_out": "Utilisez le bouton de gauche"
  },
  "text_slug": {
    "input": "Entrée",
    "generate": "Générer des slug",
    "hint": "Supprimez les signes diacritiques, conservez a–z et 0–9, transformez les espaces/symboles en traits d'union (assistant de slug d'URL, pas de référencement complet).",
    "result": "Résultat",
    "copy": "Copier",
    "dash": "—​"
  },
  "text_indent": {
    "text": "Texte",
    "use_tab": "Retrait avec tabulation",
    "spaces_per_level": "Espaces par niveau",
    "dedent_times": "Passes de retrait",
    "indent_once": "Retrait du bloc entier",
    "dedent_tab": "Supprimez jusqu'à {n} tabulation(s) de début par ligne",
    "dedent_space": "Supprimez jusqu'à {n} espace(s) de début par ligne",
    "skip_blank": "Sauter les lignes vides",
    "copy": "Copier le résultat",
    "example": "Exemple",
    "clear": "Effacer",
    "copied": "Copié dans le presse-papiers."
  },
  "text_sort_lines": {
    "label": "Tri des lignes",
    "desc": "Décroissant",
    "natural": "Tri naturel (numérique)",
    "trim_end": "Coupe la fin de la ligne avant le tri",
    "sort": "Tri",
    "page_intro": "Comprend le tri lors du nettoyage des lignes : basculer entre ordre croissant/décroissant et activer le mode numérique compatible <lc>localeCompare</lc> – idéal pour les numéros de version et les listes de fichiers."
  },
  "text_line_numbers": {
    "text": "Texte",
    "start": "Numéro de départ",
    "pad_width": "Largeur minimale",
    "separator": "Séparateur",
    "add": "Ajouter des numéros de ligne",
    "strip": "Strip simple préfixe « numéro | » ",
    "footnote": "Strip utilise une expression régulière simple pour les premiers chiffres et « | » ; modifier manuellement pour les cas complexes."
  },
  "text_wrap": {
    "note": "La largeur compte les unités de code UTF-16 – pas les colonnes terminales ni le CJK pleine largeur ; activer/désactiver la coupure stricte pour les longues lignes ininterrompues.",
    "text": "Texte",
    "max_width": "Caractères maximum par ligne",
    "break_long": "Casser les lignes longues sans espaces",
    "rewrap": "Réenrouler sur place"
  },
  "csv_markdown": {
    "csv_to_md": "CSV → Markdown​",
    "to_markdown": "Vers le tableau Markdown",
    "md_to_csv": "Tableau Markdown → CSV",
    "to_csv": "Vers CSV",
    "failed": "Échec"
  },
  "fullwidth": {
    "source": "Texte",
    "to_full": "Vers pleine largeur",
    "to_half": "Vers demi-largeur",
    "footnote": "Couvre l'ASCII et l'espace imprimables ; CJK etc. inchangé."
  },
  "rmb_daxie": {
    "convert": "Convertir",
    "placeholder": "1234.56​",
    "error": "Erreur"
  },
  "ics": {
    "raw_label": "Texte iCalendar",
    "parse": "Analyser",
    "no_events": "Aucun VEVENT analysé",
    "parse_failed": "Échec de l'analyse",
    "no_title": "(Aucun titre)",
    "start": "Début",
    "end": "Fin",
    "location": "Emplacement",
    "dash": "—​"
  },
  "vcard": {
    "raw_label": "Texte de la carte",
    "th_field": "Champ",
    "th_value": "Valeur",
    "empty": "Aucune ligne valide"
  },
  "email_headers": {
    "raw_label": "En-têtes bruts (jusqu'à la première ligne vide)",
    "th_name": "Nom",
    "th_value": "Valeur",
    "empty": "Rien d'analysé"
  },
  "docmind": {
    "privacy_title": "Avis de conversion Cloud",
    "privacy_body": "Les fichiers sont envoyés via le convertisseur de ce site vers Alibaba Cloud Document Mind (Chine continentale). Ne téléchargez pas de données personnelles sensibles. Les liens de téléchargement d'Alibaba sont généralement valides pendant environ 24 heures.",
    "err_no_file": "Choisissez d'abord un fichier PDF.",
    "err_file_too_large": "Le fichier ne doit pas dépasser {max} Mo.",
    "err_too_many_files": "Un seul fichier PDF par conversion.",
    "err_failed": "Échec de la conversion",
    "err_no_download_url": "Conversion terminée mais aucune URL de téléchargement n'a été renvoyée. Réessayez.",
    "err_proxy_unreachable": "Impossible d'accéder au service de conversion ({base}). Démarrez le proxy docmind et définissez NEXT_PUBLIC_DOCMIND_API_URL.",
    "msg_submitting": "Soumission du travail de conversion…",
    "msg_processing": "Traitement dans le cloud ; cela peut prendre de quelques dizaines de secondes à quelques minutes…",
    "msg_done": "Conversion terminée. Téléchargez à partir de la liste ci-dessous.",
    "result_title": "Résultats des conversions",
    "download_hint": "Les liens sont fournis par Alibaba Cloud et sont généralement valables environ 24 heures. Si l'enregistrement échoue, ouvrez le lien dans un nouvel onglet.",
    "selected_file": "Sélectionné : {name} (~{size} Mo)",
    "poll_hint": "Interrogé {count} heure(s), vérification toutes les 10 secondes environ",
    "limits_note": "Limites : un PDF par travail, maximum 5 Mo, maximum 10 pages"
  },
  "pdf_to_word": {
    "drop_label": "Choisissez PDF",
    "drop_desc": "Un PDF par travail, maximum 5 Mo ; convertit en Word (.docx) via Alibaba Document Mind.",
    "empty_hint": "Aucun fichier sélectionné pour l'instant.",
    "btn_convert": "Convertir",
    "before_title": "Vérifiez l'adéquation de la conversion avant de télécharger",
    "before_body": "PDF to Word télécharge le fichier vers un service d'intelligence documentaire pour la reconnaissance de la mise en page. Il est idéal pour les contrats modifiables, les rapports, les documents bureautiques et les analyses claires. Confirmez vos règles de conformité avant de télécharger des fichiers sensibles.",
    "good_for": "Bon pour",
    "good_contract": "Contrats, avis, manuels et documents nécessitant une modification",
    "good_report": "Rapports avec des titres, des paragraphes, des images et des tableaux simples",
    "good_scan": "Effacer les PDF numérisés ou les PDF photo nécessitant une OCR",
    "not_for": "Pas idéal pour",
    "not_sensitive": "les pièces d'identité, les cartes bancaires, les contrats confidentiels ou les fichiers qui ne doivent pas être téléchargés",
    "not_large": "Les PDF de plus de 5 Mo ou trop de pages",
    "not_table": "Les PDF contenant beaucoup de tableaux ; utiliser plutôt PDF vers Excel",
    "fail_title": "Échec ou qualité médiocre ?",
    "try_compress": "Compresser d'abord",
    "try_split": "Diviser d'abord",
    "try_excel": "Vers Excel"
  },
  "pdf_to_excel": {
    "drop_label": "Choisissez PDF",
    "drop_desc": "Un PDF par tâche, maximum 5 Mo ; convertit en Excel (.xlsx) via Alibaba Document Mind.",
    "empty_hint": "Aucun fichier sélectionné pour l'instant.",
    "btn_convert": "Convertir"
  },
  "pdf_merge": {
    "drop_label": "Choisissez les PDF (fusionnés dans l'ordre de la liste ; ajoutez plusieurs fois)",
    "drop_desc": "Sélection multiple prise en charge ; l'ordre suit la liste ci-dessous ; faites glisser à nouveau pour ajouter.",
    "err_need_two": "Sélectionnez au moins 2 fichiers PDF.",
    "msg_done": "Téléchargement terminé.",
    "err_failed": "Échec de la fusion",
    "empty_hint": "Aucun fichier sélectionné pour l'instant.",
    "btn_merge_download": "Fusionner et télécharger",
    "download_name": "merged.pdf​",
    "move_up": "Monter",
    "move_down": "Descendre"
  },
  "pdf_batch": {
    "phase2_title": "Phase 2 : file d'attente par lots + rendu Worker (si pris en charge)",
    "phase2_body": "Si OffscreenCanvas est pris en charge, la rastérisation s’exécute dans un Worker pour réduire les saccades de l’interface ; sinon, elle revient au thread principal par tranches.",
    "drop_label": "Ajouter des PDF à la file d'attente (sélection multiple, faites glisser plusieurs fois)",
    "drop_desc": "Les fichiers non PDF sont filtrés. Les tâches apparaissent dans la liste ci-dessous.",
    "err_no_pdf": "Aucun fichier PDF détecté.",
    "err_no_pending": "Aucune tâche en attente (les éléments terminés ne sont pas réexportés).",
    "log_started": "Démarrage de l'exportation par lots…",
    "err_cancelled": "Annulé",
    "err_failed_msg": "Le lot a échoué",
    "log_done_zip": "Téléchargement ZIP emballé terminé.",
    "scale_label": "Échelle d’exportation (le lot suggère 1,4 – 2,2)",
    "fmt_label": "Format d'exportation",
    "quality_label": "Qualité (0,1 – 1,0)",
    "status_prefix": "Statut:",
    "status_pending": "en attente",
    "status_running": "en cours d'exécution",
    "status_done": "fait",
    "status_error": "erreur",
    "btn_remove": "Retirer",
    "queue_empty": "La file d'attente est vide.",
    "btn_export_all": "Tout exporter ({n} en attente)",
    "btn_processing": "Fonctionnement…",
    "btn_cancel": "Annuler",
    "btn_clear_queue": "Effacer la file d'attente",
    "log_page_progress": "{file} : {current}/{total}"
  },
  "pdf_compress": {
    "notice_title": "Stratégie de compression (transparente)",
    "notice_body": "Compression raster : chaque page est rendue en JPG puis reconstruite en PDF. Fonctionne surtout pour les scans ; les PDF contenant du texte peuvent grossir ou paraître moins nets.",
    "drop_label": "Choisissez PDF",
    "drop_desc": "Remballez localement dans le navigateur pour réduire la taille ; rien n'est téléchargé.",
    "compress_desc": "Repack de streaming local pour réduire la taille ; non téléchargé.",
    "empty_pdf": "Aucun PDF sélectionné pour l'instant.",
    "download_name": "compressé.pdf",
    "scale_label": "Échelle de rendu (plus élevée = plus nette mais plus grande)",
    "quality_label": "Qualité JPG (0,1 – 1,0)",
    "btn_compress": "Démarrer la compression",
    "msg_select_first": "Choisissez d'abord un PDF.",
    "msg_done_hint": "Téléchargement terminé (remarque : les numérisations rétrécissent plus que les PDF texte).",
    "err_failed": "Échec de la compression",
    "preset": "Préréglage de compression",
    "preset_strong": "Fort (plus petit, moins de clarté)",
    "preset_balanced": "Équilibré (recommandé)",
    "preset_quality": "Haute qualité (fichier plus volumineux)",
    "before": "Avant",
    "after": "Après",
    "change": "Changement de taille",
    "smaller": "Compression terminée. Vérifiez la clarté avant de télécharger.",
    "larger": "Le résultat est plus grand que l'original. Conservez l'original ou essayez un préréglage plus puissant.",
    "preset_card_strong": "Le plus petit fichier",
    "preset_card_strong_desc": "Idéal pour les numérisations, les photos PDF et le partage en lecture seule.",
    "preset_card_balanced": "Équilibré",
    "preset_card_balanced_desc": "Bon défaut pour la plupart des pièces jointes.",
    "preset_card_quality": "Haute qualité",
    "preset_card_quality_desc": "Idéal pour les petits textes, les graphiques ou l'impression.",
    "raster_warning": "Remarque : cet outil rastérise les pages et reconstruit le PDF. Le texte peut ne plus être sélectionnable après compression. Utilisez PDF vers Word ou Extrayez du texte si vous avez besoin de contenu modifiable.",
    "saved": "Enregistré",
    "output_size": "Taille de sortie",
    "check_quality": "Ouvrez le résultat et vérifiez la clarté du texte/image",
    "next_actions": "Continuer après la compression",
    "next_split": "Pages divisées",
    "next_merge": "Fusionner un PDF",
    "next_images": "Convertir en images"
  },
  "pdf_crop": {
    "intro": "Ajustez les marges de CropBox/MediaBox (pt). Cela modifie la région visible et les limites de la page sans supprimer le contenu vectoriel.",
    "drop_label": "Choisissez PDF",
    "drop_desc": "Le recadrage s'effectue localement. Les pages sont configurées ci-dessous.",
    "empty_pdf": "Aucun PDF sélectionné pour l'instant.",
    "left": "Marge gauche (pt)",
    "right": "Marge droite (pt)",
    "top": "Marge supérieure (pt)",
    "bottom": "Marge inférieure (pt)",
    "mode_label": "Mode de recadrage",
    "mode_crop_media": "CropBox + MediaBox (plus général)",
    "mode_crop_only": "CropBox uniquement (conservateur)",
    "btn_crop": "Recadrer et télécharger",
    "msg_select_pdf": "Choisissez d'abord un PDF.",
    "msg_pick_pages": "Sélectionner les pages à recadrer.",
    "msg_done": "Téléchargement terminé.",
    "err_failed": "Échec du recadrage",
    "download_name": "recadré.pdf"
  },
  "pdf_decrypt": {
    "notice_title": "Avis de conformité",
    "notice_body": "Uniquement pour les PDF dont vous connaissez le mot de passe. Les pages sont rastérisées et reconstruites, de sorte que le texte et les liens sélectionnables sont perdus.",
    "drop_encrypt_label": "Choisissez PDF crypté",
    "drop_desc": "Déchiffrer localement avec votre mot de passe ; les fichiers ne sont pas téléchargés.",
    "empty_pdf": "Aucun PDF sélectionné pour l'instant.",
    "password_label": "Ouvrir le mot de passe",
    "scale_label": "Échelle de rendu",
    "quality_label": "Qualité JPG (0,1 – 1,0)",
    "btn_decrypt": "Décrypter et télécharger",
    "msg_select_first": "Choisissez d'abord un PDF.",
    "msg_done": "Téléchargement terminé.",
    "err_failed": "Échec du décryptage",
    "download_name": "decrypted.pdf​"
  },
  "pdf_delete_pages": {
    "drop_label": "Choisissez PDF",
    "drop_desc": "Cliquez sur les vignettes pour supprimer ; les pages non sélectionnées restent et sont exportées vers un nouveau fichier.",
    "hint_short": "Cliquez sur les pages pour supprimer ; les pages non sélectionnées restent dans le PDF exporté.",
    "btn_delete": "Supprimez les pages sélectionnées et téléchargez",
    "empty_pdf": "Aucun PDF sélectionné pour l'instant.",
    "msg_select_pdf": "Choisissez d'abord un PDF.",
    "msg_pick_delete": "Sélectionnez les pages à supprimer.",
    "msg_done": "Téléchargement terminé.",
    "err_failed": "Échec de la suppression",
    "thumb_title": "Pages à supprimer",
    "download_name": "pages-supprimées.pdf"
  },
  "pdf_extract_text": {
    "drop_label": "Choisissez PDF",
    "drop_desc": "Extraire le texte par page localement ; les numérisations peuvent ne pas avoir de calque de texte.",
    "empty_pdf": "Aucun PDF sélectionné pour l'instant.",
    "btn_extract": "Extraire le texte (txt)",
    "msg_select_pdf": "Choisissez d'abord un PDF.",
    "progress_page": "Extraction de la page {current} / {total}…",
    "msg_done_hint": "Texte exporté. Remarque : les fichiers PDF numérisés/images peuvent ne produire aucun texte.",
    "err_failed": "Échec de l'extraction"
  },
  "pdf_header_footer": {
    "intro": "Phase 2 : modèles d'en-tête et de pied de page gauche/centre/droite ; les espaces réservés '{'n'}' et '{'total'}' sont remplacés lors de l'exportation. Le texte chinois utilise le sous-ensemble Source Han Sans d'OSS ; les échecs de récupération retombent gracieusement.",
    "presets_heading": "Préréglages rapides",
    "drop_label": "Choisissez PDF",
    "drop_desc": "Appliquer localement le texte d'en-tête/pied de page par page ; prend en charge '{'n'}' / '{'total'}', etc.",
    "empty_pdf": "Aucun PDF sélectionné pour l'instant.",
    "header_left": "En-tête gauche",
    "header_center": "Centre d'en-tête",
    "header_right": "En-tête à droite",
    "footer_left": "Pied de page gauche",
    "footer_center": "Pied de page central",
    "footer_right": "Pied de page droit",
    "ph_company": "par ex. nom de l'entreprise",
    "ph_title": "par ex. titre du document",
    "ph_version": "par ex. version",
    "footer_center_ph": "Suggérée : '{'n'}' / '{'total'}'",
    "font_size": "Taille de la police",
    "margin_pt": "Marge (pt)",
    "btn_apply": "Appliquer et télécharger",
    "msg_select_pdf": "Choisissez d'abord un PDF.",
    "msg_need_field": "Remplissez au moins un emplacement d'en-tête ou de pied de page.",
    "msg_pick_pages": "Sélectionnez les pages pour le modèle.",
    "msg_done": "Téléchargement terminé.",
    "err_failed": "Échec",
    "preset_minimal_name": "Pied de page minimal (n / total)",
    "preset_internal_name": "Utilisation interne + pied de page",
    "preset_dual_name": "En-tête double + pied de page centré",
    "preset_internal_header": "Interne · Ne pas distribuer",
    "preset_internal_footer": "Page '{'n'}' / '{'total'}' pages​",
    "preset_dual_footer": "Confidentiel",
    "download_name": "en-tête-pied de page.pdf"
  },
  "images_to_pdf": {
    "intro": "PNG / JPEG pris en charge. Une image par page PDF ; la taille de la page correspond aux dimensions en pixels.",
    "drop_label": "Choisissez les images (l'ordre des pages suit la liste ; ajoutez plusieurs fois)",
    "drop_desc": "PNG et JPEG uniquement ; L'ordre de la liste est l'ordre des pages.",
    "empty_hint": "Aucun fichier sélectionné pour l'instant.",
    "btn_generate": "Créer un PDF",
    "msg_need_image": "Choisissez au moins une image.",
    "msg_done": "Téléchargement terminé.",
    "err_failed": "Échec de la génération",
    "download_name": "images-merged.pdf​"
  },
  "pdf_metadata": {
    "drop_label": "Choisissez PDF",
    "drop_desc": "Lire les propriétés communes du document ; modifier et exporter en tant que nouveau fichier.",
    "empty_pdf": "Aucun PDF sélectionné pour l'instant.",
    "label_title": "Titre",
    "label_author": "Auteur",
    "label_subject": "Sujet",
    "label_keywords": "Mots clés",
    "keywords_ph": "Séparer par des virgules",
    "label_creator": "Créateur",
    "label_producer": "Producteur (facultatif)",
    "producer_ph": "Laisser vide pour conserver le producteur",
    "label_language": "Langue existante (facultatif)",
    "language_ph": "par ex. zh-CN, en-US ; laissez vide pour ignorer Lang dans le plan",
    "checkbox_viewer_prefs": "Préférer le titre du document dans le titre de la fenêtre de la visionneuse (pdf-lib ViewerPreferences)",
    "btn_apply": "Appliquer et télécharger",
    "msg_loaded": "Métadonnées chargées ; modifier et exporter.",
    "msg_read_failed": "Échec de lecture",
    "msg_select_pdf": "Choisissez d'abord un PDF.",
    "msg_done_verify": "Métadonnées écrites et téléchargées (certaines visionneuses mettent en cache les anciennes métadonnées – renommez pour vérifier).",
    "err_export_failed": "Échec de l'exportation",
    "download_suffix": "-métadonnées",
    "page_intro": "Couvre les champs courants affichés sous les « propriétés du document » du lecteur. Les modifications écrivent un nouveau fichier localement : rien n’est téléchargé sur nos serveurs. Propulsé par <pdflib>Hopding/pdf-lib</pdflib>."
  },
  "pdf_page_numbers": {
    "intro": "Espaces réservés : '{'n'}' page actuelle, '{'total'}' pages totales. Les chaînes chinoises sont acceptables (par exemple « Page '{'n'}' » ); la police se charge à partir du sous-ensemble OSS avec solution de secours.",
    "drop_label": "Choisissez PDF",
    "drop_desc": "Ajoutez localement une numérotation de pied de page/bord de page.",
    "empty_pdf": "Aucun PDF sélectionné pour l'instant.",
    "start_number": "Numéro de départ",
    "align_label": "Alignement",
    "align_left": "Gauche",
    "align_center": "Centre",
    "align_right": "Droite",
    "format_string": "Chaîne de formatage",
    "font_size": "Taille de la police",
    "margin_x": "Marge horizontale (pt)",
    "margin_y_footer": "Relevage du pied de page (pt, plus grand = plus haut sur la page)",
    "btn_add": "Ajouter des numéros de page et télécharger",
    "msg_select_pdf": "Choisissez d'abord un PDF.",
    "msg_pick_pages": "Sélectionner les pages à numéroter.",
    "msg_done": "Téléchargement terminé.",
    "err_failed": "Échec",
    "download_name": "page-numbers.pdf​"
  },
  "pdf_reverse": {
    "drop_label": "Choisissez PDF",
    "drop_desc": "Inverser l'ordre complet des pages ; contenu inchangé.",
    "empty_pdf": "Aucun PDF sélectionné pour l'instant.",
    "btn_reverse": "Ordre inverse et téléchargement",
    "msg_select_pdf": "Choisissez d'abord un PDF.",
    "msg_done": "Téléchargement prêt.",
    "err_failed": "Échec du traitement",
    "download_suffix": "-inversé",
    "page_intro": "Utile lorsque la reliure ou l'ordre de lecture nécessite que l'intégralité du PDF soit retournée de bout en bout ; implémenté via la copie de page <pdflib>pdf-lib</pdflib> sans restituer le contenu vectoriel."
  },
  "pdf_rotate": {
    "drop_label": "Choisissez PDF",
    "drop_desc": "Choisissez des vignettes, puis ajoutez une rotation relative par page sélectionnée ; traité localement.",
    "empty_pdf": "Aucun PDF sélectionné pour l'instant.",
    "angle_label": "Rotation à appliquer (relative)",
    "btn_rotate": "Appliquer la rotation",
    "msg_select_pdf": "Choisissez d'abord un PDF.",
    "msg_pick_page": "Sélectionner au moins une page.",
    "msg_rotate_done": "Rotation terminée. Vous pouvez télécharger maintenant.",
    "msg_download_done": "Téléchargement démarré.",
    "err_failed": "Échec de la rotation",
    "thumb_title": "Pages à faire pivoter",
    "thumb_preview_hint": "Les aperçus sont uniquement des miniatures ; la qualité de l'exportation n'est pas affectée.",
    "download_name": "rotated.pdf​"
  },
  "pdf_split": {
    "drop_label": "Choisissez PDF",
    "drop_desc": "Divisé en plusieurs PDF par page ou taille de bloc fixe (téléchargement ZIP).",
    "empty_pdf": "Aucun PDF sélectionné pour l'instant.",
    "legend_mode": "Mode fractionné",
    "mode_each": "Un fichier par page",
    "mode_chunk": "Groupes de pages fixes",
    "chunk_size_label": "Pages par groupe",
    "hint_each": "Chaque page s'exporte sous forme de son propre PDF.",
    "hint_chunk": "Exportation de groupe toutes les {chunk} pages.",
    "btn_split": "Diviser et télécharger ZIP",
    "msg_select_pdf": "Choisissez d'abord un PDF.",
    "msg_done_zip": "La génération ZIP a démarré.",
    "err_failed": "Échec du fractionnement",
    "thumb_preview_title": "Preview (browse only; split follows options above)",
    "mode_selected": "Extraire les pages sélectionnées en un seul PDF",
    "hint_selected": "Cliquez sur les vignettes ci-dessous pour sélectionner les pages. Les {count} pages sélectionnées seront exportées sous forme d'un seul PDF dans l'ordre d'origine.",
    "msg_pick_pages": "Sélectionnez au moins une page parmi les vignettes ci-dessous.",
    "msg_done_pdf": "PDF de la page sélectionnée généré et le téléchargement a commencé.",
    "selected_download_name": "selected-pages.pdf​",
    "selected_count": "{count} pages sélectionnées",
    "first_page": "Sélectionner la page 1",
    "first_three": "Sélectionner en premier 3",
    "clear_selected": "Effacer la sélection"
  },
  "pdf_stamp": {
    "drop_pdf_label": "Choisissez PDF",
    "drop_pdf_desc": "Document de base ; choisissez les pages à tamponner.",
    "drop_stamp_label": "Tamponner l'image (PNG recommandé)",
    "drop_stamp_desc": "PNG ou JPEG ; Le format PNG transparent est généralement le meilleur rendu.",
    "empty_pdf": "Aucun PDF sélectionné pour l'instant.",
    "empty_stamp": "Aucune image de tampon pour l'instant.",
    "position_label": "Position​",
    "scale_label": "Échelle (par rapport à la largeur de l'image)",
    "margin_label": "Marge (pt)",
    "pos_center": "Centre",
    "pos_br": "En bas à droite",
    "pos_bl": "En bas à gauche",
    "pos_tr": "En haut à droite",
    "pos_tl": "En haut à gauche",
    "btn_apply": "Tamponner et télécharger",
    "msg_need_both": "Sélectionner à la fois un PDF et une image de tampon (PNG/JPG).",
    "msg_pick_pages": "Sélectionner les pages à tamponner.",
    "msg_done": "Téléchargement terminé.",
    "err_failed": "Échec",
    "download_name": "stamped.pdf​"
  },
  "pdf_to_images": {
    "hint_base": "Exporter sous forme d'images. La netteté suit l'échelle : une valeur plus élevée est plus claire, mais plus lente et plus lourde en mémoire.",
    "hint_fallback": " Le rendu hors écran n'est pas pris en charge ; certains formats reviennent au PNG.",
    "drop_label": "Choisissez PDF",
    "drop_desc": "Sélection multiple ou dépôt par lots ; chaque page devient une image dans un ZIP ; local uniquement.",
    "empty_pdf": "Aucun PDF sélectionné pour l'instant.",
    "err_no_pdf": "Aucun fichier PDF reconnu.",
    "scale_label": "Échelle de rendu (suggérer 1,5 – 3)",
    "fmt_label": "Format d'exportation",
    "opt_png": "PNG (sans perte)",
    "opt_jpeg": "JPG (plus petit)",
    "opt_webp": "WebP (plus petit)",
    "quality_label": "Qualité (0,1 – 1,0)",
    "btn_export": "Exporter (ZIP)",
    "msg_select_pdf": "Choisissez d'abord un PDF.",
    "progress_export": "Exportation de la page {current} / {total}…",
    "progress_export_multi": "Fichier {fileIndex}/{fileTotal} : {fileName} — page {current}/{total}…",
    "msg_zip_done": "Emballé sous ZIP ; le téléchargement a commencé.",
    "err_failed": "Échec de l'exportation",
    "err_cancelled": "Annulé",
    "page_range": "Plage de pages (toutes / impaires / paires / 1,3-5)",
    "page_range_invalid": "Plage de pages non valide. Utilisez tout, impair, pair ou une plage telle que 1,3-5."
  },
  "pdf_watermark": {
    "intro": "Filigranes de texte chinois via le sous-ensemble OSS Source Han Sans. Si la récupération des polices échoue, les polices intégrées sont utilisées et le chinois peut apparaître sous forme de cases.",
    "drop_label": "Choisissez PDF",
    "drop_desc": "Ajoutez un filigrane de texte aux pages choisies localement.",
    "empty_pdf": "Aucun PDF sélectionné pour l'instant.",
    "page_range_hint": "Astuce : tous / impair / pair / 1,3-5",
    "label_text": "Texte du filigrane",
    "label_color": "Couleur (#RRGGBB)",
    "label_font_size": "Taille de la police",
    "label_opacity": "Opacité (0–1)",
    "label_angle": "Rotation (degrés)",
    "btn_generate": "Générer et télécharger",
    "msg_select_pdf": "Choisissez d'abord un PDF.",
    "msg_pick_pages": "Sélectionner les pages à filigraner.",
    "msg_done": "Téléchargement terminé.",
    "err_failed": "Échec",
    "download_name": "watermarked.pdf​"
  },
  "json_format": {
    "indent_label": "Retrait",
    "indent_2": "2 espaces",
    "indent_4": "4 espaces",
    "indent_tab": "Tabulation",
    "font_size_label": "Taille de la police",
    "valid_ok": " ✓ Valide",
    "valid_bad": "✗ Invalide",
    "btn_escape": "Échapper / Annuler l'échappement",
    "btn_json_xml": "JSON ↔ XML​",
    "btn_fold": "Plier / Déplier",
    "hdr_src": "Source​",
    "hdr_result": "Résultat (modifiable)",
    "ph_src": "Collez ou entrez JSON ici…",
    "ph_result": "Le JSON formaté apparaît ici…",
    "flash_unescape_fmt_ok": "Non échappé et formaté avec succès",
    "flash_unescape_ok_maybe": "Non échappé (peut ne pas être un JSON valide)",
    "flash_unescape_fail": "Échec de l'échappement",
    "flash_escape_ok": "Échappé avec succès",
    "flash_escape_ok_maybe": "Échappé avec succès (la source peut ne pas être valide) JSON)",
    "flash_escape_fail": "Échec de l'échappement",
    "flash_please_data": "Veuillez d'abord saisir les données",
    "flash_xml_bad": "Échec de la conversion : XML non valide",
    "flash_json_bad": "Échec de la conversion : JSON non valide",
    "hint_xml_done": "Converti en XML",
    "hint_json_done": "Converti en JSON",
    "flash_need_json_src": "Veuillez d'abord saisir JSON dans le panneau source",
    "flash_need_valid_json": "Veuillez d'abord formater ou saisir un JSON valide",
    "hint_all_fold": "Tout plié",
    "hint_all_unfold": "Tout déplié",
    "flash_result_empty": "Le résultat est vide",
    "flash_clipboard_ok": "Copié dans le presse-papiers",
    "flash_no_download": "Rien à télécharger ",
    "confirm_plain_download": "Le contenu n'est pas un JSON valide. Télécharger quand même ?",
    "suffix_json_invalid": "JSON invalide",
    "btn_copy_result": "Copier le résultat"
  },
  "og_preview": {
    "mock_card_title": "Carte simulée (pas un véritable aperçu du robot)",
    "tag_snippet_title": "Extrait méta",
    "demo_title": "Outils Ku | Exemple",
    "demo_desc": "Exemple de description pour une carte de partage simulée localement."
  },
  "robots": {
    "chk_allow_site": "Autoriser : / (autoriser les explorations entières du site)",
    "lbl_disallow_paths": "Interdire les chemins (un par ligne)",
    "lbl_sitemap_urls": "URL du plan du site (une par ligne)",
    "hdr_preview": "robots.txt​"
  },
  "sitemap": {
    "lbl_site_root": "URL racine du site",
    "lbl_paths": "Chemins ou URL complètes (une par ligne)",
    "hdr_preview": "sitemap.xml​"
  },
  "csp": {
    "opt_default": "default-src 'self'​",
    "opt_script": "script-src 'self'​",
    "opt_unsafe_inline": "Autoriser les scripts en ligne (plus faibles)",
    "opt_style": "style-src 'self' 'unsafe-inline'​",
    "opt_img": "img-src * data:​",
    "opt_font": "font-src 'self'​",
    "opt_connect": "connect-src 'self'​",
    "opt_frame": "frame-ancetors 'aucun'",
    "opt_base": "base-uri 'soi'",
    "opt_form": "forme-action 'soi'",
    "opt_upgrade": "update-insecure-requests",
    "lbl_extra_directives": "Directives supplémentaires (une par ligne ; jointes par des points-virgules)",
    "hdr_preview": "Content-Security-Policy​",
    "placeholder_extra": "report-uri https://...​"
  },
  "permissions_policy": {
    "lbl_extra": "Entrées supplémentaires (séparées par des virgules)",
    "hdr_preview": "Permissions-Policy​",
    "placeholder_extra": "interest-cohort=()​"
  },
  "env_parse": {
    "chk_mask": "Valeurs de masque (affichage uniquement ; texte source inchangé)",
    "lbl_raw": "Contenu .env",
    "th_key": "Clé",
    "th_value": "Valeur",
    "empty_rows": "Aucune clé=valeur rows"
  },
  "http_headers": {
    "intro": "Exemples d'en-têtes de réponse de sécurité courants ; configurer une pile (Nginx / CDN / framework).",
    "hsts_title": "HSTS​",
    "hsts_desc": "Forcer HTTPS (âge maximum d'un an)",
    "xcto_title": "X-Content-Type-Options​",
    "xcto_desc": "Désactiver le reniflage MIME",
    "xfo_title": "X-Frame-Options​",
    "xfo_desc": "Refuser l'intégration (identique à DENY)",
    "ref_title": "Referrer-Policy​",
    "ref_desc": "Resserrer Referer",
    "pp_title": "Permissions-Policy (exemple)",
    "pp_desc": "Désactiver certaines API sensibles"
  },
  "graphql_format": {
    "lbl_input": "GraphQL​",
    "syntax_error": "Syntaxe erreur"
  },
  "openapi_view": {
    "lbl_input": "OpenAPI (JSON)​",
    "err_invalid_json": "Impossible d'analyser JSON",
    "root_label": "racine"
  },
  "properties_json": {
    "lbl_properties": ".properties​",
    "lbl_json": "JSON (valeurs de chaîne → propriétés)",
    "btn_to_json": "→ JSON​",
    "btn_to_properties": "→ Propriétés",
    "footnote_flat": "Les objets imbriqués ne sont pas aplatis ; uniquement les mappages de chaînes plates.",
    "err_failed": "Échec"
  },
  "xml_format": {
    "lbl_xml": "XML​",
    "btn_validate_indent": "Valider et indenter",
    "err_parse_failed": "Échec de l'analyse XML",
    "err_failed": "Échec"
  },
  "semver": {
    "lbl_a": "Version A​",
    "lbl_b": "Version B​",
    "btn_compare": "Comparer",
    "invalid": "invalide",
    "err_parse_line": "Échec de l'analyse : A={a} B={b}",
    "cmp_before": "A est avant B",
    "cmp_after": "A est après B",
    "cmp_equal": "Égal",
    "line_norm": "Normalisé : A={a} B={b}",
    "line_cmp": "Comparer : {rel}",
    "line_diff": "semver.diff : {diff}",
    "diff_same": "diff : (même version)"
  },
  "mermaid": {
    "lbl_source": "Source sirène",
    "btn_render": "Afficher",
    "btn_rendering": "Rendu…",
    "err_render": "Échec du rendu"
  },
  "editorconfig": {
    "preset_web": "Web par défaut (2 espaces)",
    "preset_py": "Python (4 espaces)",
    "preset_go": "Aller (onglet)"
  },
  "image_compress": {
    "intro_note": "Les images sont traitées localement dans votre navigateur et ne sont jamais téléchargées. La compression s'exécute en parallèle en fonction des capacités de l'appareil tout en contrôlant l'utilisation de la mémoire. PNG prend en charge la quantification intelligente visuellement sans perte ou la compression stricte au pixel près. L'original est conservé tant que le résultat n'est pas inférieur.",
    "drop_desc": "Le traitement par lots est pris en charge. Les composants de compression se réchauffent après la sélection et les dimensions de l'image restent inchangées.",
    "fmt_auto": "Identique à la source",
    "fmt_jpeg": "Unifier au format JPG",
    "fmt_webp": "Unifier en tant que WebP",
    "fmt_png": "Unifier en PNG",
    "quality_label": "Qualité de compression",
    "quality_high": "Haute qualité",
    "quality_balanced": "Recommandé (équilibré)",
    "quality_strong": "Forte compression",
    "png_mode_label": "Mode de compression PNG",
    "png_mode_smart": "Compression intelligente (recommandée)",
    "png_mode_lossless": "Sans perte stricte",
    "png_smart_hint": "Le mode intelligent fusionne des couleurs similaires et peut réduire considérablement la taille du PNG avec presque aucun changement visible, mais il n'est pas sans perte au pixel près.",
    "png_lossless_hint": "Le mode strict sans perte préserve chaque pixel et optimise uniquement l'encodage PNG, les économies sont donc généralement moindres qu'en mode intelligent.",
    "progress": "Terminé {completed} / {total}",
    "worker_hint": "Traitement en parallèle avec {count} workers en arrière-plan",
    "preparing_hint": "Préparation des composants de compression d'image…",
    "fallback_hint": "Le traitement de l'image d'arrière-plan n'est pas disponible dans ce navigateur ; le mode de compatibilité est actif",
    "cancel": "Annuler la compression",
    "cancelling": "Annulation…",
    "cancelled": "La compression a été annulée. Les résultats complets restent disponibles.",
    "completed": "{count} images terminées.",
    "size_change": "Taille totale : {before} → {after}",
    "saved": "Enregistré : {size} ({percent} %)",
    "original_kept": "Originaux conservés : {count}"
  },
  "image_exif": {
    "intro_note": "La visualisation/le dépouillement se produit localement. Le décapage réexporte l'image (plus universelle) et peut changer de taille/format.",
    "drop_desc": "Analyser EXIF ​​localement ; les fichiers ne sont pas téléchargés.",
    "empty_hint": "Aucune image sélectionnée.",
    "lbl_export_after_strip": "Format après bande",
    "opt_jpeg_rec": "JPG (recommandé)",
    "opt_png": "PNG​",
    "opt_webp": "WebP​",
    "btn_strip": "Supprimer les EXIF ​​et télécharger",
    "details_raw": "EXIF JSON brut",
    "msg_no_exif": "Aucun EXIF ​​détecté (ou le format n'en a pas).",
    "msg_read_fail": "Échec de lecture",
    "msg_exported_clean": "Version exportée sans métadonnées.",
    "msg_strip_fail": "Échec du traitement"
  },
  "image_crop": {
    "intro_note": "Faites glisser l’aperçu pour sélectionner la zone de recadrage ou saisissez les pixels ci-dessous. Le traitement est local.",
    "drop_desc": "Recadrage d’une image ; export PNG / JPG / WebP.",
    "empty_hint": "Aucune image sélectionnée.",
    "hint_canvas": "Source {w}×{h} px — faites glisser sur l'image pour sélectionner",
    "lbl_left_x": "X gauche",
    "lbl_top_y": "Haut Y",
    "lbl_width": "Largeur",
    "lbl_height": "Hauteur",
    "btn_reset_full": "Réinitialiser l'image complète",
    "lbl_quality_short": "Qualité",
    "btn_export": "Exporter le recadrage",
    "msg_pick_area": "Veuillez sélectionner une image et une zone de recadrage.",
    "msg_exported": "Recadrage exporté.",
    "msg_export_fail": "Échec de l'exportation"
  },
  "image_resize": {
    "intro_note": "Le redimensionnement s'effectue localement. contenir = s'insérer à l'intérieur avec un rembourrage ; cover = remplir et recadrer.",
    "drop_desc": "Définissez la taille et le format ci-dessous, puis cliquez sur Démarrer le traitement pour l'exportation par lots."
  },
  "image_scale": {
    "intro_note": "Mise à l'échelle proportionnelle par bord long, largeur fixe ou hauteur fixe ; rapport hauteur/largeur préservé. Le mode bord long conserve les originaux plus petits que la cible ; Les modes largeur/hauteur peuvent être mis à l’échelle. Traitement local.",
    "drop_desc": "Définissez le mode d'échelle et les pixels cibles, puis exportez par lots.",
    "lbl_scale_by": "Mise à l'échelle par",
    "mode_long_edge": "Bord long (rétrécir uniquement pour limiter)",
    "mode_width": "Largeur (largeur fixe, hauteur proportionnelle)",
    "mode_height": "Hauteur (hauteur fixe, largeur proportionnelle)",
    "dim_long_edge": "Limite du bord long (px)",
    "dim_width": "Largeur cible (px)",
    "dim_height": "Hauteur cible (px)",
    "lbl_quality_01": "Qualité (0,1–1)"
  },
  "image_transform": {
    "intro_note": "Canevas + filtres CSS (niveaux de gris/inverser) localement ; Exportation JPEG de la transparence des composites sur du blanc.",
    "drop_desc": "Formats raster courants ; définir les transformations puis l'exportation par lots.",
    "lbl_rotate": "Rotation",
    "rot_0": "Aucun",
    "rot_90": "90° dans le sens des aiguilles d'une montre",
    "rot_180": "180°​",
    "rot_270": "270° dans le sens des aiguilles d'une montre",
    "lbl_export_fmt": "Format d'exportation",
    "lbl_quality_short": "Qualité",
    "flip_h": "Retourner horizontalement",
    "flip_v": "Retourner verticalement",
    "filter_gray": "Niveaux de gris",
    "filter_invert": "Inverser",
    "msg_need_transform": "Sélectionnez au moins une transformation (rotation, retournement ou filtre).",
    "msg_summary": "Terminé : {ok}/{total} réussi.",
    "btn_zip": "Télécharger le package ZIP"
  },
  "image_watermark": {
    "intro_note": "Les filigranes sont rendus localement ; rien n'est téléchargé.",
    "drop_desc": "Définissez le filigrane du texte, puis exportez par lots.",
    "lbl_text": "Texte du filigrane",
    "lbl_position": "Position​",
    "pos_tl": "En haut à gauche",
    "pos_tr": "En haut à droite",
    "pos_bl": "En bas à gauche",
    "pos_br": "En bas à droite",
    "pos_center": "Centre",
    "lbl_color": "Couleur",
    "lbl_font_size": "Taille de la police",
    "lbl_opacity": "Opacité (0–1)",
    "lbl_padding": "Espacement (px)",
    "msg_empty_text": "Le texte du filigrane ne peut pas être vide."
  },
  "image_collage": {
    "intro_note": "La couture s'exécute localement ; évitez trop d'images (sortie très haute/large).",
    "drop_label": "Sélectionnez les images (ordre = ordre des points)",
    "drop_desc": "Sélection multiple prise en charge ; l'ordre de la liste est l'ordre des points : supprimez les éléments à ajuster.",
    "empty_hint": "Aucune image pour l'instant. L'ordre définit ici l'ordre des points.",
    "lbl_direction": "Direction​",
    "dir_vertical": "Vertical (longue bande)",
    "dir_horizontal": "Horizontal​",
    "lbl_gap": "Espace (px)",
    "msg_started": "Téléchargement démarré."
  },
  "image_convert": {
    "page_intro": "Les formats raster courants (y compris <fmt>PNG, JPEG, WebP, GIF, BMP, ICO, AVIF</fmt>, selon le décodage du navigateur) et <svg>SVG</svg> sont convertis localement. Le GIF animé exporte uniquement la première image ; les zones transparentes se remplissent de blanc lors de l'exportation au format JPEG ; HEIC et les formats similaires ne peuvent souvent pas être décodés dans le navigateur.",
    "common_uses_title": "Utilisations courantes",
    "common_use_li1": "Unifiez les ressources Web en WebP ou PNG ; flux de travail d'impression/archivage au format JPEG.",
    "common_use_li2": "Rasterisez SVG en bitmap pour des outils en aval raster uniquement."
  },
  "image_convert_to_png": {
    "page_intro": "Exportez les formats d'image courants au format PNG localement sur votre appareil : rien ne quitte votre machine. Utile lorsque vous avez besoin d’un flux de travail PNG uniquement ou que l’aval accepte uniquement PNG. Les images animées exportent la première image.",
    "common_notes_title": "Remarques",
    "common_notes_li1": "Il est possible que les formats HEIC et certains fournisseurs ne soient pas décodés dans le navigateur : convertissez-les d'abord en JPG dans votre système d'exploitation.",
    "common_notes_li2": "Les très grandes images utilisent plus de mémoire ; si la conversion échoue, redimensionnez ou divisez.",
    "drop_subline": "Entrée multiformat ; la sortie est toujours centrée sur PNG."
  },
  "image_gif_to_png": {
    "drop_subline": "GIF ; exporte un format PNG à image unique."
  },
  "image_jpg_to_png": {
    "page_intro": "<jpeg>JPEG</jpeg> entraîne des pertes ; la conversion en PNG ne peut pas récupérer les détails supprimés, mais elle arrête toute compression avec perte supplémentaire, ce qui est pratique lorsque votre pipeline d'édition ou vos tâches par lots se normalisent en PNG. Prise en charge de la sélection multiple et du glisser-déposer.",
    "notes_title": "Remarques",
    "notes_body": "Les photos JPEG typiques sont opaques ; après la conversion PNG, ils restent généralement totalement opaques à moins que la source n'ait déjà une transparence (rare).",
    "drop_subline": "Axé sur JPG/JPEG ; autres rasters autorisés. La sortie est centrée sur PNG."
  },
  "image_jpg_to_webp": {
    "drop_subline": "JPG/JPEG ; d'autres rasters vers WebP sont également pris en charge."
  },
  "image_png_to_jpg": {
    "drop_subline": "Axé sur PNG ; d'autres rasters au format JPG sont également pris en charge."
  },
  "image_png_to_webp": {
    "drop_subline": "Axé sur PNG ; d'autres rasters vers WebP sont également pris en charge."
  },
  "image_svg_to_png": {
    "drop_subline": "Choisissez les fichiers .svg ; la sortie est centrée sur PNG."
  },
  "image_webp_to_jpg": {
    "drop_subline": "WebP ; d'autres rasters au format JPG sont également pris en charge."
  },
  "image_webp_to_png": {
    "page_intro": "De nombreux sites proposent des ressources <webp>WebP</webp> plus petites ; lorsque votre chaîne d'outils cible n'accepte que PNG, effectuez une conversion par lots localement ici avant d'importer ailleurs. Sélection multi-fichiers prise en charge.",
    "tips_title": "Astuce",
    "tips_body": "Les WebP transparents, sans perte et avec perte sont tous rastérisés dans le navigateur avant de les enregistrer au format PNG, comme pour l'exportation à partir d'applications graphiques de bureau dans la plupart des cas.",
    "drop_subline": "Axé sur WebP ; autres rasters OK ; la sortie est toujours PNG."
  },
  "image_ico": {
    "intro_note": "Créez favicon.ico à partir d'une image localement : choisissez une taille de carré et téléchargez (PNG dans ICO pour les navigateurs modernes et Windows).",
    "drop_desc": "Choisissez la taille, puis téléchargez favicon.ico.",
    "pick_label": "Sélectionnez l'image (512 × 512 ou plus recommandé)",
    "empty_hint": "Aucune image sélectionnée.",
    "lbl_side": "Côté sortie (carré)",
    "hint_one_size": "ICO ne contient que la taille sélectionnée.",
    "err_pick_first": "Veuillez d'abord sélectionner une image.",
    "err_canvas": "Impossible de créer un contexte de canevas",
    "msg_download_started": "Téléchargement commencé. favicon.ico.",
    "msg_generate_fail": "La génération a échoué",
    "page_intro": "Choisissez une grande image (512 × 512 ou plus recommandée), choisissez la longueur du bord de sortie, puis téléchargez <favicon>favicon.ico</favicon>."
  },
  "image_ocr": {
    "intro_note": "Les packs de travail, de base et de langue Tesseract se chargent à partir du CDN (première exécution plus lente). Les images restent dans votre navigateur.",
    "lbl_langs": "Langues (codes Tesseract, par exemple eng, chi_sim, eng+chi_sim)",
    "lbl_image": "Image​",
    "hdr_result": "Texte reconnu",
    "prog_initializing": "Initialisation…",
    "prog_recognizing": "Reconnaissance de {pct} %",
    "empty_result": "(Aucun texte reconnu)",
    "err_failed": "La reconnaissance a échoué",
    "lang_zh_en": "Chinois simplifié + anglais",
    "lang_zh": "Chinois simplifié",
    "lang_ja_en": "Japonais + anglais",
    "lang_zh_tw_en": "chinois traditionnel + anglais",
    "copy": "Copier le texte",
    "download_txt": "Télécharger TXT"
  },
  "bcrypt": {
    "text_label": "Texte",
    "rounds_label": "Tours (4-31)",
    "generate": "Générer un hachage",
    "copy": "Copier",
    "verify_hash_label": "Hash pour vérifier",
    "verify": "Vérifier",
    "match": "Correspondance",
    "not_match": "Ne correspond pas"
  },
  "sm3": {
    "text_label": "Saisir le texte",
    "compute": "Calculer",
    "copy": "Copier"
  },
  "sm4": {
    "key_label": "Clé (32 caractères hexadécimaux)",
    "text_label": "Saisir le texte",
    "encrypt": "Crypter",
    "decrypt": "Déchiffrer",
    "process": "Processus",
    "copy": "Copier",
    "error": "Erreur"
  },
  "sm2": {
    "generate_keypair": "Générer une paire de clés",
    "public_key": "Clé publique",
    "private_key": "Clé privée",
    "text_label": "Saisir le texte",
    "encrypt": "Crypter",
    "decrypt": "Déchiffrer",
    "copy": "Copier",
    "error": "Erreur"
  },
  "password_strength": {
    "password_label": "Mot de passe",
    "level_0": "Faible",
    "level_1": "Moyen",
    "level_2": "Fort",
    "level_3": "Très fort",
    "length": "Longueur",
    "crack_time": "Temps de crack",
    "lower": "Minuscules",
    "upper": "Majuscules",
    "digit": "Chiffre",
    "special": "Spécial"
  },
  "wifi_qr": {
    "ssid": "SSID​",
    "password": "Mot de passe",
    "encryption": "Cryptage",
    "none": "Aucun",
    "generate": "Générer des QR"
  },
  "json_to_go": {
    "struct_name": "Nom de la structure",
    "json_label": "Saisir JSON",
    "convert": "Convertir",
    "copy": "Copier",
    "parse_error": "Erreur d'analyse JSON"
  },
  "json_to_java": {
    "class_name": "Nom de la classe",
    "json_label": "Saisir JSON",
    "convert": "Convertir",
    "copy": "Copier",
    "parse_error": "Erreur d'analyse JSON"
  },
  "json_to_sql": {
    "table_name": "Nom du tableau",
    "json_label": "Entrée JSON Array",
    "convert": "Convertir",
    "copy": "Copier",
    "parse_error": "Erreur d'analyse JSON",
    "not_array": "L'entrée n'est pas un tableau JSON"
  },
  "json_merge": {
    "json_a": "JSON A​",
    "json_b": "JSON B​",
    "merge": "Fusion",
    "copy": "Copier",
    "parse_error": "Erreur d'analyse JSON"
  },
  "nginx_format": {
    "input_label": "Configuration Nginx en entrée",
    "format": "Format​",
    "copy": "Copier"
  },
  "docker_to_compose": {
    "cmd_label": "Commande docker run en entrée",
    "convert": "Convertir",
    "copy": "Copier"
  },
  "regex_cheatsheet": {
    "copy": "Copier",
    "copied": "Copié"
  },
  "faker": {
    "generate": "Générer de fausses données"
  },
  "deobfuscate": {
    "input_label": "Entrée du code JS",
    "format": "Format​",
    "copy": "Copier"
  },
  "text_pinyin": {
    "input_label": "Entrée du chinois",
    "copy": "Copier"
  },
  "text_zh_convert": {
    "s2t": "Simp→Trad​",
    "t2s": "Trad→Simp​",
    "input_label": "Saisir le texte",
    "copy": "Copier"
  },
  "text_mask": {
    "input_label": "Saisir le texte",
    "keep_first": "Conserver le premier N",
    "keep_last": "Conserver le dernier N",
    "mask_char": "Caractère de masque",
    "copy": "Copier"
  },
  "text_emoji": {
    "search_placeholder": "Rechercher Emoji…",
    "copied": "Copié"
  },
  "text_synonym": {
    "input_label": "Saisir le mot",
    "synonyms": "Synonymes",
    "antonyms": "Antonymes",
    "not_found": "Introuvable dans le dictionnaire"
  },
  "totp": {
    "secret_label": "Secret (Base32)​",
    "remaining": "{sec}s restant"
  },
  "basic_auth": {
    "username": "Nom d'utilisateur",
    "password": "Mot de passe",
    "copy": "Copier"
  },
  "cookie_parse": {
    "input_label": "Saisir la chaîne de cookie",
    "key": "Clé",
    "value": "Valeur"
  },
  "jwt_generate": {
    "header": "En-tête (JSON)",
    "payload": "Charge utile (JSON)",
    "secret": "Secret​",
    "generate": "Générer JWT",
    "copy": "Copier",
    "error": "La génération a échoué"
  },
  "svg_placeholder": {
    "width": "Largeur",
    "height": "Hauteur",
    "text": "Texte",
    "fg": "Premier plan",
    "bg": "Arrière-plan",
    "copy_svg": "Copier SVG",
    "copy_data_url": "Copier l'URL des données"
  },
  "stopwatch": {
    "start": "Début",
    "pause": "Pause​",
    "resume": "Reprendre",
    "lap": "Tour",
    "reset": "Réinitialiser",
    "lap_n": "Tour {n}"
  },
  "date_calc": {
    "add_days": "Ajouter/soustraire des jours",
    "date_diff": "Différence de date",
    "date1": "Date​",
    "date2": "Date 2​",
    "days": "jours",
    "calc": "Calculer"
  },
  "percentage": {
    "mode_of": "X% de Y",
    "mode_is": "X est quel % de Y",
    "mode_change": "Taux de changement",
    "percent": "Pourcent",
    "of_value": "Valeur",
    "value": "Valeur",
    "total": "Total​",
    "from": "De",
    "to": "À"
  },
  "temperature": {
    "value": "Température"
  },
  "roman_numeral": {
    "to_roman": "→ Romain",
    "from_roman": "→ Arabe",
    "arabic": "Arabe",
    "roman": "Romain"
  },
  "image_greyscale": {
    "process": "Vers niveaux de gris",
    "download": "Télécharger"
  },
  "image_nine_grid": {
    "process": "Recadrage à neuf grilles"
  },
  "mac_lookup": {
    "input_label": "Saisir l'adresse MAC",
    "not_found": "Fournisseur introuvable"
  },
  "ipv4_range": {
    "start": "Démarrer l'IP",
    "end": "Fin IP"
  },
  "port_reference": {
    "port": "Port​",
    "proto": "Protocole",
    "name": "Nom"
  },
  "math_eval": {
    "placeholder": "Entrez une expression, par ex. 2^10 + sqrt(16)",
    "calc": "Calculer",
    "preview": "Aperçu",
    "supported": "Opérations prises en charge",
    "history": "Historique",
    "clear": "Effacer",
    "copy_result": "Copier le résultat",
    "copied": "Résultat copié.",
    "radian_note": "Les fonctions trigonométriques utilisent des radians, par exemple sin(pi/2) = 1."
  },
  "eta_calc": {
    "total": "Total​",
    "done": "Terminé",
    "elapsed": "Écoulé",
    "elapsed_unit": "secondes",
    "speed": "Vitesse",
    "speed_unit": "/s​",
    "remaining": "ETA​",
    "total_time": "Total estimé"
  },
  "mac_gen": {
    "count": "Nombre",
    "separator": "Séparateur",
    "prefix": "Préfixe (facultatif)",
    "uppercase": "Majuscules",
    "generate": "Générer",
    "results": "Résultats",
    "copy_all": "Copier tout"
  },
  "device_info": {
    "note": "Détecter les informations actuelles sur l'environnement du navigateur.",
    "property": "Propriété",
    "value": "Valeur"
  },
  "bip39": {
    "strength": "Bits d'entropie",
    "generate": "Générer",
    "loading": "Chargement…",
    "mnemonic": "Mnémonique",
    "copy": "Copier",
    "error": "La génération a échoué"
  },
  "rsa_keygen": {
    "key_size": "Taille de clé",
    "generate": "Générer une paire de clés",
    "generating": "Générateur…",
    "public_key": "Clé publique (PEM)",
    "private_key": "Clé privée (PEM)",
    "copy": "Copier"
  },
  "xml_json": {
    "input": "Entrée",
    "output": "Sortie",
    "convert": "Convertir",
    "copy": "Copier"
  },
  "json_minify": {
    "input": "Saisir JSON",
    "minify": "Réduire",
    "output": "Sortie",
    "copy": "Copier",
    "original": "Original​",
    "minified_size": "Minifié",
    "saved": "Enregistré"
  },
  "numeronym": {
    "encode": "Encoder",
    "decode": "Décoder",
    "examples": "Exemples courants"
  },
  "ascii_art": {
    "text": "Texte",
    "char_set": "Caractère de remplissage",
    "result": "Résultat",
    "copy": "Copier",
    "hint": "Prend en charge les lettres anglaises, les chiffres et certains signes de ponctuation, jusqu'à 30 caractères."
  },
  "idcard": {
    "input_label": "Saisir le numéro de carte d'identité",
    "valid": "Valide",
    "invalid": "Invalide",
    "province": "Province​",
    "birthday": "Anniversaire",
    "gender": "Sexe",
    "male": "Homme",
    "female": "Femme",
    "unknown": "Inconnu"
  },
  "chinese_colors": {
    "copied": "Copié"
  },
  "relationship": {
    "input_label": "Chaîne de relations d'entrée (par exemple, père, mère)",
    "placeholder": "père, mère",
    "unknown": "Inconnu"
  },
  "curl_to_code": {
    "input_label": "Commande cURL",
    "lang_label": "Langue cible",
    "convert": "Convertir",
    "output": "Code de sortie",
    "copy": "Copier",
    "copied": "Copié",
    "err_parse": "Impossible d'analyser la commande cURL"
  },
  "box_shadow": {
    "layer": "Couche",
    "remove": "Retirer",
    "offsetX": "Décalage X",
    "offsetY": "Décalage Y",
    "blur": "Flou",
    "spread": "Étalement",
    "color": "Couleur",
    "add_layer": "Ajouter un calque",
    "preview": "Aperçu",
    "copy": "Copier",
    "copied": "Copié"
  },
  "border_radius": {
    "top_left": "En haut à gauche",
    "top_right": "En haut à droite",
    "bottom_right": "En bas à droite",
    "bottom_left": "En bas à gauche",
    "preview": "Aperçu",
    "copy": "Copier",
    "copied": "Copié"
  },
  "flexbox": {
    "direction": "flex-direction​",
    "justify_content": "justifier le contenu",
    "align_items": "aligner les éléments",
    "flex_wrap": "flex-wrap​",
    "gap": "écart",
    "add_child": "Ajouter un enfant",
    "remove_child": "Supprimer un enfant",
    "preview": "Aperçu",
    "copy": "Copier",
    "copied": "Copié"
  },
  "gradient": {
    "type": "Type​",
    "angle": "Angle​",
    "color_stops": "Couleur Arrêts",
    "remove": "Retirer",
    "add_stop": "Ajouter un arrêt",
    "preview": "Aperçu",
    "copy": "Copier",
    "copied": "Copié"
  },
  "css_animation": {
    "preset": "Préréglage",
    "duration": "Durée(s)",
    "timing": "Minutage",
    "iteration": "Itération",
    "keyframes": "Images clés",
    "preview": "Aperçu",
    "copy": "Copier",
    "copied": "Copié"
  },
  "color_blindness": {
    "input_color": "Couleur d'entrée",
    "original": "Original​",
    "palette": "Aperçu de la palette"
  },
  "token_count": {
    "input_label": "Saisir le texte",
    "placeholder": "Entrez le texte pour estimer le nombre de jetons…",
    "chars": "caractères",
    "words": "mots",
    "lines": "lignes",
    "estimate": "Estimation du jeton",
    "tokens": "jetons",
    "of_context": "du contexte",
    "disclaimer": "※ Estimation approximative. Le nombre réel dépend du tokenizer spécifique.",
    "model": "Modèle de référence",
    "output_tokens": "Jetons de sortie attendus",
    "input_estimate": "Jetons d'entrée estimés",
    "context_usage": "Utilisation du contexte",
    "estimated_cost": "Coût estimé (USD)",
    "disclaimer_extended": "Il s'agit d'une approximation basée sur les caractères, et non d'un résultat officiel exact du tokenizer. Les prix et les limites du contexte peuvent changer ; vérifiez les derniers tarifs du fournisseur avant d'envoyer une demande."
  },
  "screenshot_beautify": {
    "upload": "Télécharger une capture d'écran",
    "bg_color": "Arrière-plan",
    "padding": "Rembourrage",
    "border_radius": "Rayon de frontière",
    "shadow_blur": "Flou d'ombre",
    "shadow_color": "Couleur de l'ombre",
    "preview": "Aperçu",
    "no_image": "Veuillez d'abord télécharger une capture d'écran",
    "export_png": "Exporter PNG"
  },
  "pangu_spacing": {
    "input_label": "Saisir le texte",
    "placeholder": "Bonjour, 这是123test文本",
    "output": "Résultat",
    "copy": "Copier",
    "copied": "Copié"
  },
  "aspect_ratio": {
    "width": "Largeur",
    "height": "Hauteur",
    "calc_ratio": "Calculer le rapport",
    "common_ratios": "Ratios communs",
    "reverse_calc": "Calcul inverse",
    "ratio_w": "Rapport W",
    "ratio_h": "Rapport H",
    "known_side": "Côté connu",
    "known_value": "Valeur connue",
    "result": "Résultat"
  },
  "loan_calc": {
    "principal": "Montant principal",
    "annual_rate": "Taux annuel (%)",
    "term": "Durée du prêt (années)",
    "term_half_year": "6 mois ({months} périodes)",
    "term_years": "{ans, pluriel, un {1 an} autre {# ans}} ({months} périodes)",
    "method": "Méthode",
    "equal_installment": "Versement égal",
    "equal_principal": "Principal égal",
    "monthly_payment": "Paiement mensuel",
    "total_interest": "Intérêts totaux",
    "total_payment": "Paiement total",
    "schedule": "Échéancier de paiement",
    "month": "Mois",
    "payment": "Paiement",
    "principal_part": "Principal​",
    "interest_part": "Intérêts",
    "remaining": "Restant"
  },
  "bmi": {
    "height": "Hauteur",
    "weight": "Poids",
    "underweight": "Insuffisance pondérale",
    "normal": "Normal​",
    "overweight": "Surpoids",
    "obese": "Obèse",
    "range_chart": "Tableau de plage d'IMC"
  },
  "work_hours": {
    "summary_title": "Résumé des heures",
    "auto_calculate": "Recalcule automatiquement lors d'un changement d'équipe",
    "shifts_unit": "Equipe de travail",
    "total_work": "Travail total",
    "regular_hours": "Heures régulières",
    "overtime": "Heures supplémentaires",
    "estimated_pay": "Salaire estimé",
    "enter_hourly_rate": "Entrez un taux horaire pour calculer",
    "total_span": "Durée de présence sur site",
    "total_break": "Pauses totales",
    "rules_title": "Règles de calcul et de rémunération",
    "rules_hint": "Les heures supplémentaires sont calculées par équipe au-dessus de la norme quotidienne. Les chiffres de rémunération ne sont que des estimations.",
    "standard_hours_day": "Heures/jour standard",
    "rounding": "Arrondi des heures",
    "no_rounding": "Aucun arrondi (minutes exactes)",
    "nearest_minutes": "{minutes} minutes les plus proches",
    "hourly_rate": "Taux horaire",
    "overtime_multiplier": "Multiplicateur d'heures supplémentaires",
    "currency": "Devise",
    "timesheet_title": "Détails de l'équipe",
    "overnight_hint": "Une heure de fin antérieure au début est traitée comme une équipe de nuit.",
    "fill_week": "Remplir cette semaine de travail",
    "add_shift": "Ajouter une équipe",
    "quick_shift": "Ajout rapide",
    "shift": "Équipe",
    "date": "Date​",
    "start_time": "Heure de début",
    "end_time": "Heure de fin",
    "break_minutes": "Pause (minutes)",
    "note": "Remarque",
    "note_placeholder": "Projet, emplacement, etc. (facultatif)",
    "duplicate": "Dupliquer",
    "remove": "Retirer",
    "overnight": "Nuit",
    "break_too_long": "La pause est plus longue que la durée du poste. Le temps de travail pour ce quart de travail est compté comme zéro.",
    "work_time": "Temps de travail",
    "break_short": "Pause",
    "hour_short": "h​",
    "minute_short": "m​",
    "work_minutes": "Minutes de travail",
    "regular_minutes": "Minutes régulières",
    "overtime_minutes": "Minutes d'heures supplémentaires",
    "total_pay": "Salaire total",
    "report_title": "Rapport de feuille de temps",
    "report_hint": "Copiez un rapport lisible ou exportez au format CSV pour une édition ultérieure.",
    "copy_report": "Copier le rapport",
    "export_csv": "Exporter CSV",
    "reset": "Réinitialiser les équipes",
    "copied": "Rapport de feuille de temps copié.",
    "exported": "CSV exporté.",
    "week_filled": "Des équipes du lundi au vendredi ont été ajoutées pour cette semaine."
  },
  "template_filler": {
    "template_label": "Texte du modèle",
    "template_placeholder": "Entrez le modèle, par exemple : Bonjour, '{' '{' 'nom' '}' '}' !",
    "variables": "Variables​",
    "fill_data": "Remplir les données",
    "add_row": "Ajouter une ligne",
    "row": "Rangée",
    "remove_row": "Retirer",
    "result": "Résultat",
    "copy": "Copier",
    "copied": "Copié"
  },
  "url_defang": {
    "defang": "Désarmer",
    "refang": "Réarmer",
    "input_label": "Saisir l'URL",
    "output": "Sortie",
    "copy": "Copier",
    "copied": "Copié",
    "rules": "Règles",
    "rule1": ":// → [://]​",
    "rule2": ". → [.]​",
    "rule3": "Refang est l'opération inverse"
  },
  "protobuf_decode": {
    "decode": "Décoder",
    "invalid_hex": "Entrée hexadécimale invalide",
    "result": "Résultat",
    "field": "Champ",
    "wire_type": "Type de fil",
    "value": "Valeur",
    "unknown_wire": "Type de fil inconnu"
  },
  "pdf_signature": {
    "upload": "Télécharger le PDF",
    "checking": "Vérification…",
    "signed": "Signé",
    "not_signed": "Non signé",
    "file": "Fichier",
    "pages": "Pages​",
    "parse_error": "Erreur d'analyse PDF"
  },
  "dev_string_obfuscator": {
    "input_label": "Code d'entrée",
    "input_placeholder": "Coller le code JavaScript avec des chaînes littérales…",
    "method_label": "Méthode d'obscurcissement",
    "method_base64": "Base64​",
    "method_hex": "Hex​",
    "method_unicode": "Unicode​",
    "method_charcode": "CharCode​",
    "method_reverse": "Inverse",
    "obfuscate": "Obscurcir",
    "output": "Résultat obscurci",
    "copy": "Copier",
    "copied": "Copié"
  },
  "dev_git_cheatsheet": {
    "category_basic": "Opérations de base",
    "category_branch": "Gestion des succursales",
    "category_remote": "Référentiel distant",
    "category_undo": "Annuler et restaurer",
    "category_stash": "Stash​",
    "category_log": "Journal et historique",
    "copy": "Copier",
    "copied": "Copié",
    "click_copy": "Cliquez pour copier"
  },
  "html_wysiwyg": {
    "bold": "Gras",
    "italic": "Italique",
    "underline": "Souligné",
    "strikethrough": "Barré",
    "ordered_list": "Liste ordonnée",
    "unordered_list": "Liste non ordonnée",
    "mode_edit": "Visuel",
    "source_view": "Vue source",
    "preview": "Aperçu",
    "copy_html": "Copier HTML",
    "copied": "Copié",
    "prompt_url": "URL du lien",
    "prompt_img_url": "URL de l'image"
  },
  "dev_css_unit_converter": {
    "context_title": "Référence Px",
    "input_title": "Entrée",
    "value_label": "Valeur",
    "from_unit": "Depuis l'unité",
    "results_title": "Conversions​",
    "col_unit": "Unité",
    "col_value": "Valeur",
    "base_size_label": "Taille de police de base (px)",
    "viewport_width": "Largeur de la fenêtre (px)",
    "viewport_height": "Hauteur de la fenêtre (px)",
    "result": "Résultat de la conversion",
    "copy": "Copier",
    "copied": "Copié"
  },
  "web_meta_tag_generator": {
    "general": "Méta de base",
    "title_label": "Titre",
    "description_label": "Description​",
    "viewport_label": "Porte d'affichage",
    "charset_label": "Jeu de caractères",
    "author_label": "Auteur",
    "keywords_label": "Mots clés",
    "robots_label": "Robots​",
    "og_title": "Titre OG",
    "og_description": "Description OG",
    "og_image": "URL de l'image OG",
    "og_url": "URL OG",
    "twitter_card": "Type de carte Twitter",
    "generate": "Générer",
    "output": "Code de balise méta",
    "preview": "Aperçu",
    "copy": "Copier",
    "copied": "Copié"
  },
  "encode_unicode": {
    "input_label": "Saisir le texte",
    "output_label": "Sortie",
    "encode": "Encoder",
    "decode": "Décoder",
    "format_label": "Format​",
    "format_backslash_u": "\\uXXXX​",
    "format_html_entity": "&#xXXXX;​",
    "copy": "Copier",
    "copied": "Copié",
    "decode_failed": "Échec du décodage"
  },
  "encode_quoted_printable": {
    "input_label": "Entrée",
    "output_label": "Sortie",
    "line_len": "Longueur de ligne maximale",
    "encode": "Encoder",
    "decode": "Décoder",
    "copy": "Copier",
    "copied": "Copié",
    "encode_failed": "Échec de l'encodage",
    "decode_failed": "Échec du décodage",
    "err_decode": "Échec du décodage imprimable-cité"
  },
  "encode_uuencode": {
    "input_label": "Entrée",
    "output_label": "Sortie",
    "encode": "UUEEncode",
    "decode": "UUDecode​",
    "filename_label": "Nom de fichier",
    "mode": "Mode fichier (par exemple 644)",
    "copy": "Copier",
    "copied": "Copié",
    "encode_failed": "Échec de l'encodage",
    "decode_failed": "Échec du décodage",
    "err_decode": "Échec du UUDecode"
  },
  "encode_base85": {
    "input_label": "Entrée",
    "input_mode": "Mode de saisie",
    "mode_text": "Texte (UTF-8)",
    "mode_hex": "Octets hexadécimaux",
    "delimiters": "enroulement avec <~ ~>",
    "output_label": "Sortie",
    "encode": "Encoder",
    "decode": "Décoder",
    "copy": "Copier",
    "copied": "Copié",
    "invalid_hex": "Entrée hexadécimale invalide",
    "encode_failed": "Échec de l'encodage",
    "decode_failed": "Échec du décodage",
    "err_decode": "Échec du décodage Base85"
  },
  "camera_recorder": {
    "select_device": "Appareil photo",
    "default": "Par défaut",
    "start_camera": "Démarrer la caméra",
    "stop_camera": "Arrêter la caméra",
    "take_photo": "Prendre une photo",
    "start_record": "Démarrer l'enregistrement",
    "stop_record": "Arrêter l'enregistrement",
    "pause": "Pause​",
    "resume": "Reprendre",
    "recording": "Enregistrement…",
    "paused": "En pause",
    "photo_result": "Photo​",
    "video_result": "Vidéo",
    "export_photo": "Exporter PNG",
    "export_video": "Exporter WebM",
    "no_camera": "Impossible d'accéder à la caméra"
  },
  "text_regex_memo": {
    "category_chars": "Classes de caractères",
    "category_quantifiers": "Quantificateurs",
    "category_anchors": "Ancres",
    "category_groups": "Groupes et références",
    "category_lookaround": "Recherche (anticipation/recherche)",
    "category_flags": "Le mode Flags",
    "copy": "Copier",
    "click_copy": "Cliquez pour copier",
    "copied": "Copié"
  },
  "dev_git_diff_viewer": {
    "input_label": "Coller la sortie Diff",
    "input_placeholder": "Coller le texte de sortie git diff…",
    "parse": "Analyser",
    "files_changed": "Fichiers modifiés",
    "additions": "Ajouts",
    "deletions": "Suppressions",
    "changes": "Modifications",
    "err_parse": "Impossible d'analyser la sortie diff"
  },
  "web_url_query_editor": {
    "url_label": "Saisir l'URL",
    "url_placeholder": "https://example.com?key=value&foo=bar​",
    "parse": "Analyser",
    "url_encode": "Encodage d'URL lors de la création",
    "params": "Paramètres de requête",
    "result": "URL construite",
    "key": "Clé",
    "value": "Valeur",
    "add_param": "Ajouter un paramètre",
    "remove_param": "Retirer",
    "preview": "URL d'aperçu",
    "copy": "Copier",
    "copied": "Copié",
    "err_invalid_url": "URL"
  },
  "tax_calc": {
    "income_label": "Salaire mensuel (CNY)",
    "social_label": "Assurance sociale (mensuelle, CNY)",
    "special_label": "Déductions spéciales (mensuelles, CNY)",
    "calc": "Calculer",
    "taxable": "Revenu mensuel imposable : ",
    "annual_taxable": "Revenu annuel imposable : ",
    "rate": "Taux d'imposition : ",
    "monthly_tax": "Impôt mensuel : ",
    "annual_tax": "Impôt annuel : ",
    "after_tax": "Revenu après impôt",
    "assumption": "Estimation des retenues cumulatives pour les résidents de Chine continentale et suppose les mêmes revenus mensuels et déductions tout au long de l'année.",
    "schedule": "Retenue cumulative mensuelle",
    "month": "Mois",
    "monthly_taxable": "Mensuelle Taxable",
    "cumulative_taxable": "Cumulatif Taxable",
    "cumulative_tax": "Taxe cumulée",
    "disclaimer": "Estimation seulement ; exclut les cas particuliers tels que les primes annuelles, les revenus de service et les différences de retenues antérieures."
  },
  "coord_convert": {
    "lng_label": "Longitude (lng)​",
    "lat_label": "Latitude (lat)​",
    "from_label": "De",
    "to_label": "À",
    "convert": "Convertir",
    "result_label": "Résultat",
    "copy": "Copier"
  },
  "sensitive_words": {
    "placeholder": "Coller les documents officiels, les communiqués de presse, les avis, etc.",
    "check": "Contrôle strict",
    "found_prefix": "Termes sensibles trouvés ({count} types) : ",
    "col_word": "Terme",
    "col_count": "Nombre",
    "no_found": "Aucun résultat dans le dictionnaire, mais une révision manuelle est toujours requise avant la publication.",
    "bank_count": "Dictionnaire strict du gouvernement : {count} termes",
    "mode_hint": "Évasion détection activée : les espaces et les caractères de largeur nulle ont été supprimés ; pleine largeur normalisée.",
    "disclaimer": "Cet outil ne remplace pas l'examen de confidentialité ou l'approbation humaine finale. Aucun résultat ne signifie pas publiable.",
    "custom_dict_title": "Liste de mots personnalisée",
    "custom_dict_hint": "Texte UTF-8, un terme par ligne ; les lignes commençant par # sont des commentaires. Stocké localement dans votre navigateur.",
    "upload_dict": "Télécharger le dictionnaire (.txt)",
    "upload_txt": "Télécharger le texte à vérifier (.txt)",
    "clear_custom": "Effacer la liste personnalisée",
    "custom_bank_count": "Personnalisé {count}",
    "active_bank_count": "{count} actif(s)",
    "source_file": "Fichier source",
    "highlight_title": "Aperçu en surbrillance",
    "col_position": "Positions​",
    "dict_imported": "Importé {count} termes personnalisés",
    "dict_cleared": "Liste personnalisée effacée",
    "err_dict_empty": "Le fichier de dictionnaire est vide ou invalide",
    "err_dict_parse": "Échec de la lecture du fichier dictionnaire",
    "err_txt_read": "Échec de la lecture du fichier texte"
  },
  "signature": {
    "color_label": "Couleur du trait",
    "width_label": "Largeur du trait",
    "export": "Exporter PNG",
    "clear": "Effacer"
  },
  "subtitle_convert": {
    "from_fmt": "Du format",
    "to_fmt": "Au format",
    "input_placeholder": "Coller le contenu des sous-titres…",
    "convert": "Convertir",
    "output": "Sortie",
    "copy": "Copier"
  },
  "htpasswd": {
    "username_label": "Nom d'utilisateur",
    "password_label": "Mot de passe",
    "algorithm_label": "Algorithme",
    "add": "Ajouter",
    "copy": "Copier tout"
  },
  "gcd_lcm": {
    "input_label": "Des nombres (séparés par des virgules)",
    "input_placeholder": "par ex. 12, 18, 24",
    "calc": "Calculer"
  },
  "periodic_table": {
    "atomic_number": "Numéro atomique : ",
    "atomic_mass": "Masse atomique :",
    "category": "Catégorie : "
  },
  "danmaku": {
    "text_label": "Texte Danmaku",
    "color_label": "Couleur",
    "speed_label": "Vitesse",
    "send": "Envoyer"
  },
  "teleprompter": {
    "placeholder": "Entrer le contenu du script…",
    "speed_label": "Vitesse",
    "font_size_label": "Taille de la police",
    "mirror_label": "Miroir",
    "play": "Lecture",
    "stop": "Arrêter",
    "pause": "Pause​"
  },
  "batch_rename": {
    "add_files": "Ajouter des fichiers",
    "prefix_label": "Préfixe",
    "start_num_label": "Numéro de départ",
    "pad_len_label": "Zéro remplissage",
    "ext_label": "Extension​",
    "col_original": "Original​",
    "col_renamed": "Renommé",
    "copy": "Liste de copies"
  },
  "bankcard_bin": {
    "lookup_title": "Analyse BIN / IIN de la carte",
    "lookup_hint": "Détecte le réseau de carte, interroge d'abord la base locale couvrant {count} grands émetteurs chinois et valide les numéros complets.",
    "mode_single": "Recherche unique",
    "mode_batch": "Recherche par lots",
    "card_label": "BIN, IIN ou numéro de carte complet",
    "placeholder": "Entrez 6 à 19 chiffres ; les espaces sont acceptés",
    "clear": "Effacer",
    "examples": "Exemples",
    "privacy_note": "Toutes les exécutions de détection et de validation dans ce navigateur. Les numéros de carte ne sont pas téléchargés et les résultats affichent uniquement des numéros masqués.",
    "empty_title": "Entrez les 6 premiers chiffres pour commencer",
    "empty_hint": "Entrez un numéro de carte complet pour exécuter également une somme de contrôle Luhn.",
    "masked_number": "Numéro masqué",
    "bank": "Émetteur",
    "network": "Réseau de la carte",
    "card_type": "Type de carte",
    "bin6": "BIN à 6 chiffres",
    "iin8": "IIN à 8 chiffres",
    "checksum": "Vérification Luhn",
    "need_8_digits": "Affiché après 8 chiffres",
    "issuer_matched": "Émetteur correspondant",
    "issuer_not_matched": "Émetteur non apparié",
    "issuer_unknown": "Émetteur non disponible",
    "digit_unit": "chiffres",
    "digits": "Longueur",
    "copy_result": "Copier le résultat",
    "copied": "Résultats copiés.",
    "exported": "CSV exporté.",
    "checksum_not_run": "Entrez au moins 13 chiffres pour une vérification du numéro complet",
    "checksum_valid": "Réussi",
    "checksum_invalid": "Échec",
    "checksum_warning": "Ce numéro a échoué au contrôle Luhn et peut contenir une faute de frappe. Luhn vérifie uniquement la structure des nombres ; cela ne prouve pas qu'une carte existe ou est active.",
    "data_disclaimer": "L'émetteur, le pays et le type de carte utilisent des données BIN publiques hors ligne et des règles locales. Ils peuvent changer avec de nouvelles plages ou des modifications de produits. Pour les paiements, le risque ou tout usage critique, vérifiez avec les données en direct de l'émetteur ou du réseau. La base mondiale additionnelle est basée sur iannuttall/binlist-data (CC BY 4.0), un jeu archivé qui n'est pas un registre IIN officiel.",
    "type_credit": "Crédit",
    "type_debit": "Débit",
    "type_prepaid": "Prépayé",
    "type_unknown": "Inconnu",
    "network_unionpay": "UnionPay​",
    "network_visa": "Visa​",
    "network_mastercard": "Mastercard​",
    "network_amex": "American Express​",
    "network_jcb": "JCB​",
    "network_discover": "Découverte",
    "network_diners": "Diners Club​",
    "network_maestro": "Maestro​",
    "network_unknown": "Inconnu / autre",
    "batch_label": "Numéros de carte ou BIN",
    "batch_placeholder": "Un par ligne, ou séparé par des virgules/points-virgules\n622202\n621700\n4111 1111 1111 1111",
    "batch_hint": "Jusqu'à 100 entrées à la fois. Les doublons sont supprimés et les exportations ne contiennent jamais de numéros de carte complets non masqués.",
    "run_batch": "Exécuter une recherche par lots",
    "batch_empty": "Entrez d'abord au moins une valeur.",
    "batch_complete": "{count} entrées traitées.",
    "batch_results": "Résultats du lot",
    "batch_summary": "{total} au total · {matched} émetteurs trouvés · {valid} validations Luhn réussies",
    "copy_table": "Copier le tableau",
    "export_csv": "Exporter CSV",
    "feature_local": "Traitement local du navigateur",
    "feature_local_desc": "Charge uniquement le fragment BIN nécessaire à 6 / 8 chiffres et n'appelle pas d'API BIN externe en temps réel.",
    "feature_validation": "Détection et validation",
    "feature_validation_desc": "Le réseau est détecté à partir de tranches de numéros ; les numéros complets sont vérifiés séparément avec Luhn.",
    "feature_iin": "Support à 6 et 8 chiffres",
    "feature_iin_desc": "Affiche à la fois le BIN traditionnel à 6 chiffres et l'IIN moderne à 8 chiffres à des fins de comparaison.",
    "global_hint": "La base mondiale additionnelle couvre les régions linguistiques actuelles, l'Amérique latine, le Brésil, l'Allemagne, la Russie et la France. Seuls les 6 / 8 premiers chiffres BIN sont utilisés.",
    "global_loading": "Chargement de la base BIN mondiale additionnelle…",
    "country": "Pays / région",
    "country_unknown": "Non disponible",
    "card_category": "Niveau / produit",
    "category_unknown": "Non disponible",
    "data_source": "Source des données",
    "source_china_local": "Base locale Chine",
    "source_binlist_data": "Jeu public binlist-data",
    "source_rules": "Règles de plage",
    "source_unknown": "Aucune correspondance",
    "batch_loading": "Chargement des données BIN et traitement de {count} entrées…",
    "type_charge": "Carte de paiement différé",
    "network_elo": "Elo​",
    "network_laser": "Laser​",
    "network_solo": "Solo​",
    "network_atm": "ATM​",
    "network_other": "Autre",
    "input_kind": "Type d'entrée",
    "input_kind_bin6": "BIN à 6 chiffres",
    "input_kind_iin8": "IIN / préfixe à 8 chiffres",
    "input_kind_card": "Numéro de carte complet",
    "input_kind_partial": "Moins de 6 chiffres",
    "confidence": "Confiance",
    "confidence_high": "Élevé : correspond à un préfixe de plus de 8 chiffres",
    "confidence_medium": "Moyen : correspond à un BIN à 6 chiffres",
    "confidence_low": "Faible : correspond à une règle uniquement ou ne correspond pas",
    "result_note": "Remarque",
    "note_exact_or_iin": "Correspond à un préfixe de plus de 8 chiffres pour une identification plus précise.",
    "note_bin6_match": "Correspond à un BIN à 6 chiffres ; un IIN à 8 chiffres plus récent peut être plus spécifique.",
    "note_network_only": "Seul le réseau de la carte a été détecté ; émetteur introuvable.",
    "note_not_found": "Émetteur et réseau introuvables. Vérifiez les entrées ou utilisez les données officielles pour les décisions.",
    "filter_all": "Tous",
    "filter_matched": "Émetteur correspondant",
    "filter_unmatched": "Inégalé",
    "filter_luhn_failed": "Échec de Luhn"
  },
  "gif_frames": {
    "hint": "Téléchargez un fichier GIF pour extraire les images",
    "frame_count": "Images :"
  },
  "code_screenshot": {
    "lang_label": "Langue",
    "bg_label": "Arrière-plan",
    "export": "Exporter PNG"
  },
  "grid_paper": {
    "type_label": "Type de grille",
    "type_tian": "Tian​",
    "type_mi": "Mi​",
    "type_fang": "Carré",
    "type_dot": "Point",
    "cell_size_label": "Taille de cellule (px)",
    "rows_label": "Lignes",
    "cols_label": "Colonnes",
    "generate": "Générer",
    "export": "Exporter PNG"
  },
  "exchange_rate": {
    "amount_label": "Montant",
    "from_label": "De",
    "to_label": "À",
    "convert": "Convertir",
    "disclaimer": "Les taux de change fluctuent et sont fournis à titre de référence uniquement. Utilisez le devis de votre banque ou de votre fournisseur de paiement pour le règlement.",
    "swap": "Échangez des devises",
    "refresh": "Taux d'actualisation",
    "refreshing": "Actualisation…",
    "live_source": "Taux de référence quotidiens ExchangeRate-API",
    "offline_source": "Taux de repli hors ligne",
    "live_failed": "Les taux en direct n'ont pas pu être chargés. Une solution de secours hors ligne datée est utilisée."
  },
  "hanzi_decompose": {
    "placeholder": "Entrez les caractères chinois…",
    "decompose": "Décomposition",
    "unknown": "N/A​",
    "done": "Décomposé {count} Caractères Hanzi.",
    "no_hanzi": "Aucun caractère Hanzi trouvé.",
    "copied": "Résultats copiés.",
    "exported": "CSV exporté.",
    "example": "Utiliser un exemple",
    "results_title": "Résultats de la décomposition",
    "copy": "Copier les résultats",
    "export_csv": "Exporter CSV",
    "col_char": "Caractère",
    "col_parts": "Parties",
    "col_structure": "Structure​",
    "structure_unknown": "Inconnu",
    "structure_single": "Composant unique",
    "structure_pair": "Structure en deux parties",
    "structure_multi": "Structure en plusieurs parties"
  },
  "audio_editor": {
    "start_label": "Début (sec)",
    "end_label": "Fin (sec)",
    "duration": "Durée : ",
    "clip": "Clip et exportation WAV"
  },
  "csr_generate": {
    "key_size": "Taille de clé",
    "generate": "Générer",
    "private_key": "Clé privée"
  },
  "torrent_analyze": {
    "parse_error": "Échec de l'analyse. Veuillez confirmer qu'il s'agit d'un fichier .torrent valide.",
    "name_label": "Nom : ",
    "total_size": "Taille totale : ",
    "piece_length": "Longueur de la pièce : ",
    "info_hash": "Hash d'informations : ",
    "files_label": "Fichiers : ",
    "trackers": "Trackers : ",
    "magnet_link": "Lien magnétique : ",
    "copy": "Copier"
  },
  "pdf_encrypt": {
    "drop_label": "Choisissez PDF",
    "drop_desc": "Ajouter un mot de passe ouvert à un PDF non crypté",
    "empty_pdf": "Aucun PDF sélectionné",
    "password_label": "Ouvrir le mot de passe",
    "confirm_label": "Confirmer le mot de passe",
    "btn_encrypt": "Crypter et télécharger",
    "msg_select_first": "Veuillez d'abord sélectionner un fichier PDF.",
    "msg_password_required": "Veuillez saisir un mot de passe.",
    "msg_password_mismatch": "Les mots de passe ne correspondent pas.",
    "msg_done": "PDF crypté généré ; le téléchargement a commencé.",
    "err_encrypted_or_invalid": "Impossible de lire ce PDF (crypté, corrompu ou non pris en charge). S'il dispose d'un mot de passe, utilisez d'abord PDF Decrypt.",
    "err_failed": "Le cryptage a échoué. Essayez Chrome ou Edge."
  },
  "heic_to_jpg": {
    "hint": "HEIC/HEIF est décodé en JPG dans votre navigateur ; les fichiers ne sont pas téléchargés.",
    "drop_label": "Images HEIC / HEIF",
    "drop_desc": ".heic, .heif — plusieurs fichiers OK",
    "empty": "Aucun fichier HEIC sélectionné",
    "quality_label": "Qualité JPG (0,5–1)",
    "btn_convert": "Convertir en JPG",
    "msg_select": "Veuillez d'abord sélectionner les images HEIC/HEIF.",
    "msg_done": "Fait. Le téléchargement a commencé.",
    "err_convert": "Impossible de décoder ce fichier HEIC.",
    "err_failed": "Échec de la conversion. Essayez Chrome ou Edge."
  },
  "word_count": {
    "hint": "Tapez ou collez le texte pour compter localement : rien n'est envoyé à un serveur."
  },
  "age_calc": {
    "birth_label": "Date de naissance",
    "ref_label": "À partir de la date (facultatif)",
    "ref_hint": "Laissez vide pour utiliser aujourd'hui",
    "years": "Années",
    "months": "Mois",
    "days": "jours",
    "total_days": "Nombre total de jours",
    "err_invalid_birth": "Date de naissance invalide",
    "err_ref_before_birth": "La date de référence ne peut pas être antérieure à la date de naissance."
  },
  "random_number": {
    "min": "Minimum​",
    "max": "Maximum​",
    "count": "Compter (1 à 500)",
    "integer": "Entiers uniquement",
    "generate": "Générer",
    "copy": "Copier tout",
    "output": "Résultats",
    "err_range": "Pour les entiers, min ne peut pas être supérieur à max",
    "copied": "Copié dans le presse-papiers."
  },
  "caesar": {
    "input_text": "Saisir du texte",
    "shift": "Changement (1-25)",
    "mode": "Mode​",
    "encrypt": "Crypter",
    "decrypt": "Déchiffrer",
    "run": "Courir",
    "result": "Résultat"
  },
  "des": {
    "input_text": "Saisir du texte / hexadécimal",
    "key": "Clé (≥8 octets)",
    "mode": "Mode​",
    "action": "Action​",
    "encrypt": "Crypter",
    "decrypt": "Déchiffrer",
    "run": "Courir",
    "result": "Résultat",
    "key_too_short": "La clé doit faire au moins 8 octets",
    "invalid_hex": "Longueur hexadécimale non multiple de 16"
  },
  "ripemd": {
    "input_text": "Saisir du texte",
    "compute": "Calculer",
    "result": "Hash RIPEMD-160"
  },
  "bcc_lrc": {
    "input_hex": "Données hexadécimales (séparées par des espaces)",
    "mode": "Mode de vérification",
    "compute": "Calculer",
    "result": "Résultat",
    "invalid_hex": "Octet hexadécimal invalide",
    "no_data": "Veuillez saisir des données"
  },
  "iso_garble": {
    "input": "Texte tronqué",
    "fix": "Correction",
    "result": "Texte corrigé",
    "not_iso": "Contient des caractères non ISO-8859-1",
    "decode_failed": "Échec du décodage UTF-8"
  },
  "emoji_encode": {
    "input": "Saisir du texte",
    "mode": "Mode d'encodage",
    "core_values": "Valeurs principales",
    "action": "Action​",
    "encode": "Encoder",
    "decode": "Décoder",
    "run": "Courir",
    "result": "Résultat",
    "decode_failed": "Échec du décodage"
  },
  "code_playground": {
    "preview": "Aperçu"
  },
  "dir_tree": {
    "input": "Chemins de répertoire (un par ligne)",
    "generate": "Générer",
    "result": "Arborescence de répertoire"
  },
  "kv_to_code": {
    "input": "Paires clé-valeur (clé=valeur, une par ligne)",
    "language": "Langue cible",
    "convert": "Convertir",
    "result": "Code​"
  },
  "file_hash": {
    "algorithm": "Algorithme de hachage",
    "drop_here": "Déposer le fichier ici",
    "browse": "Parcourir le fichier"
  },
  "endianness": {
    "input_hex": "Entrée des octets hexadécimaux",
    "from": "De l'endianité",
    "to": "À l'endianité",
    "convert": "Convertir",
    "result": "Résultat"
  },
  "ones_complement": {
    "decimal": "Entier décimal",
    "bits": "Largeur de bits",
    "compute": "Calculer",
    "original": "Original​",
    "ones": "Complément à un",
    "twos": "Complément à deux"
  },
  "ssl_generate": {
    "key_type": "Type de clé",
    "generate": "Générer",
    "public_key": "Clé publique",
    "private_key": "Clé privée",
    "fingerprint": "SHA-256 Empreinte digitale"
  },
  "url_batch": {
    "template": "Modèle d'URL (espace réservé {id} ou {param})",
    "params": "Paramètres (un par ligne)",
    "generate": "Générer",
    "result": "Résultat"
  },
  "line_filter": {
    "input": "Saisir du texte",
    "min_len": "Longueur minimale",
    "max_len": "Longueur maximale",
    "action": "Action​",
    "filter": "Filtre",
    "truncate": "Tronquer",
    "pad": "Remplissage",
    "run": "Courir",
    "result": "Résultat"
  },
  "tts": {
    "input": "Saisir du texte",
    "voice": "Voix",
    "rate": "Taux",
    "volume": "Volume​",
    "play": "Lecture",
    "pause": "Pause​",
    "stop": "Arrêter",
    "speaking": "Parlant..."
  },
  "whois": {
    "domain": "Domaine",
    "query": "Requête",
    "querying": "Requête...",
    "result": "Résultat"
  },
  "dns_query": {
    "domain": "Domaine",
    "record_type": "Type d'enregistrement",
    "query": "Requête",
    "querying": "Requête...",
    "result": "Résultat"
  },
  "icp_query": {
    "domain": "Domaine",
    "query": "Requête",
    "querying": "Requête...",
    "result": "Résultat",
    "api_error": "Échec de la requête API"
  },
  "my_ip": {
    "query": "Requête sur mon IP",
    "querying": "Requête..."
  },
  "browser_fingerprint": {
    "ua": "Agent utilisateur",
    "language": "Langue",
    "languages": "Langues",
    "platform": "Plateforme",
    "cookies": "Cookies​",
    "do_not_track": "Ne pas suivre",
    "screen_res": "Résolution de l'écran",
    "avail_res": "Résolution disponible",
    "color_depth": "Profondeur de couleur",
    "pixel_depth": "Profondeur de pixels",
    "device_pixel_ratio": "Rapport de pixels de l'appareil",
    "timezone": "Fuseau horaire",
    "timezone_offset": "Décalage du fuseau horaire",
    "max_touch": "Toucher max",
    "hardware_concurrency": "Cœurs du processeur",
    "memory": "Mémoire",
    "canvas": "Empreinte digitale sur toile"
  },
  "doh": {
    "domain": "Domaine",
    "server": "Serveur DoH",
    "query": "Requête",
    "querying": "Requête...",
    "result": "Résultat"
  },
  "placeholder_img": {
    "width": "Largeur",
    "height": "Hauteur",
    "bg": "Arrière-plan",
    "fg": "Premier plan",
    "text": "Texte",
    "generate": "Générer",
    "download": "Télécharger"
  },
  "privacy_policy": {
    "app_name": "Nom de l'application",
    "developer": "Développeur",
    "collect_types": "Types de données collectées",
    "generate": "Générer",
    "result": "Politique de confidentialité",
    "title": "Politique de confidentialité",
    "default_types": "Informations sur l'appareil, emplacement, journaux d'utilisation",
    "section1_title": "1. Collection d'informations",
    "section1_body": "{appName} est développé par {developer}. Nous collectons les informations suivantes pour fournir et améliorer les services.",
    "section2_title": "2. Utilisation des informations",
    "section2_body": "{appName} collecte des {types} uniquement pour le fonctionnement de l'application et l'amélioration de l'expérience, et ne les vendra pas à des tiers.",
    "section3_title": "3. Sécurité des informations",
    "section3_body": "Nous prenons des mesures raisonnables pour protéger vos informations personnelles.",
    "section4_title": "4. Vos droits",
    "section4_body": "Vous disposez d'un droit d'accès, de rectification et de suppression de vos informations personnelles.",
    "section5_title": "5. Contacter",
    "section5_body": "Pour toute question, veuillez contacter {developer}."
  },
  "pomodoro": {
    "work": "Fonctionnement",
    "break": "Pause",
    "start": "Début",
    "pause": "Pause​",
    "reset": "Réinitialiser",
    "work_min": "Travail (min)",
    "break_min": "Pause (min)",
    "completed": "Complété"
  },
  "art_qr": {
    "text": "Texte/URL",
    "fg": "Premier plan",
    "bg": "Arrière-plan",
    "style": "Style de points",
    "square": "Carré",
    "circle": "Cercle",
    "generate": "Générer",
    "download": "Télécharger"
  },
  "ppi_calc": {
    "diagonal": "Diagonale (pouces)",
    "horizontal": "Px horizontal",
    "vertical": "Px vertical",
    "compute": "Calculer",
    "result": "PPI​"
  },
  "mortgage_calc": {
    "principal": "Principal​",
    "rate": "Taux annuel (%)",
    "years": "Années",
    "method": "Méthode",
    "equal_payment": "Paiement égal",
    "equal_principal": "Principal égal",
    "compute": "Calculer",
    "monthly": "Mensuel",
    "total": "Total​",
    "interest": "Intérêts totaux",
    "first_month": "Premier mois",
    "schedule": "Calendrier de remboursement complet",
    "period": "Période",
    "payment": "Paiement",
    "principal_part": "Principal​",
    "interest_part": "Intérêts",
    "remaining": "Solde",
    "export_csv": "Exporter CSV",
    "invalid": "Entrez un principal, un taux et une durée valides.",
    "disclaimer": "Calculé avec un taux annuel fixe pour la planification uniquement. Votre contrat et la déclaration du prêteur prévalent."
  },
  "gb_code": {
    "search": "Rechercher un caractère ou un code"
  },
  "solar_lunar": {
    "year": "Année",
    "month": "Mois",
    "day": "Jour",
    "convert": "Convertir"
  },
  "world_clock": {},
  "chem_balance": {
    "input": "Équation chimique (par exemple H2+O2=H2O)",
    "balance": "Solde"
  },
  "mic_test": {
    "enumerate": "Énumérer les appareils",
    "default": "Appareil par défaut",
    "device": "Appareil",
    "status_label": "Statut",
    "status_idle": "Inactif",
    "status_granted": "Accordé",
    "status_denied": "Refusé",
    "status_recording": "Enregistrement",
    "status_playing": "Lecture",
    "record": "Démarrer l'enregistrement",
    "stop": "Arrêter l'enregistrement",
    "play": "Lecture de l'enregistrement",
    "download": "Télécharger l'enregistrement",
    "duration": "Durée",
    "volume": "Volume​"
  },
  "keyboard_test": {
    "hint": "Appuyez sur n'importe quelle touche de votre clavier pour tester",
    "current": "Touche actuelle",
    "history": "Historique des touches"
  },
  "screen_test": {
    "color_red": "Rouge",
    "color_green": "Vert",
    "color_blue": "Bleu",
    "color_white": "Blanc",
    "color_black": "Noir",
    "click_exit": "Cliquez ou appuyez sur ESC pour quitter le plein écran",
    "screen_info": "Informations sur l'écran",
    "resolution": "Résolution",
    "available": "Disponible",
    "pixel_ratio": "Rapport de pixels",
    "esc_hint": "Appuyez sur ESC pour quitter le mode plein écran"
  },
  "pfx_to_pem": {
    "select_file": "Sélectionnez Fichier PFX/P12",
    "password": "Mot de passe",
    "parse": "Analyser",
    "parsing": "Analyse...",
    "cert_pem": "Certificat PEM",
    "key_pem": "Clé privée PEM",
    "download": "Télécharger",
    "parse_error": "Échec de l'analyse",
    "no_content": "Aucun certificat ou clé privée trouvée",
    "forge_required": "La bibliothèque node-forge n'est requise"
  },
  "http_request": {
    "headers": "En-têtes",
    "add_header": "Ajouter un en-tête",
    "body": "Corps",
    "send": "Envoyer",
    "sending": "Envoi...",
    "cors_warning": "Remarque : la politique CORS du navigateur peut limiter certaines requêtes ; seuls les points de terminaison compatibles CORS sont pris en charge",
    "status": "Statut",
    "status_text": "Texte d'état",
    "time": "Heure",
    "response_headers": "En-têtes de réponse",
    "response_body": "Corps de réponse"
  },
  "doodle": {
    "color": "Couleur",
    "size": "Taille du pinceau",
    "eraser": "Gomme",
    "undo": "Annuler",
    "clear": "Effacer",
    "download": "Télécharger PNG",
    "reset": "Réinitialiser Canvas"
  },
  "modpow": {
    "base": "Base​",
    "exponent": "Exposant",
    "modulus": "Module",
    "calc": "Calculer",
    "result": "Résultat :",
    "err_modulus_zero": "Le module ne peut pas être 0",
    "err_negative_exp": "L'exposant ne peut pas être négatif",
    "err_invalid": "Entrée invalide, veuillez saisir des entiers",
    "note": "L'exponentiation modulaire est largement utilisée dans le cryptage RSA, l'échange de clés Diffie-Hellman, la cryptographie à courbe elliptique, etc. Cet outil utilise BigInt avec l'algorithme de carré et de multiplication, prenant en charge entiers arbitrairement grands."
  },
  "bit_reverse": {
    "input_label": "Saisie d'un entier positif",
    "width_label": "Largeur de bits",
    "calc": "Calculer",
    "step_original": "Binaire d'origine :",
    "step_reversed": "Binaire inversé :",
    "result_dec": "Résultat (décimal) :",
    "result_hex": "Résultat (hexadécimal) :",
    "err_negative": "Veuillez saisir un entier non négatif",
    "err_invalid": "Entrée invalide"
  },
  "punctuation": {
    "cn2en": "CN → FR",
    "en2cn": "FR → CN",
    "input_label": "Saisir du texte",
    "convert": "Convertir",
    "output_label": "Sortie",
    "copy": "Copier",
    "copied": "Copié"
  },
  "leap_year": {
    "mode_single": "Année unique",
    "mode_range": "Gamme",
    "year_label": "Année",
    "start_label": "Année de début",
    "end_label": "Fin d'année",
    "check": "Vérifier",
    "is_leap": "L'année {year} est une année bissextile",
    "not_leap": "L'année {year} n'est pas une année bissextile",
    "range_result": "{count} années bissextiles entre {start} et {end} :",
    "err_invalid": "Veuillez saisir une année valide",
    "err_range": "Veuillez saisir des années de début et de fin valides",
    "rule": "Règle des années bissextiles : Une année divisible par 4 est une année bissextile, sauf si elle est divisible par 100 mais pas par 400. Par exemple : 2000 est une année bissextile, 1900 ne l'est pas, 2024 is."
  },
  "reverse": {
    "mode_char": "Caractère inversé",
    "mode_line": "Ligne inversée",
    "input_label": "Saisir du texte",
    "action": "Inverse",
    "output_label": "Sortie",
    "copy": "Copier",
    "copied": "Copié"
  },
  "reaction_test": {
    "click_start": "Cliquez pour démarrer",
    "wait_green": "Attendez le vert…",
    "click_now": "Cliquez maintenant !",
    "your_time": "Votre temps de réaction : {ms} ms",
    "too_early": "Trop tôt ! Attendez le signal vert.",
    "try_again": "Réessayez",
    "stats_title": "Statistiques",
    "avg": "Moyenne",
    "best": "Meilleur",
    "worst": "Pire",
    "history_title": "Historique (10 derniers)"
  },
  "ipv4_ipv6": {
    "input_label": "Entrer l'adresse",
    "mode_auto": "Auto​",
    "mode_ipv4": "IPv4​",
    "mode_ipv6": "IPv6​",
    "invalid_ipv4": "Adresse IPv4 invalide",
    "invalid_ipv6": "Adresse IPv6 invalide",
    "invalid_input": "Entrée d'adresse invalide",
    "mapped": "IPv6 mappé",
    "mapped_hex": "IPv6 mappé (Hex)",
    "compatible": "Compatible IPv4",
    "compatible_hex": "Compatible IPv4 (Hex)",
    "six_to_four": "Adresse 6to4",
    "expanded": "Entièrement développée",
    "compressed": "Compressée",
    "extracted_ipv4": "IPv4 extrait",
    "no_ipv4_mapping": "Cette adresse IPv6 ne contient pas de mappage IPv4",
    "batch_placeholder": "Un IPv4 ou IPv6 par ligne\n192.168.1.1\n::ffff:192.168.1.1\n2002:c0a8:0101::",
    "first_line_hint": "La première ligne montre la conversion détaillée ; plusieurs lignes génèrent le tableau de lots ci-dessous.",
    "batch_results": "Résultats de l'analyse par lots",
    "copy_batch": "Copier les résultats par lots",
    "col_input": "Entrée",
    "col_type": "Type​",
    "col_output": "Résultat converti/extrait",
    "col_note": "Remarque",
    "invalid": "Invalide",
    "batch_note_ipv4": "IPv6 généré mappé IPv4 pour les journaux et la configuration à double pile.",
    "batch_note_extractable": "Cet IPv6 contient des informations IPv4 extractibles.",
    "batch_note_no_mapping": "IPv6 standard ne contient pas d'IPv4 et ne peut pas être directement reconverti."
  },
  "code_formatter": {
    "language": "Langue",
    "indent_size": "Taille du retrait",
    "wrap_length": "Longueur d'enveloppe",
    "input_label": "Code d'entrée",
    "input_placeholder": "Coller le code…",
    "format": "Format​",
    "output_label": "Formaté Sortie",
    "copy": "Copier",
    "copied": "Copié"
  },
  "port_check": {
    "host_label": "Nom d'hôte/IP",
    "port_label": "Port​",
    "check": "Vérifier",
    "check_common": "Vérification des ports communs",
    "th_port": "Port​",
    "th_service": "Service​",
    "th_status": "Statut",
    "status_checking": "Vérification…",
    "status_open": "Ouvrir",
    "status_closed": "Fermé",
    "status_timeout": "Temps mort",
    "status_error": "Erreur",
    "limitation_note": "Remarque : En raison des restrictions de sécurité CORS du navigateur, les résultats de la vérification des ports sont uniquement à titre de référence. Cela utilise le mode fetch sans cors ; une réponse opaque suggère que le service répond peut-être, mais ne peut pas être confirmée. Une détection plus précise nécessite des outils côté serveur."
  },
  "auto_refresh": {
    "url_label": "URL cible",
    "interval_label": "Intervalle de rafraîchissement",
    "seconds": "secondes (min 5s)",
    "start": "Début",
    "stop": "Arrêter",
    "countdown": "Compte à rebours",
    "total_refreshes": "Rafraîchissements",
    "last_refresh": "Dernier rafraîchissement",
    "preview": "Aperçu de la page",
    "bookmarklet_title": "Bookmarklet​",
    "bookmarklet_desc": "Faites glisser le bouton ci-dessous vers votre barre de favoris pour utiliser l'actualisation automatique sur n'importe quelle page.",
    "bookmarklet_btn": "Actualisation automatique du signet"
  },
  "text_to_html_table": {
    "inputLabel": "Saisissez le texte (CSV/TSV)",
    "placeholder": "Nom, Âge, Ville\nAlice, 25 ans, Pékin\nBob, 30 ans, Shanghai",
    "delimiter": "Délimiteur",
    "hasHeader": "Ligne d'en-tête",
    "border": "Bordure",
    "padding": "Remplissage de cellule",
    "className": "Nom de la classe CSS",
    "htmlCode": "Code HTML",
    "copy": "Copier le code",
    "copied": "Copié",
    "preview": "Aperçu"
  },
  "font_preview": {
    "textLabel": "Texte d'aperçu",
    "fontSize": "Taille de la police",
    "customFont": "Police personnalisée"
  },
  "symbols": {
    "search": "Rechercher",
    "searchPlaceholder": "Rechercher un symbole ou un nom…"
  },
  "rc4": {
    "key": "Clé",
    "mode": "Mode​",
    "encrypt": "Crypter",
    "decrypt": "Déchiffrer",
    "plaintext": "Texte brut",
    "ciphertext": "Texte chiffré",
    "inputEnc": "Encodage d'entrée",
    "outputEnc": "Encodage de sortie",
    "result": "Résultat",
    "keyRequired": "La clé est requise",
    "inputRequired": "L'entrée est requise"
  },
  "clipboard_viewer": {
    "read": "Lire le Presse-papiers",
    "hint": "Nécessite l'autorisation du navigateur. En cas de refus, utilisez la zone de collage ci-dessous.",
    "pasteArea": "Zone de collage (Ctrl+V)",
    "pasteItems": "Contenu collé"
  },
  "svg_editor": {
    "tool": "Outil",
    "add": "Ajouter une forme",
    "properties": "Propriétés",
    "delete": "Supprimer la sélection",
    "svgCode": "Code SVG",
    "copy": "Copier",
    "copied": "Copié"
  }
}
