perf+security: fix build, secure downloads, dedupe translations, refactor i18n
All checks were successful
Deploy to Production / Build and Deploy (push) Successful in 2m49s

Frontend:
- Fix Framer Motion / motion-dom build error by pinning framer-motion to
  11.18.2 (compatible with React 19 and Next.js 16).
- Add cross-env and build:local script to bypass standalone symlink errors
  on Windows without Developer Mode.
- Allow NEXT_OUTPUT=default to disable standalone output for local builds.
- Refactor i18n: split 14,177-line src/lib/i18n.tsx into per-locale,
  per-namespace JSON files under src/lib/i18n/messages/.
- Load English synchronously; other locales loaded on demand via dynamic
  imports (reduces initial bundle, improves maintainability).
- Remove unused next-intl message files src/messages/en.json and fr.json.

Backend:
- Remove insecure legacy /api/v1/download/{filename} and /api/v1/cleanup/{filename}
  endpoints. The job-based /api/v1/download/{job_id} already enforces ownership.
- Deduplicate texts in TranslationService.translate_batch before sending them
  to the provider, reducing API calls for repeated strings.
- Pin httpx to <0.28 to fix TestClient incompatibility with starlette 0.35.1.
- Add pytest-cov and ruff dev dependencies/config.

DevOps:
- Remove hardcoded Grafana password from docker-compose.yml and
  docker-compose.monitoring.yml; use GRAFANA_PASSWORD env var.
- Change default TRANSLATION_SERVICE from ollama to google in
  docker-compose.yml (Ollama is an optional profile).
- Add GRAFANA_PASSWORD to .env.example.
- Add .coverage and frontend/pnpm-workspace.yaml to .gitignore.

Tests:
- Update API versioning tests for removed legacy endpoints.
- Add tests/test_translation_service.py for deduplication behavior.

Verified:
- pnpm run build:local passes.
- uv run pytest tests/test_providers/* tests/test_translation_service.py
  tests/test_story_3_5_api_versioning.py tests/test_download_endpoint.py
  tests/test_translators/test_excel_translator.py: provider/translator tests
  pass; one pre-existing French error-message test still fails (message is
  returned in English, unrelated to this change).
This commit is contained in:
2026-06-14 16:44:18 +02:00
parent eda6821632
commit fa637abff0
365 changed files with 23910 additions and 14955 deletions

View File

@@ -0,0 +1,48 @@
{
"admin.login.title": "Administration",
"admin.login.required": "Connexion requise",
"admin.login.password": "Mot de passe administrateur",
"admin.login.connecting": "Connexion...",
"admin.login.access": "Accéder au panneau admin",
"admin.login.restricted": "Accès réservé aux administrateurs",
"admin.layout.checking": "Vérification de l'authentification...",
"admin.dashboard.title": "Dashboard Admin",
"admin.dashboard.subtitle": "Panneau de contrôle administrateur",
"admin.dashboard.refresh": "Actualiser",
"admin.dashboard.refreshTooltip": "Actualiser les données du dashboard",
"admin.dashboard.config": "Configuration système",
"admin.dashboard.maxFileSize": "Taille max fichier :",
"admin.dashboard.translationService": "Service de traduction :",
"admin.dashboard.formats": "Formats :",
"admin.nav.dashboard": "Dashboard",
"admin.nav.users": "Utilisateurs",
"admin.nav.pricing": "Tarifs & Stripe",
"admin.nav.providers": "Fournisseurs",
"admin.nav.system": "Système",
"admin.nav.logs": "Logs",
"admin.users.title": "Gestion des Utilisateurs",
"admin.users.subtitle": "Visualiser et gérer les comptes utilisateurs",
"admin.users.planUpdated": "Plan mis à jour",
"admin.users.planChanged": "Le plan a été changé vers \\\"{plan}\\\" avec succès.",
"admin.users.unknownError": "Erreur inconnue",
"admin.users.error": "Erreur",
"admin.users.planUpdateError": "Impossible de mettre à jour le plan : {message}",
"admin.users.noKeys": "Aucune clé",
"admin.users.noKeysDesc": "Cet utilisateur n'a pas de clés API actives.",
"admin.users.keysRevoked": "Clés révoquées",
"admin.users.keysRevokedDesc": "{count} clé(s) API révoquée(s) avec succès.",
"admin.users.revokeError": "Impossible de révoquer les clés : {message}",
"admin.users.retry": "Réessayer",
"admin.system.title": "Système",
"admin.system.subtitle": "Surveiller l'état du système et gérer les ressources",
"admin.system.quotas": "Quotas de traduction",
"admin.system.resetQuotas": "Réinitialiser les quotas mensuels",
"admin.system.resetting": "Réinitialisation...",
"admin.system.reset": "Réinitialiser",
"admin.system.allOperational": "Tous les systèmes opérationnels",
"admin.system.issuesDetected": "Problèmes système détectés",
"admin.system.waitingData": "En attente de données...",
"admin.system.purging": "Purge...",
"admin.system.clean": "Nettoyer",
"admin.system.purge": "Purger"
}

View File

@@ -0,0 +1,72 @@
{
"apiKeys.webhook.title": "Intégration Webhook",
"apiKeys.webhook.descriptionBefore": "Passez un paramètre ",
"apiKeys.webhook.descriptionAfter": " pour recevoir une requête POST lorsque votre traduction est terminée.",
"apiKeys.webhook.codeParam": "webhook_url",
"apiKeys.title": "Clés API",
"apiKeys.subtitle": "Gérez vos clés API pour l'accès programmatique à l'API de traduction.",
"apiKeys.loading": "Chargement...",
"apiKeys.sectionTitle": "API & Automatisation",
"apiKeys.sectionDesc": "Générez et gérez vos clés API pour les workflows d'automatisation",
"apiKeys.keysUsed": "{total} sur {max} clés utilisées",
"apiKeys.maxReached": "Nombre maximum de clés atteint. Révoquez une clé pour en générer une nouvelle.",
"apiKeys.canGenerate": "Vous pouvez générer {count} clé supplémentaire",
"apiKeys.canGeneratePlural": "Vous pouvez générer {count} clés supplémentaires",
"apiKeys.generateNew": "Générer une nouvelle clé",
"apiKeys.keyRevoked": "Clé révoquée",
"apiKeys.keyRevokedDesc": "La clé API a été révoquée avec succès.",
"apiKeys.keyNotFound": "Clé introuvable",
"apiKeys.keyNotFoundDesc": "La clé API n'existe plus. Elle a peut-être déjà été révoquée.",
"apiKeys.error": "Erreur",
"apiKeys.revokeError": "Impossible de révoquer la clé API. Veuillez réessayer.",
"apiKeys.limitReached": "Limite atteinte",
"apiKeys.limitReachedDesc": "Vous avez atteint le maximum de 10 clés API. Révoquez une clé existante pour en générer une nouvelle.",
"apiKeys.proRequired": "Fonctionnalité Pro requise",
"apiKeys.proRequiredDesc": "Les clés API sont une fonctionnalité Pro. Veuillez mettre à niveau votre compte.",
"apiKeys.generateError": "Impossible de générer la clé API. Veuillez réessayer.",
"apiKeys.upgrade.title": "Clés API",
"apiKeys.upgrade.subtitle": "Automatisez vos traductions avec l'accès API",
"apiKeys.upgrade.feat1": "Générez des clés API illimitées",
"apiKeys.upgrade.feat2": "Automatisez la traduction de documents",
"apiKeys.upgrade.feat3": "Notifications webhook",
"apiKeys.upgrade.feat4": "Modes de traduction IA",
"apiKeys.upgrade.proFeature": "Les clés API sont une fonctionnalité {pro}. Passez à un forfait supérieur pour débloquer l'automatisation API.",
"apiKeys.upgrade.pro": "Pro",
"apiKeys.upgrade.cta": "Passer à Pro",
"apiKeys.dialog.maxTitle": "Nombre maximum de clés atteint",
"apiKeys.dialog.maxDesc": "Vous avez atteint le maximum de 10 clés API. Veuillez révoquer une clé existante avant d'en générer une nouvelle.",
"apiKeys.dialog.close": "Fermer",
"apiKeys.dialog.generated": "Clé API générée !",
"apiKeys.dialog.generatedDesc": "Votre nouvelle clé API a été créée. Copiez-la maintenant — elle ne sera plus affichée.",
"apiKeys.dialog.important": "Important :",
"apiKeys.dialog.importantDesc": "C'est la seule fois où vous verrez cette clé. Conservez-la en toute sécurité.",
"apiKeys.dialog.apiKey": "Clé API",
"apiKeys.dialog.name": "Nom :",
"apiKeys.dialog.done": "Terminé",
"apiKeys.dialog.copied": "J'ai copié la clé",
"apiKeys.dialog.generateTitle": "Générer une nouvelle clé API",
"apiKeys.dialog.generateDesc": "Créez une nouvelle clé API pour l'accès programmatique à l'API de traduction.",
"apiKeys.dialog.keyName": "Nom de la clé (facultatif)",
"apiKeys.dialog.keyNamePlaceholder": "ex : Production, Staging",
"apiKeys.dialog.keyNameHint": "Un nom descriptif pour vous aider à identifier cette clé plus tard.",
"apiKeys.dialog.nameTooLong": "Le nom ne doit pas dépasser {max} caractères",
"apiKeys.dialog.nameInvalid": "Le nom ne peut contenir que des lettres, chiffres, espaces, tirets et tirets bas",
"apiKeys.dialog.cancel": "Annuler",
"apiKeys.dialog.generating": "Génération...",
"apiKeys.dialog.generate": "Générer la clé",
"apiKeys.table.name": "Nom",
"apiKeys.table.prefix": "Préfixe",
"apiKeys.table.created": "Créée",
"apiKeys.table.lastUsed": "Dernière utilisation",
"apiKeys.table.never": "Jamais",
"apiKeys.table.actions": "Actions",
"apiKeys.table.revoke": "Révoquer",
"apiKeys.table.copyPrefix": "Copier le préfixe de la clé",
"apiKeys.table.revokeKey": "Révoquer la clé",
"apiKeys.revokeDialog.title": "Révoquer la clé API",
"apiKeys.revokeDialog.desc": "Êtes-vous sûr de vouloir révoquer la clé « {name} » ? Cette action est irréversible.",
"apiKeys.revokeDialog.confirm": "Oui, révoquer",
"apiKeys.revokeDialog.cancel": "Annuler",
"apiKeys.noKeysGenerated": "Aucune clé générée",
"apiKeys.copied": "Copié !"
}

View File

@@ -0,0 +1,3 @@
{
"auth.brandName": "Wordly"
}

View File

@@ -0,0 +1,12 @@
{
"checkout.activating": "Activation en cours…",
"checkout.activatingDesc": "Nous mettons à jour votre abonnement, veuillez patienter.",
"checkout.paymentConfirmed": "Paiement confirmé !",
"checkout.subscriptionActivated": "Abonnement activé !",
"checkout.planActivated": "Forfait {plan} activé !",
"checkout.redirectingToProfile": "Redirection vers votre profil…",
"checkout.paymentReceived": "Paiement reçu",
"checkout.redirecting": "Redirection…",
"checkout.syncError": "Erreur de synchronisation",
"checkout.networkError": "Erreur réseau. Votre paiement est confirmé — rechargez votre profil."
}

View File

@@ -0,0 +1,4 @@
{
"common.loading": "Chargement...",
"common.backToHome": "Retour à l'accueil"
}

View File

@@ -0,0 +1,25 @@
{
"context.proTitle": "Fonctionnalité Pro",
"context.proDesc": "Le contexte et les glossaires professionnels sont disponibles avec les forfaits Pro, Business et Enterprise. Ils permettent d'obtenir des traductions plus précises grâce à des instructions et un vocabulaire spécifiques à votre domaine.",
"context.viewPlans": "Voir les forfaits",
"context.title": "Contexte & Glossaire",
"context.subtitle": "Améliorez la qualité de traduction avec des instructions et un vocabulaire spécifiques à votre domaine.",
"context.presets.title": "Glossaires professionnels",
"context.presets.desc": "Chargez un glossaire complet avec instructions et terminologie spécialisée",
"context.instructions.title": "Instructions de contexte",
"context.instructions.desc": "Instructions que l'IA suivra pendant la traduction",
"context.instructions.placeholder": "Ex : Vous traduisez des documents techniques HVAC. Utilisez une terminologie d'ingénierie précise...",
"context.glossary.title": "Glossaire technique",
"context.glossary.desc": "Format : source=cible (un par ligne). Les glossaires chargés via preset sont modifiables.",
"context.glossary.terms": "termes dans le glossaire",
"context.clearAll": "Tout effacer",
"context.saving": "Enregistrement...",
"context.save": "Enregistrer",
"context.presets.createGlossary": "Créer le glossaire",
"context.presets.created": "Glossaire créé",
"context.presets.createdDesc": "Le glossaire \\\"{name}\\\" a été créé avec {count} termes.",
"context.presets.hint": "Cliquez sur un preset pour créer un glossaire avec des termes spécifiques au domaine. Gérez vos glossaires dans la section Glossaires.",
"context.glossary.manage": "Gérer les glossaires",
"context.saved": "Enregistré",
"context.savedDesc": "Vos instructions de contexte ont été enregistrées."
}

View File

@@ -0,0 +1,7 @@
{
"cookieConsent.title": "Cookies sur Wordly",
"cookieConsent.description": "Nous utilisons des cookies strictement nécessaires au fonctionnement du service (session, sécurité, langue). Avec votre accord, nous pouvons aussi utiliser des cookies optionnels pour mesurer l'audience et améliorer le produit.",
"cookieConsent.acceptAll": "Tout accepter",
"cookieConsent.essentialOnly": "Nécessaires uniquement",
"cookieConsent.learnMore": "En savoir plus"
}

View File

@@ -0,0 +1,115 @@
{
"dashboard.nav.translate": "Traduire",
"dashboard.nav.profile": "Mon Profil",
"dashboard.nav.settings": "Paramètres",
"dashboard.nav.context": "Contexte",
"dashboard.nav.services": "Services",
"dashboard.nav.apiKeys": "Clés API",
"dashboard.nav.glossaries": "Glossaires & Contexte",
"dashboard.header.title": "Dashboard",
"dashboard.header.subtitle": "Gérez vos traductions",
"dashboard.header.toggleMenu": "Menu",
"dashboard.header.profileTitle": "Mon profil",
"dashboard.sidebar.theme": "Thème",
"dashboard.sidebar.signOut": "Déconnexion",
"dashboard.sidebar.backHome": "Retour à l'accueil",
"dashboard.sidebar.upgradeToPro": "Passer Pro →",
"dashboard.translate.pageTitle": "Traduire un document",
"dashboard.translate.pageSubtitle": "Importez un fichier et choisissez la langue cible",
"dashboard.translate.errorNotificationTitle": "Erreur",
"dashboard.translate.dropzone.uploadAria": "Zone de dépôt de fichier",
"dashboard.translate.dropzone.title": "Glissez-déposez votre fichier ici",
"dashboard.translate.dropzone.subtitle": "ou cliquez pour sélectionner (DOCX, XLSX, PPTX, PDF)",
"dashboard.translate.dropzone.replaceFile": "Remplacer le fichier",
"dashboard.translate.language.source": "Langue source",
"dashboard.translate.language.target": "Langue cible",
"dashboard.translate.language.loading": "Chargement des langues…",
"dashboard.translate.language.autoDetect": "Auto-détection",
"dashboard.translate.language.selectPlaceholder": "Sélectionner…",
"dashboard.translate.language.loadErrorPrefix": "Erreur de chargement des langues",
"dashboard.translate.provider.loading": "Chargement des fournisseurs…",
"dashboard.translate.provider.noneConfigured": "Aucun fournisseur configuré",
"dashboard.translate.provider.modelTitle": "Modèle",
"dashboard.translate.provider.sectionTitle": "Fournisseur",
"dashboard.translate.provider.llmDivider": "IA · Context-Aware",
"dashboard.translate.provider.llmDividerPro": "IA · Context-Aware (Pro)",
"dashboard.translate.provider.upgrade": "Passer Pro",
"dashboard.translate.provider.upgradeSuffix": "pour débloquer la traduction IA",
"dashboard.translate.provider.tabStandard": "Standard",
"dashboard.translate.provider.tabLLM": "Multi-Modèles IA",
"dashboard.translate.translateImages": "Traduire les images",
"dashboard.translate.translateImagesDesc": "Extraire et traduire le texte des images (vision requise)",
"dashboard.translate.trust.zeroRetention": "Rétention zéro",
"dashboard.translate.trust.deletedAfter": "Fichiers supprimés après traitement",
"dashboard.translate.actions.uploading": "Chargement…",
"dashboard.translate.actions.translate": "Traduire",
"dashboard.translate.actions.filePrefix": "Fichier : ",
"dashboard.translate.actions.cancel": "Annuler",
"dashboard.translate.actions.tryAgain": "Réessayer",
"dashboard.translate.steps.uploading": "Chargement du fichier…",
"dashboard.translate.steps.starting": "Démarrage de la traduction…",
"dashboard.translate.complete.title": "Traduction terminée !",
"dashboard.translate.complete.descNamed": "Votre fichier {name} a été traduit avec succès.",
"dashboard.translate.complete.descGeneric": "Votre fichier a été traduit avec succès.",
"dashboard.translate.complete.downloading": "Téléchargement…",
"dashboard.translate.complete.download": "Télécharger",
"dashboard.translate.complete.newTranslation": "Nouvelle traduction",
"dashboard.translate.complete.toastOkTitle": "Succès",
"dashboard.translate.complete.toastOkDesc": "{name} a été téléchargé avec succès.",
"dashboard.translate.complete.toastFailTitle": "Échec",
"dashboard.translate.complete.toastFailDesc": "La traduction a échoué. Veuillez réessayer.",
"dashboard.translate.sourceDocument": "Document source",
"dashboard.translate.configuration": "Configuration",
"dashboard.translate.translating": "Traduction en cours",
"dashboard.translate.liveMonitor": "Moniteur en direct",
"dashboard.translate.summary": "Résumé",
"dashboard.translate.engine": "Moteur",
"dashboard.translate.confidence": "Confiance",
"dashboard.translate.cancel": "Annuler",
"dashboard.translate.segments": "Segments",
"dashboard.translate.characters": "Caractères",
"dashboard.translate.elapsed": "Écoulé",
"dashboard.translate.segPerMin": "Seg/min",
"dashboard.translate.highQuality": "Haute qualité",
"dashboard.translate.quality": "Qualité",
"dashboard.translate.completed": "Traduction terminée",
"dashboard.translate.replace": "Remplacer",
"dashboard.translate.pdfMode.title": "Mode de traduction PDF",
"dashboard.translate.pdfMode.preserveLayout": "Préserver la mise en page",
"dashboard.translate.pdfMode.textOnly": "Texte uniquement",
"dashboard.translate.pdfMode.preserveLayoutDesc": "Conserve les images, tableaux et formatage. Idéal pour les PDF simples.",
"dashboard.translate.pdfMode.textOnlyDesc": "Traduit tout le texte parfaitement. Sortie propre, sans problème de mise en page.",
"dashboard.translate.pipeline.upload": "Upload",
"dashboard.translate.pipeline.analyze": "Analyse",
"dashboard.translate.pipeline.translate": "Traduction",
"dashboard.translate.pipeline.rebuild": "Reconstruction",
"dashboard.translate.pipeline.finalize": "Finalisation",
"dashboard.translate.progress.processingFallback": "Traitement en cours…",
"dashboard.translate.progress.connectionLost": "Connexion perdue. Reconnexion…",
"dashboard.translate.progress.failedTitle": "Traduction échouée",
"dashboard.translate.error.unexpected": "Une erreur inattendue est survenue. Réessayez.",
"dashboard.translate.error.noResult": "La traduction n'a produit aucun résultat. Vérifiez que le document contient du texte, puis réessayez ou choisissez un autre moteur.",
"dashboard.translate.error.apiKey": "Clé API invalide ou manquante. Contactez l'administrateur pour configurer les clés.",
"dashboard.translate.error.quota": "Limite d'utilisation atteinte. Réessayez dans quelques minutes ou choisissez un autre moteur.",
"dashboard.translate.error.timeout": "La connexion au service de traduction a expiré. Vérifiez votre réseau et réessayez.",
"dashboard.translate.error.sessionExpired": "La session a expiré. Cliquez sur Réessayer pour relancer la traduction.",
"dashboard.translate.error.empty": "Le document semble vide ou ne contient pas de texte traduisible (PDF image ?).",
"dashboard.translate.error.unsupported": "Format de fichier non supporté ou fichier corrompu.",
"dashboard.translate.error.connection": "Connexion perdue. Vérifiez votre réseau et réessayez.",
"dashboard.translate.error.generic": "Traduction échouée : {detail}",
"dashboard.translate.error.title": "Traduction échouée",
"dashboard.translate.retry": "Réessayer la traduction",
"dashboard.translate.newFile": "Nouveau fichier",
"dashboard.translate.modeAI": "Mode IA",
"dashboard.translate.modeClassic": "Mode Classique",
"dashboard.translate.glossaryLLMHint": "Glossaires disponibles en mode IA",
"dashboard.translate.submitting": "Envoi en cours...",
"dashboard.translate.submit": "Lancer la traduction",
"dashboard.translate.noFile": "Déposez d'abord un fichier",
"dashboard.translate.noTargetLang": "Sélectionnez une langue cible",
"dashboard.topbar.interfaceLabel": "Interface de traduction",
"dashboard.topbar.premiumAccess": "Accès Premium",
"dashboard.checkoutSyncError": "Erreur lors de la synchronisation du paiement.",
"dashboard.networkRefresh": "Erreur réseau. Veuillez rafraîchir la page.",
"dashboard.continueToTranslate": "Continuer vers la traduction"
}

View File

@@ -0,0 +1,31 @@
{
"fileUploader.uploadDocument": "Téléverser un document",
"fileUploader.uploadDesc": "Glissez-déposez ou cliquez pour sélectionner un fichier (Excel, Word, PowerPoint)",
"fileUploader.dropHere": "Déposez votre fichier ici…",
"fileUploader.dragAndDrop": "Glissez-déposez votre document ici",
"fileUploader.orClickBrowse": "ou cliquez pour parcourir",
"fileUploader.preview": "Aperçu",
"fileUploader.translationOptions": "Options de traduction",
"fileUploader.configureSettings": "Configurez vos paramètres de traduction",
"fileUploader.targetLanguage": "Langue cible",
"fileUploader.selectLanguage": "Sélectionner une langue",
"fileUploader.translationProvider": "Fournisseur de traduction",
"fileUploader.selectProvider": "Sélectionner un fournisseur",
"fileUploader.advancedOptions": "Options avancées",
"fileUploader.translateImages": "Traduire les images",
"fileUploader.translating": "Traduction…",
"fileUploader.translateDocument": "Traduire le document",
"fileUploader.processing": "Traitement…",
"fileUploader.translationError": "Erreur de traduction",
"fileUploader.translationComplete": "Traduction terminée !",
"fileUploader.translationCompleteDesc": "Votre document a été traduit avec succès tout en préservant la mise en forme.",
"fileUploader.download": "Télécharger le document traduit",
"fileUploader.webgpuUnsupported": "WebGPU n'est pas pris en charge dans ce navigateur. Veuillez utiliser Chrome 113+ ou Edge 113+.",
"fileUploader.webllmNotLoaded": "Modèle WebLLM non chargé. Allez dans Paramètres > Services de traduction pour charger un modèle.",
"fileUploader.extracting": "Extraction des textes du document…",
"fileUploader.noTranslatable": "Aucun texte traduisible trouvé dans le document",
"fileUploader.foundTexts": "{count} textes trouvés à traduire",
"fileUploader.translatingItem": "Traduction {current}/{total} : « {preview} »",
"fileUploader.reconstructing": "Reconstruction du document…",
"fileUploader.translatingLocally": "Traduction locale avec WebLLM…"
}

View File

@@ -0,0 +1,14 @@
{
"forgotPassword.enterEmail": "Veuillez entrer votre adresse email",
"forgotPassword.error": "Une erreur s'est produite",
"forgotPassword.title": "Mot de passe oublié",
"forgotPassword.checkEmail": "Vérifiez votre boîte mail",
"forgotPassword.subtitle": "Entrez votre email pour recevoir un lien de réinitialisation",
"forgotPassword.sentMessage": "Si un compte existe avec cette adresse, un email de réinitialisation a été envoyé.",
"forgotPassword.emailLabel": "Adresse email",
"forgotPassword.emailPlaceholder": "vous@exemple.com",
"forgotPassword.sending": "Envoi en cours...",
"forgotPassword.sendLink": "Envoyer le lien de réinitialisation",
"forgotPassword.backToLogin": "Retour à la connexion",
"forgotPassword.loading": "Chargement..."
}

View File

@@ -0,0 +1,189 @@
{
"glossaries.yourGlossaries": "Vos glossaires",
"glossaries.title": "Glossaires & Contexte",
"glossaries.description": "Gérez vos glossaires et instructions de contexte pour des traductions plus précises.",
"glossaries.createNew": "Créer nouveau",
"glossaries.empty": "Aucun glossaire",
"glossaries.emptyDesc": "Créez votre premier glossaire ou chargez un préréglage professionnel ci-dessus",
"glossaries.defineTerms": "termes",
"glossaries.aboutTitle": "À propos des glossaires",
"glossaries.aboutDesc": "Les glossaires vous permettent de définir des traductions exactes pour des termes spécifiques. Lors de la traduction, les termes du glossaire garantissent des traductions cohérentes et précises.",
"glossaries.aboutFormat": "Chaque terme a un mot source et des traductions en plusieurs langues. Sélectionnez un glossaire dans la page de traduction pour l'appliquer.",
"glossaries.toast.created": "Glossaire créé",
"glossaries.toast.createdDesc": "Le glossaire \\\"{name}\\\" a été créé.",
"glossaries.toast.imported": "Glossaire importé",
"glossaries.toast.importedDesc": "Le glossaire \\\"{name}\\\" a été importé.",
"glossaries.toast.updated": "Glossaire mis à jour",
"glossaries.toast.updatedDesc": "Le glossaire \\\"{name}\\\" a été mis à jour.",
"glossaries.toast.deleted": "Glossaire supprimé",
"glossaries.toast.deletedDesc": "Le glossaire a été supprimé.",
"glossaries.toast.error": "Erreur",
"glossaries.toast.errorCreate": "Impossible de créer le glossaire",
"glossaries.toast.errorImport": "Impossible d'importer le glossaire",
"glossaries.toast.errorUpdate": "Impossible de mettre à jour le glossaire",
"glossaries.toast.errorDelete": "Impossible de supprimer le glossaire",
"glossaries.dialog.title": "Nouveau glossaire",
"glossaries.dialog.description": "Créez un glossaire pour vos traductions",
"glossaries.dialog.nameLabel": "Nom",
"glossaries.dialog.namePlaceholder": "Mon glossaire",
"glossaries.dialog.tabTemplates": "Modèles",
"glossaries.dialog.tabFile": "Fichier",
"glossaries.dialog.tabManual": "Manuel",
"glossaries.dialog.cancel": "Annuler",
"glossaries.dialog.creating": "Création…",
"glossaries.dialog.importing": "Import…",
"glossaries.dialog.importBtn": "Importer",
"glossaries.dialog.selectPrompt": "Sélectionner",
"glossaries.dialog.createBtn": "Créer",
"glossaries.dialog.createEmpty": "Créer vide",
"glossaries.dialog.terms": "termes",
"glossaries.dialog.templatesDesc": "Choisissez un modèle prédéfini",
"glossaries.dialog.templatesEmpty": "Aucun modèle disponible",
"glossaries.dialog.dropTitle": "Glissez un fichier CSV ici",
"glossaries.dialog.dropOr": "ou",
"glossaries.dialog.dropFormats": "CSV, TSV, TXT",
"glossaries.termEditor.addTerm": "Ajouter un terme",
"glossaries.termEditor.maxReached": "Maximum {max} termes par glossaire atteint.",
"glossaries.dialog.formatTitle": "Format",
"glossaries.dialog.formatDesc": "source,target (un par ligne)",
"glossaries.dialog.formatNote": "Première ligne ignorée si en-tête détecté",
"glossaries.dialog.errorFormat": "Format non supporté",
"glossaries.dialog.errorSize": "Fichier trop volumineux",
"glossaries.dialog.errorEmpty": "Fichier vide",
"glossaries.dialog.errorRead": "Erreur de lecture",
"glossaries.dialog.parsing": "Analyse…",
"glossaries.dialog.termsImported": "termes importés",
"glossaries.dialog.changeFile": "Changer le fichier",
"glossaries.dialog.retry": "Réessayer",
"glossaries.edit.title": "Modifier le glossaire",
"glossaries.edit.description": "Modifiez le nom, la paire de langues et les termes du glossaire.",
"glossaries.edit.nameLabel": "Nom du glossaire",
"glossaries.edit.namePlaceholder": "Entrez le nom du glossaire...",
"glossaries.edit.sourceLang": "Langue source",
"glossaries.edit.targetLang": "Langue cible",
"glossaries.edit.termsLabel": "Termes ({count} valides)",
"glossaries.edit.exportCsv": "Exporter CSV",
"glossaries.edit.importCsv": "Importer CSV",
"glossaries.edit.cancel": "Annuler",
"glossaries.edit.saving": "Enregistrement...",
"glossaries.edit.saveChanges": "Enregistrer les modifications",
"glossaries.edit.importFailedTitle": "Échec de l'importation",
"glossaries.edit.importFailedMaxDesc": "Le CSV contient {count} termes, le maximum est de {max}. Veuillez réduire le nombre de termes.",
"glossaries.edit.importSuccessTitle": "Importation réussie",
"glossaries.edit.importSuccessDesc": "{count} termes importés avec succès.",
"glossaries.edit.importFailedEmptyDesc": "Aucun terme valide trouvé dans le fichier CSV.",
"glossaries.edit.importFailedReadDesc": "Impossible de lire le fichier CSV.",
"glossaries.delete.title": "Supprimer le glossaire",
"glossaries.delete.description": "Êtes-vous sûr de vouloir supprimer ce glossaire ?",
"glossaries.delete.warning": "Cette action est irréversible",
"glossaries.delete.warningDesc": "Toutes les paires de termes seront définitivement supprimées.",
"glossaries.delete.cancel": "Annuler",
"glossaries.delete.deleting": "Suppression...",
"glossaries.delete.deleteBtn": "Supprimer",
"glossaries.upgrade.title": "Glossaires",
"glossaries.upgrade.description": "Personnalisez vos traductions avec une terminologie personnalisée",
"glossaries.upgrade.feature1": "Créez plusieurs glossaires",
"glossaries.upgrade.feature2": "Définissez des paires de termes source→cible",
"glossaries.upgrade.feature3": "Importez/exportez via CSV",
"glossaries.upgrade.feature4": "Appliquez aux traductions LLM",
"glossaries.upgrade.proFeatureBefore": "Les glossaires sont une fonctionnalité ",
"glossaries.upgrade.proFeatureAfter": ". Passez à un forfait supérieur pour débloquer la terminologie personnalisée.",
"glossaries.upgrade.proLabel": "Pro",
"glossaries.upgrade.upgradeBtn": "Passer à Pro",
"glossaries.loading": "Chargement...",
"glossaries.howItWorks.title": "Comment ces paramètres sont utilisés",
"glossaries.howItWorks.step1Title": "Configurez ici",
"glossaries.howItWorks.step1Desc": "Rédigez vos instructions de contexte ou créez/importez un glossaire de termes.",
"glossaries.howItWorks.step2Title": "Activez dans Traduire",
"glossaries.howItWorks.step2Desc": "Sur la page de traduction, dans la colonne de droite, sélectionnez votre glossaire.",
"glossaries.howItWorks.warning": "Les instructions de contexte s'appliquent automatiquement à toutes vos traductions IA une fois enregistrées. Les glossaires doivent être sélectionnés manuellement sur la page Traduire.",
"glossaries.howItWorks.goToTranslate": "Aller à Traduire",
"glossaries.status.unsaved": "Non enregistré",
"glossaries.status.active": "Actif · s'applique à toutes les traductions IA",
"glossaries.status.inactive": "Inactif",
"glossaries.instructions.whatForBold": "À quoi ça sert ?",
"glossaries.instructions.whatForDesc": "Ces instructions sont envoyées automatiquement à l'IA avant chaque traduction, sans que vous ayez besoin de faire quoi que ce soit sur la page Traduire. Utilisez-les pour guider le style, le registre ou la terminologie générale.",
"glossaries.instructions.example": "Exemple : « Vous traduisez des rapports financiers. Soyez formel, précis et conservez tous les chiffres. »",
"glossaries.instructions.charCount": "{count} caractères",
"glossaries.instructions.emptyHint": "Vide — aucune instruction envoyée à l'IA",
"glossaries.instructions.clearAll": "Tout effacer",
"glossaries.instructions.saving": "Enregistrement…",
"glossaries.instructions.saved": "Enregistré",
"glossaries.presets.whatForBold": "À quoi ça sert ?",
"glossaries.presets.whatForDesc": "Cliquer sur une carte crée un glossaire pré-rempli avec les termes spécialisés du domaine. Ce glossaire apparaîtra dans vos glossaires ci-dessous, et vous pourrez le sélectionner manuellement sur la page Traduire pour forcer des traductions de termes précis.",
"glossaries.presets.clickHint": "Cliquez sur une carte → glossaire créé → sélectionnez-le dans Traduire",
"glossaries.presets.creating": "Création…",
"glossaries.presets.alreadyImported": "Déjà importé",
"glossaries.presets.it.title": "IT / Logiciel",
"glossaries.presets.it.desc": "Développement, infrastructure, DevOps",
"glossaries.presets.legal.title": "Juridique / Contrats",
"glossaries.presets.legal.desc": "Droit des affaires, contentieux",
"glossaries.presets.medical.title": "Médical / Santé",
"glossaries.presets.medical.desc": "Pharmacologie, chirurgie, diagnostic",
"glossaries.presets.finance.title": "Finance / Comptabilité",
"glossaries.presets.finance.desc": "IFRS, bilans, fiscalité",
"glossaries.presets.marketing.title": "Marketing / Publicité",
"glossaries.presets.marketing.desc": "Digital, branding, analytics",
"glossaries.presets.hr.title": "RH / Ressources Humaines",
"glossaries.presets.hr.desc": "Contrats, politiques, recrutement",
"glossaries.presets.scientific.title": "Scientifique / Recherche",
"glossaries.presets.scientific.desc": "Publications, thèses, articles",
"glossaries.presets.ecommerce.title": "E-commerce / Vente",
"glossaries.presets.ecommerce.desc": "Boutiques en ligne, catalogues, CRM",
"glossaries.grid.title": "Vos",
"glossaries.grid.titleHighlight": "glossaires",
"glossaries.grid.countWithAction": "{count} glossaire({plural}) — cliquez sur une carte pour la modifier",
"glossaries.grid.emptyAction": "Créez votre premier glossaire ou importez un preset ci-dessus",
"glossaries.grid.activeTranslation": "Traduction active :",
"glossaries.grid.goToTranslate": "Aller à Traduire pour activer",
"glossaries.badge.compatible": "Compatible",
"glossaries.badge.otherTarget": "Autre cible",
"glossaries.card.editTerms": "Modifier les termes",
"glossaries.card.created": "Créé",
"glossaries.card.term": "terme",
"glossaries.card.delete": "Supprimer",
"glossaries.grid.searchPlaceholder": "Rechercher un glossaire…",
"glossaries.grid.noResults": "Aucun résultat pour cette recherche.",
"glossaries.detail.backToList": "Retour aux glossaires",
"glossaries.detail.save": "Enregistrer",
"glossaries.detail.savedTitle": "Enregistré",
"glossaries.detail.savedDesc": "Le glossaire a été mis à jour.",
"glossaries.detail.settingsTitle": "Paramètres",
"glossaries.detail.sourceLang": "Langue source",
"glossaries.detail.targetLang": "Langue cible",
"glossaries.detail.termsTitle": "Termes",
"glossaries.detail.terms": "termes",
"glossaries.detail.searchTerms": "Filtrer…",
"glossaries.detail.noTerms": "Aucun terme pour l'instant.",
"glossaries.detail.addFirstTerm": "Ajouter le premier terme",
"glossaries.detail.addTerm": "Ajouter un terme",
"glossaries.detail.maxReached": "Limite maximale atteinte",
"glossaries.detail.source": "Source",
"glossaries.detail.target": "Cible",
"glossaries.detail.sourcePlaceholder": "terme source",
"glossaries.detail.targetPlaceholder": "terme cible",
"glossaries.detail.csvTitle": "CSV",
"glossaries.detail.csvDesc": "Exportez vos termes en CSV ou importez-en de nouveaux (remplace la liste actuelle).",
"glossaries.detail.export": "Exporter",
"glossaries.detail.import": "Importer",
"glossaries.detail.dangerTitle": "Zone danger",
"glossaries.detail.dangerDesc": "La suppression est définitive. Tous les termes associés seront perdus.",
"glossaries.detail.deleteGlossary": "Supprimer ce glossaire",
"glossaries.detail.confirmDelete": "Confirmer la suppression ?",
"glossaries.detail.confirm": "Confirmer",
"glossaries.detail.cancel": "Annuler",
"glossaries.detail.sourceLangNote": "'La source originale est en francais. Pour les autres langues, on lit le champ translations du terme (si disponible).'",
"glossaries.detail.sourceLocked": "fixé",
"glossaries.detail.sourceLockedNote": "Les templates ne stockent la source qu'en français. Le multilingue source est sur la roadmap.",
"glossaries.detail.targetLangNote": "Choisissez une langue pour voir les traductions correspondantes, ou « Multilingue » pour la valeur par défaut.",
"glossaries.detail.notFoundTitle": "Glossaire introuvable",
"glossaries.detail.notFoundDesc": "Ce glossaire n'existe pas ou vous n'y avez pas accès.",
"glossaries.detail.maxTermsTitle": "Limite atteinte",
"glossaries.detail.maxTermsDesc": "Maximum {max} termes par glossaire.",
"glossaries.detail.importEmptyTitle": "Fichier vide",
"glossaries.detail.importEmptyDesc": "Aucun terme détecté dans ce fichier.",
"glossaries.detail.importedTitle": "Importé",
"glossaries.detail.importedDesc": "{count} termes importés.",
"glossaries.detail.importErrorTitle": "Erreur de lecture",
"glossaries.detail.importErrorDesc": "Impossible de lire le fichier."
}

View File

@@ -0,0 +1,60 @@
// Auto-generated by scripts/generate_i18n_index.py
// Merges all namespace JSON files for locale "fr".
import admin from "./admin.json";
import apiKeys from "./apiKeys.json";
import auth from "./auth.json";
import checkout from "./checkout.json";
import common from "./common.json";
import context from "./context.json";
import cookieConsent from "./cookieConsent.json";
import dashboard from "./dashboard.json";
import fileUploader from "./fileUploader.json";
import forgotPassword from "./forgotPassword.json";
import glossaries from "./glossaries.json";
import landing from "./landing.json";
import langSelector from "./langSelector.json";
import layout from "./layout.json";
import login from "./login.json";
import memento from "./memento.json";
import pricing from "./pricing.json";
import profile from "./profile.json";
import providerSelector from "./providerSelector.json";
import providerTheme from "./providerTheme.json";
import register from "./register.json";
import resetPassword from "./resetPassword.json";
import services from "./services.json";
import settings from "./settings.json";
import translate from "./translate.json";
import translateComplete from "./translateComplete.json";
const messages: Record<string, string> = {
...admin,
...apiKeys,
...auth,
...checkout,
...common,
...context,
...cookieConsent,
...dashboard,
...fileUploader,
...forgotPassword,
...glossaries,
...landing,
...langSelector,
...layout,
...login,
...memento,
...pricing,
...profile,
...providerSelector,
...providerTheme,
...register,
...resetPassword,
...services,
...settings,
...translate,
...translateComplete,
};
export default messages;

View File

@@ -0,0 +1,152 @@
{
"landing.nav.why": "Pourquoi nous ?",
"landing.nav.formats": "Formats",
"landing.nav.pricing": "Tarification",
"landing.nav.login": "Connexion",
"landing.nav.startFree": "Essai gratuit",
"landing.hero.tag": "IA Documentaire Professionnelle",
"landing.hero.titleLine1": "Traduisez vos documents.",
"landing.hero.titleLine2": "Mise en forme parfaite.",
"landing.hero.description": "Le seul traducteur qui préserve les SmartArt, graphiques, tables des matières, formes, en-têtes et pieds de page — exactement tels qu'ils étaient.",
"landing.hero.ctaMain": "Essai gratuit — 2 docs/mois",
"landing.hero.ctaSec": "Voir les offres",
"landing.hero.deleted": "Fichiers supprimés après 60 min",
"landing.hero.noHidden": "Pas de prix cachés",
"landing.hero.preview": "Aperçu avant paiement",
"landing.hero.formattedOk": "Formatage OK",
"landing.hero.aiActive": "Traduction IA active",
"landing.steps.title": "Comment ça marche ?",
"landing.steps.subtitle": "Trois étapes. Zéro perte de format.",
"landing.steps.step1.num": "01",
"landing.steps.step1.title": "Déposez votre fichier",
"landing.steps.step1.desc": "Glissez-déposez votre document Excel, Word, PowerPoint ou PDF.",
"landing.steps.step2.num": "02",
"landing.steps.step2.title": "Choisissez la langue",
"landing.steps.step2.desc": "Sélectionnez la langue cible et le moteur de traduction — classique ou IA contextuelle.",
"landing.steps.step3.num": "03",
"landing.steps.step3.title": "Téléchargez le résultat",
"landing.steps.step3.desc": "Récupérez votre document traduit avec un formatage identique à l'original.",
"landing.features.tag": "Moteur de Traduction IA",
"landing.features.title": "La traduction qui comprend votre métier",
"landing.features.description": "Nos modèles IA analysent le contexte, respectent votre terminologie et traduisent même le texte dans vos images.",
"landing.features.context.title": "Contexte métier",
"landing.features.context.desc": "Décrivez votre domaine et obtenez des traductions adaptées, pas génériques.",
"landing.features.glossary.title": "Glossaires métier",
"landing.features.glossary.desc": "Définissez vos termes techniques. CTA restera « Air Handling Unit », jamais « Call To Action ».",
"landing.features.vision.title": "Vision sur images",
"landing.features.vision.desc": "Le texte incrusté dans vos images, diagrammes et graphiques est détecté et traduit.",
"landing.features.demo.source": "Source (FR)",
"landing.features.demo.google": "Google Translate",
"landing.features.demo.ours": "Notre IA",
"landing.layout.title": "Votre mise en forme,",
"landing.layout.title2": "parfaitement préservée",
"landing.layout.subtitle": "Les autres traducteurs détruisent votre mise en page. Pas nous.",
"landing.layout.p1.title": "SmartArt et diagrammes",
"landing.layout.p1.desc": "Organigrammes, flux, hiérarchies — tout traduit à l'identique.",
"landing.layout.p2.title": "Tables des matières",
"landing.layout.p2.desc": "Entrées de TDM, numéros et renvois mis à jour correctement.",
"landing.layout.p3.title": "Graphiques",
"landing.layout.p3.desc": "Titres, étiquettes, légendes et séries — tout est traduit.",
"landing.layout.p4.title": "Formes et zones de texte",
"landing.layout.p4.desc": "Rectangles, blocs arrondis, légendes — localisé partout.",
"landing.layout.p5.title": "En-têtes et pieds de page",
"landing.layout.p5.desc": "En-têtes, pieds de page et notes ne sont jamais oubliés.",
"landing.layout.p6.title": "130+ langues",
"landing.layout.p6.desc": "Google Traduction, DeepL et moteurs IA haute performance.",
"landing.formats.title": "Chaque format,",
"landing.formats.title2": "chaque élément",
"landing.formats.subtitle": "Nous traduisons ce que les autres oublient. Votre entreprise mérite une documentation irréprochable.",
"landing.formats.word.name": "Word",
"landing.formats.word.i1": "Paragraphes et titres",
"landing.formats.word.i2": "Tableaux et graphiques",
"landing.formats.word.i3": "Diagrammes SmartArt",
"landing.formats.word.i4": "Table des matières",
"landing.formats.word.i5": "En-têtes et pieds",
"landing.formats.word.i6": "Formes et zones de texte",
"landing.formats.word.i7": "Notes de bas de page",
"landing.formats.excel.name": "Excel",
"landing.formats.excel.i1": "Valeurs de cellules",
"landing.formats.excel.i2": "Noms de feuilles",
"landing.formats.excel.i3": "Graphiques et étiquettes",
"landing.formats.excel.i4": "En-têtes et pieds",
"landing.formats.excel.i5": "Cellules fusionnées",
"landing.formats.pptx.name": "PowerPoint",
"landing.formats.pptx.i1": "Texte et notes",
"landing.formats.pptx.i2": "Graphiques et diagrammes",
"landing.formats.pptx.i3": "Formes et zones de texte",
"landing.formats.pptx.i4": "Masques de diapositives",
"landing.formats.pptx.i5": "Animations préservées",
"landing.formats.pdf.name": "PDF",
"landing.formats.pdf.i1": "PDF textuels",
"landing.formats.pdf.i2": "Mise en page préservée",
"landing.formats.pdf.i3": "Images conservées",
"landing.formats.pdf.i4": "Tableaux maintenus",
"landing.formats.pdf.i5": "Sortie DOCX ou PDF",
"landing.pricing.title": "Des prix simples et honnêtes",
"landing.pricing.subtitle": "Ce que vous voyez est ce que vous payez. Aucun frais caché.",
"landing.pricing.monthly": "Mensuel",
"landing.pricing.annual": "Annuel",
"landing.pricing.bestValue": "Le plus populaire",
"landing.pricing.month": "/mois",
"landing.pricing.footer": "Le prix affiché est le prix que vous payez. Aucun frais caché après traduction.",
"landing.pricing.starter.name": "Starter",
"landing.pricing.starter.desc": "Pour les particuliers et petits projets",
"landing.pricing.starter.f1": "50 documents / mois",
"landing.pricing.starter.f2": "Jusqu'à 50 pages par doc",
"landing.pricing.starter.f3": "Google Traduction + DeepL",
"landing.pricing.starter.f4": "Fichiers jusqu'à 10 Mo",
"landing.pricing.starter.cta": "Commencer",
"landing.pricing.pro.name": "Pro",
"landing.pricing.pro.desc": "Pour les professionnels exigeants",
"landing.pricing.pro.f1": "200 documents / mois",
"landing.pricing.pro.f2": "Jusqu'à 200 pages par doc",
"landing.pricing.pro.f3": "Traduction par IA",
"landing.pricing.pro.f4": "Google + DeepL inclus",
"landing.pricing.pro.f5": "Glossaires et prompts",
"landing.pricing.pro.f6": "Support prioritaire",
"landing.pricing.pro.cta": "Essayer Pro",
"landing.pricing.business.name": "Business",
"landing.pricing.business.desc": "Pour les équipes avec des besoins élevés",
"landing.pricing.business.f1": "1 000 documents / mois",
"landing.pricing.business.f2": "Jusqu'à 500 pages par doc",
"landing.pricing.business.f3": "IA Premium (Claude)",
"landing.pricing.business.f4": "Tous les fournisseurs + API",
"landing.pricing.business.f5": "Webhooks et automatisation",
"landing.pricing.business.f6": "5 postes d'équipe",
"landing.pricing.business.cta": "Nous contacter",
"landing.pricing.free.name": "Gratuit",
"landing.pricing.free.desc": "Idéal pour découvrir l'application",
"landing.pricing.free.cta": "Choisir ce plan",
"landing.pricing.enterprise.name": "Entreprise",
"landing.pricing.enterprise.desc": "Solutions sur mesure pour les grandes organisations",
"landing.pricing.enterprise.cta": "Nous contacter",
"landing.cta.title": "Commencez à traduire en 30 secondes",
"landing.cta.subtitle": "Aucune carte bancaire requise. Essayez gratuitement dès maintenant et redonnez vie à vos documents multilingues.",
"landing.cta.button": "Créer un compte gratuit",
"landing.cta.secure": "Sécurisé par chiffrement AES-256",
"landing.footer.desc": "Spécialiste de la traduction documentaire intelligente. Nous marions l'art de la mise en page et la science de l'IA contextuelle.",
"landing.footer.product": "Produit",
"landing.footer.resources": "Ressources",
"landing.footer.legal": "Légal",
"landing.footer.rights": "© 2026 Wordly.art — Tous droits réservés.",
"landing.hero.contextEngine": "Traduction détectée : Terme technique de maintenance pour systèmes CVC...",
"landing.hero.liveAnalysis": "Analyse en direct",
"landing.hero.termsDetected": "termes détectés",
"landing.steps.process": "PROCESSUS",
"landing.translate.newProject": "Nouveau projet",
"landing.translate.title": "Traduire un document",
"landing.translate.subtitle": "Importez un fichier et choisissez la langue cible",
"landing.translate.sourceDocument": "Document source",
"landing.translate.configuration": "Configuration",
"landing.translate.sourceLang": "Langue source",
"landing.translate.targetLang": "Langue cible",
"landing.translate.provider": "Fournisseur",
"landing.translate.startTranslation": "Lancer la traduction",
"landing.translate.zeroRetention": "Rétention zéro",
"landing.translate.filesDeleted": "Fichiers supprimés après traitement",
"landing.translate.dropHere": "Glissez-déposez ici",
"landing.translate.supportedFormats": "Fichiers DOCX, XLSX, PPTX ou PDF supportés",
"landing.translate.aiAnalysis": "Analyse IA Active",
"landing.translate.processing": "Traitement en cours",
"landing.translate.preservingLayout": "Votre mise en page est en cours de préservation"
}

View File

@@ -0,0 +1,7 @@
{
"langSelector.search": "Rechercher…",
"langSelector.noResults": "Aucun résultat",
"langSelector.source": "Source",
"langSelector.target": "Cible",
"langSelector.swap": "Inverser"
}

View File

@@ -0,0 +1,5 @@
{
"layout.nav.apiAccess": "Accès API",
"layout.footer.terms": "CGU",
"layout.footer.privacy": "Confidentialité"
}

View File

@@ -0,0 +1,18 @@
{
"login.errorTitle": "Erreur de connexion",
"login.welcomeBack": "Bienvenue",
"login.signInToContinue": "Connectez-vous pour continuer à traduire",
"login.email": "Email",
"login.emailPlaceholder": "vous@exemple.com",
"login.password": "Mot de passe",
"login.forgotPassword": "Mot de passe oublié ?",
"login.passwordPlaceholder": "••••••••",
"login.signingIn": "Connexion en cours...",
"login.signIn": "Se connecter",
"login.noAccount": "Pas encore de compte ?",
"login.signUpFree": "Créer un compte gratuit",
"login.orContinueWith": "ou continuer avec l'e-mail",
"login.google.connecting": "Connexion…",
"login.google.errorGeneric": "Une erreur est survenue avec la connexion Google.",
"login.google.errorFailed": "La connexion Google a échoué. Veuillez réessayer."
}

View File

@@ -0,0 +1,6 @@
{
"memento.title": "Découvrez Momento",
"memento.slogan": "Momento n'est pas qu'une simple application de notes. C'est un écosystème intelligent qui connecte, analyse et développe vos idées en temps réel grâce à 6 types d'agents IA et une recherche sémantique de pointe.",
"memento.ctaFree": "Commencer gratuitement",
"memento.ctaMore": "Voir plus"
}

View File

@@ -0,0 +1,151 @@
{
"pricing.nav.back": "Retour",
"pricing.nav.home": "Accueil",
"pricing.nav.mySubscription": "Mon abonnement",
"pricing.header.badge": "Modèles IA mis à jour — Mars 2026",
"pricing.header.title": "Un forfait pour chaque besoin",
"pricing.header.subtitle": "Traduisez vos documents Word, Excel et PowerPoint en conservant la mise en page originale. Sans jamais saisir de clé API.",
"pricing.billing.monthly": "Mensuel",
"pricing.billing.yearly": "Annuel",
"pricing.plans.free.name": "Gratuit",
"pricing.plans.starter.name": "Starter",
"pricing.plans.pro.name": "Pro",
"pricing.plans.business.name": "Business",
"pricing.plans.enterprise.name": "Entreprise",
"pricing.plans.free.description": "Parfait pour découvrir l'application",
"pricing.plans.starter.description": "Pour les particuliers et petits projets",
"pricing.plans.pro.description": "Pour les professionnels et équipes en croissance",
"pricing.plans.business.description": "Pour les équipes et organisations",
"pricing.plans.enterprise.description": "Solutions sur mesure pour grandes organisations",
"pricing.plans.pro.highlight": "Le plus populaire",
"pricing.plans.pro.badge": "POPULAIRE",
"pricing.plans.enterprise.badge": "SUR DEVIS",
"pricing.plans.free.feat1": "5 documents / mois",
"pricing.plans.free.feat2": "Jusqu'à 15 pages par document",
"pricing.plans.free.feat3": "Google Traduction inclus",
"pricing.plans.free.feat4": "Toutes les langues (130+)",
"pricing.plans.free.feat5": "Support communautaire",
"pricing.plans.starter.feat1": "50 documents / mois",
"pricing.plans.starter.feat2": "Jusqu'à 50 pages par document",
"pricing.plans.starter.feat3": "Google Traduction + DeepL",
"pricing.plans.starter.feat4": "Fichiers jusqu'à 10 Mo",
"pricing.plans.starter.feat5": "Support par e-mail",
"pricing.plans.starter.feat6": "Historique 30 jours",
"pricing.plans.pro.feat1": "200 documents / mois",
"pricing.plans.pro.feat2": "Jusqu'à 200 pages par document",
"pricing.plans.pro.feat3": "Traduction IA Essentielle",
"pricing.plans.pro.feat4": "Google Traduction + DeepL",
"pricing.plans.pro.feat5": "Fichiers jusqu'à 25 Mo",
"pricing.plans.pro.feat6": "Glossaires personnalisés",
"pricing.plans.pro.feat7": "Support prioritaire",
"pricing.plans.pro.feat8": "Historique 90 jours",
"pricing.plans.business.feat1": "1 000 documents / mois",
"pricing.plans.business.feat2": "Jusqu'à 500 pages par document",
"pricing.plans.business.feat3": "IA Essentielle + Premium (Claude Haiku)",
"pricing.plans.business.feat4": "Tous les fournisseurs de traduction",
"pricing.plans.business.feat5": "Fichiers jusqu'à 50 Mo",
"pricing.plans.business.feat6": "Accès API (10 000 appels/mois)",
"pricing.plans.business.feat7": "Webhooks de notification",
"pricing.plans.business.feat8": "Support dédié",
"pricing.plans.business.feat9": "Historique 1 an",
"pricing.plans.business.feat10": "Analytiques avancées",
"pricing.plans.enterprise.feat1": "Documents illimités",
"pricing.plans.enterprise.feat2": "Tous les modèles IA (GPT-5, Claude Opus 4.6…)",
"pricing.plans.enterprise.feat3": "Déploiement on-premise ou cloud dédié",
"pricing.plans.enterprise.feat4": "SLA 99,9 % garanti",
"pricing.plans.enterprise.feat5": "Support 24/7 dédié",
"pricing.plans.enterprise.feat6": "Marque blanche (white-label)",
"pricing.plans.enterprise.feat7": "Équipes illimitées",
"pricing.plans.enterprise.feat8": "Intégrations sur mesure",
"pricing.card.onRequest": "Sur devis",
"pricing.card.free": "Gratuit",
"pricing.card.perMonth": "/mois",
"pricing.card.billedYearly": "Facturé {price} € / an",
"pricing.card.documents": "Documents",
"pricing.card.pagesMax": "Pages max",
"pricing.card.aiTranslation": "Traduction IA",
"pricing.card.unlimited": "Illimité",
"pricing.card.perMonthStat": "/ mois",
"pricing.card.perDoc": "p / doc",
"pricing.card.aiEssential": "Essentielle",
"pricing.card.aiEssentialPremium": "Essentielle + Premium",
"pricing.card.aiCustom": "Sur mesure",
"pricing.card.myPlan": "Mon forfait",
"pricing.card.managePlan": "Gérer mon forfait",
"pricing.card.startFree": "Commencer gratuitement",
"pricing.card.contactUs": "Nous contacter",
"pricing.card.choosePlan": "Choisir ce forfait",
"pricing.card.processing": "Traitement…",
"pricing.comparison.title": "Comparaison détaillée",
"pricing.comparison.subtitle": "Tout ce qui est inclus dans chaque forfait",
"pricing.comparison.feature": "Fonctionnalité",
"pricing.comparison.docsPerMonth": "Documents / mois",
"pricing.comparison.pagesMaxPerDoc": "Pages max / document",
"pricing.comparison.maxFileSize": "Taille max fichier",
"pricing.comparison.googleTranslation": "Google Traduction",
"pricing.comparison.deepl": "DeepL",
"pricing.comparison.aiEssential": "Traduction IA Essentielle",
"pricing.comparison.aiPremium": "Traduction IA Premium",
"pricing.comparison.apiAccess": "Accès API",
"pricing.comparison.priorityProcessing": "Traitement prioritaire",
"pricing.comparison.support": "Support",
"pricing.comparison.support.community": "Communauté",
"pricing.comparison.support.email": "E-mail",
"pricing.comparison.support.priority": "Prioritaire",
"pricing.comparison.support.dedicated": "Dédié",
"pricing.comparison.mb": "Mo",
"pricing.credits.title": "Crédits supplémentaires",
"pricing.credits.subtitle": "Besoin de plus ? Achetez des crédits à l'unité, sans abonnement.",
"pricing.credits.perPage": "1 crédit = 1 page traduite.",
"pricing.credits.bestValue": "Le meilleur rapport",
"pricing.credits.unit": "crédits",
"pricing.credits.centsPerCredit": "cts / crédit",
"pricing.credits.buy": "Acheter",
"pricing.trust.encryption.title": "Chiffrement de bout en bout",
"pricing.trust.encryption.sub": "TLS 1.3 + AES-256 au repos",
"pricing.trust.languages.title": "130+ langues",
"pricing.trust.languages.sub": "Dont arabe, persan, hébreu (RTL)",
"pricing.trust.parallel.title": "Traitement parallèle",
"pricing.trust.parallel.sub": "IA multi-thread ultra-rapide",
"pricing.trust.availability.title": "Disponible 24/7",
"pricing.trust.availability.sub": "Uptime garanti 99,9 %",
"pricing.aiModels.title": "Nos modèles IA — Mars 2026",
"pricing.aiModels.essential.title": "Traduction IA Essentielle",
"pricing.aiModels.essential.plan": "Forfait Pro",
"pricing.aiModels.essential.descPrefix": "Basée sur",
"pricing.aiModels.essential.descSuffix": "— le modèle IA le plus rentable de 2026. Qualité comparable aux modèles frontier à une fraction du coût.",
"pricing.aiModels.essential.modelName": "notre modèle IA Essentiel",
"pricing.aiModels.essential.context": "163K tokens de contexte",
"pricing.aiModels.essential.value": "Excellent rapport qualité/prix",
"pricing.aiModels.premium.title": "Traduction IA Premium",
"pricing.aiModels.premium.plan": "Forfait Business",
"pricing.aiModels.premium.descPrefix": "Basée sur",
"pricing.aiModels.premium.descSuffix": "d'Anthropic — précis sur les documents juridiques, médicaux et techniques complexes.",
"pricing.aiModels.premium.context": "200K tokens de contexte",
"pricing.aiModels.premium.precision": "Meilleure précision",
"pricing.faq.title": "Questions fréquentes",
"pricing.faq.q1": "Puis-je changer de forfait à tout moment ?",
"pricing.faq.a1": "Oui. Le passage à un forfait supérieur est immédiat et proratisé. La rétrogradation prend effet à la fin de la période en cours.",
"pricing.faq.q2": "Qu'est-ce que la « Traduction IA Essentielle » ?",
"pricing.faq.a2": "C'est notre moteur IA. Il comprend le contexte de vos documents, préserve la mise en page et gère les termes techniques bien mieux qu'une traduction classique.",
"pricing.faq.q3": "Quelle est la différence entre IA Essentielle et IA Premium ?",
"pricing.faq.a3": "L'IA Essentielle utilise un modèle optimisé (excellent rapport qualité/prix). L'IA Premium utilise Claude Sonnet 4.6 d'Anthropic, plus précis sur les documents juridiques, médicaux et techniques complexes.",
"pricing.faq.q4": "Mes documents sont-ils conservés après traduction ?",
"pricing.faq.a4": "Les fichiers traduits sont disponibles selon votre forfait (30 jours Starter, 90 jours Pro, 1 an Business). Ils sont chiffrés au repos et en transit.",
"pricing.faq.q5": "Que se passe-t-il si je dépasse mon quota mensuel ?",
"pricing.faq.a5": "Vous pouvez acheter des crédits supplémentaires à l'unité, ou upgrader votre forfait. Vous êtes notifié à 80 % d'utilisation.",
"pricing.faq.q6": "Y a-t-il une version d'essai gratuite des forfaits payants ?",
"pricing.faq.a6": "Le forfait Gratuit est permanent et sans carte bancaire. Pour les forfaits Pro et Business, contactez-nous pour un accès d'essai de 14 jours.",
"pricing.faq.q7": "Quels formats de fichiers sont supportés ?",
"pricing.faq.a7": "Word (.docx), Excel (.xlsx/.xls), PowerPoint (.pptx), et bientôt PDF. Tous les plans supportent les mêmes formats.",
"pricing.cta.title": "Prêt à commencer ?",
"pricing.cta.subtitle": "Commencez gratuitement, sans carte bancaire. Passez à un forfait supérieur quand vous en avez besoin.",
"pricing.cta.createAccount": "Créer un compte gratuit",
"pricing.cta.login": "Se connecter",
"pricing.toast.demo": "Mode démo — Stripe n'est pas encore configuré. En production, vous seriez redirigé vers le paiement pour activer le forfait {planId}.",
"pricing.toast.networkError": "Erreur réseau. Veuillez réessayer.",
"pricing.toast.paymentError": "Erreur lors de la création du paiement.",
"pricing.dashboard": "Tableau de bord",
"pricing.okSymbol": "✓",
"pricing.errSymbol": "✕"
}

View File

@@ -0,0 +1,58 @@
{
"profile.header.title": "Mon Profil",
"profile.header.subtitle": "Gérez votre compte et vos préférences.",
"profile.tabs.account": "Compte",
"profile.tabs.subscription": "Abonnement",
"profile.tabs.preferences": "Préférences",
"profile.account.user": "Utilisateur",
"profile.account.memberSince": "Membre depuis",
"profile.plan.label": "Forfait",
"profile.plan.free": "Gratuit",
"profile.plan.starter": "Starter",
"profile.plan.pro": "Pro",
"profile.plan.business": "Business",
"profile.plan.enterprise": "Enterprise",
"profile.plan.pricePerMonth": "{price} €/mois",
"profile.subscription.canceling": "Annulation en cours",
"profile.subscription.active": "Actif",
"profile.subscription.unknown": "Inconnu",
"profile.subscription.accessUntil": "Accès jusqu'au",
"profile.subscription.renewalOn": "Renouvellement le",
"profile.subscription.upgradePlan": "Passer à un forfait payant",
"profile.subscription.changePlan": "Changer de forfait",
"profile.subscription.manageBilling": "Gérer la facturation",
"profile.subscription.billingUnavailable": "Portail de facturation non disponible.",
"profile.subscription.billingError": "Erreur lors de l'accès au portail.",
"profile.subscription.cancelSuccess": "Abonnement annulé. Vous conservez l'accès jusqu'à la fin de la période.",
"profile.subscription.cancelError": "Erreur lors de l'annulation.",
"profile.subscription.networkError": "Erreur réseau.",
"profile.usage.title": "Utilisation ce mois-ci",
"profile.usage.resetOn": "Reset le",
"profile.usage.documents": "Documents",
"profile.usage.pages": "Pages",
"profile.usage.extraCredits": "crédit supplémentaire",
"profile.usage.extraCreditsPlural": "crédits supplémentaires",
"profile.usage.quotaReached": "Quota atteint",
"profile.usage.quotaReachedDesc": "Passez à un forfait supérieur pour continuer.",
"profile.usage.unlockMore": "Débloquez plus de traductions avec un forfait payant.",
"profile.usage.viewPlans": "Voir les forfaits",
"profile.usage.includedInPlan": "Inclus dans votre forfait",
"profile.danger.title": "Zone danger",
"profile.danger.description": "L'annulation prend effet à la fin de votre période en cours. Vous conservez l'accès jusqu'à cette date.",
"profile.danger.confirm": "Êtes-vous sûr(e) ? Cette action ne peut pas être annulée.",
"profile.danger.confirmCancel": "Confirmer l'annulation",
"profile.danger.cancelSubscription": "Annuler mon abonnement",
"profile.danger.keep": "Non, garder",
"profile.prefs.interfaceLang": "Langue de l'interface",
"profile.prefs.interfaceLangDesc": "La langue est détectée automatiquement selon votre navigateur. Vous pouvez la changer manuellement.",
"profile.prefs.defaultTargetLang": "Langue cible par défaut",
"profile.prefs.selectLanguage": "Sélectionner une langue",
"profile.prefs.defaultTargetLangDesc": "Cette langue sera pré-sélectionnée lors de vos traductions.",
"profile.prefs.save": "Enregistrer",
"profile.prefs.theme": "Thème",
"profile.prefs.themeDesc": "Choisissez l'apparence de l'interface",
"profile.prefs.cache": "Cache",
"profile.prefs.cacheDesc": "Effacer le cache local peut résoudre certains problèmes d'affichage.",
"profile.prefs.clearing": "Effacement...",
"profile.prefs.clearCache": "Effacer le cache"
}

View File

@@ -0,0 +1,7 @@
{
"providerSelector.noClassic": "Aucun traducteur standard disponible.",
"providerSelector.noLlm": "Aucun modèle IA configuré.",
"providerSelector.costOne": "Coût : 1 crédit par page",
"providerSelector.costFive": "Coût : 5 crédits par page (Facteur Premium)",
"providerSelector.unlockContextual": "Débloquez la traduction contextuelle haut de gamme pour vos documents entiers."
}

View File

@@ -0,0 +1,29 @@
{
"providerTheme.deepseek.badge": "Essentielle",
"providerTheme.deepseek.subBadge": "Technique & Éco",
"providerTheme.deepseek.desc": "Traduction ultra-précise et économique, idéale pour les documents techniques et le code.",
"providerTheme.openai.badge": "Premium",
"providerTheme.openai.subBadge": "Haute Fidélité",
"providerTheme.openai.desc": "Le standard mondial de l'IA. Cohérence textuelle maximale et respect strict du style.",
"providerTheme.minimax.badge": "Avancée",
"providerTheme.minimax.subBadge": "Performance",
"providerTheme.minimax.desc": "Vitesse d'exécution incroyable et excellente compréhension des structures complexes.",
"providerTheme.openrouter.badge": "Express",
"providerTheme.openrouter.subBadge": "Multi-Modèles",
"providerTheme.openrouter.desc": "Accès unifié aux meilleurs modèles open-source optimisés pour la traduction.",
"providerTheme.openrouter_premium.badge": "Ultra",
"providerTheme.openrouter_premium.subBadge": "Maximum Context",
"providerTheme.openrouter_premium.desc": "Traduction assistée par les modèles de pointe (GPT-4o, Claude Sonnet 4.6) pour documents longs.",
"providerTheme.zai.badge": "Spécialisée",
"providerTheme.zai.subBadge": "Finance & Droit",
"providerTheme.zai.desc": "Modèle affiné pour les terminologies métiers exigeantes (juridique, finance).",
"providerTheme.default.badge": "Moderne",
"providerTheme.default.subBadge": "Raisonnement IA",
"providerTheme.default.desc": "Traduction par grand modèle linguistique (LLM) avec analyse sémantique avancée.",
"providerTheme.classic.google.label": "Google Traduction",
"providerTheme.classic.google.desc": "Traduction ultra-rapide couvrant plus de 130 langues. Recommandé pour les flux généraux.",
"providerTheme.classic.deepl.label": "DeepL Pro",
"providerTheme.classic.deepl.desc": "Traduction haute précision réputée pour sa fluidité et ses formulations naturelles.",
"providerTheme.classic.google_cloud.label": "Google Cloud API",
"providerTheme.classic.google_cloud.desc": "Moteur cloud professionnel optimisé pour le traitement de gros volumes de documents."
}

View File

@@ -0,0 +1,29 @@
{
"register.title": "Créer un compte",
"register.subtitle": "Commencez à traduire gratuitement",
"register.error.failed": "L'inscription a échoué",
"register.name.label": "Nom",
"register.name.placeholder": "Votre nom",
"register.name.error": "Le nom doit contenir au moins 2 caractères",
"register.email.label": "Adresse email",
"register.email.placeholder": "vous@exemple.com",
"register.email.error": "Adresse email invalide",
"register.password.label": "Mot de passe",
"register.password.error": "Le mot de passe doit contenir au moins 8 caractères, une majuscule, une minuscule et un chiffre",
"register.password.show": "Afficher le mot de passe",
"register.password.hide": "Masquer le mot de passe",
"register.password.strengthLabel": "Force :",
"register.password.strength.weak": "Faible",
"register.password.strength.medium": "Moyen",
"register.password.strength.strong": "Fort",
"register.confirmPassword.label": "Confirmer le mot de passe",
"register.confirmPassword.error": "Les mots de passe ne correspondent pas",
"register.confirmPassword.show": "Afficher",
"register.confirmPassword.hide": "Masquer",
"register.submit.creating": "Création du compte...",
"register.submit.create": "Créer mon compte",
"register.hasAccount": "Vous avez déjà un compte ?",
"register.login": "Se connecter",
"register.terms.prefix": "En créant un compte, vous acceptez notre",
"register.terms.link": "utilisation du service"
}

View File

@@ -0,0 +1,22 @@
{
"resetPassword.passwordRequirements": "Le mot de passe doit contenir au moins 8 caractères, une majuscule, une minuscule et un chiffre",
"resetPassword.passwordMismatch": "Les mots de passe ne correspondent pas",
"resetPassword.tokenMissing": "Token manquant. Veuillez utiliser le lien reçu par email.",
"resetPassword.error": "Une erreur s'est produite",
"resetPassword.invalidLink": "Lien invalide",
"resetPassword.invalidLinkMessage": "Ce lien de réinitialisation est invalide. Veuillez redemander un nouveau lien.",
"resetPassword.requestNewLink": "Redemander un lien",
"resetPassword.successTitle": "Mot de passe réinitialisé",
"resetPassword.newPasswordTitle": "Nouveau mot de passe",
"resetPassword.successSubtitle": "Vous allez être redirigé vers la connexion",
"resetPassword.subtitle": "Définissez votre nouveau mot de passe",
"resetPassword.successMessage": "Votre mot de passe a été réinitialisé avec succès. Vous allez être redirigé vers la page de connexion.",
"resetPassword.newPassword": "Nouveau mot de passe",
"resetPassword.showPassword": "Afficher le mot de passe",
"resetPassword.hidePassword": "Masquer le mot de passe",
"resetPassword.confirmPassword": "Confirmer le mot de passe",
"resetPassword.resetting": "Réinitialisation...",
"resetPassword.resetPassword": "Réinitialiser le mot de passe",
"resetPassword.backToLogin": "Retour à la connexion",
"resetPassword.loading": "Chargement..."
}

View File

@@ -0,0 +1,14 @@
{
"services.title": "Fournisseurs de traduction",
"services.subtitle": "Les fournisseurs sont configurés par l'administrateur. Vous pouvez voir ceux actuellement disponibles pour votre compte.",
"services.loading": "Chargement des fournisseurs...",
"services.noProviders": "Aucun fournisseur n'est actuellement configuré. Contactez votre administrateur.",
"services.classic": "Traduction classique",
"services.llmPro": "IA · Contextuelle (Pro)",
"services.available": "Disponible",
"services.model": "Modèle",
"services.adminOnly.title": "La configuration des fournisseurs est réservée à l'administrateur",
"services.adminOnly.desc": "Les clés API, la sélection de modèle et l'activation des fournisseurs sont gérées exclusivement par l'administrateur. Vous n'avez jamais besoin de saisir de clé API.",
"services.fallback.google.label": "Google Traduction",
"services.fallback.google.desc": "Traduction rapide, 130+ langues"
}

View File

@@ -0,0 +1,20 @@
{
"settings.title": "Paramètres",
"settings.subtitle": "Configuration générale de l'application",
"settings.formats.title": "Formats supportés",
"settings.formats.subtitle": "Types de documents que vous pouvez traduire",
"settings.formats.formulas": "Formules",
"settings.formats.styles": "Styles",
"settings.formats.images": "Images",
"settings.formats.headers": "En-têtes",
"settings.formats.tables": "Tableaux",
"settings.formats.slides": "Slides",
"settings.formats.notes": "Notes",
"settings.cache.title": "Cache",
"settings.cache.desc": "Effacer le cache local peut résoudre certains problèmes d'affichage.",
"settings.cache.clearing": "Effacement...",
"settings.cache.clear": "Effacer le cache",
"settings.formats.excel.name": "Excel",
"settings.formats.word.name": "Word",
"settings.formats.powerpoint.name": "PowerPoint"
}

View File

@@ -0,0 +1,93 @@
{
"translate.glossary.selectGlossary": "Sélectionner un glossaire...",
"translate.mode.label": "Mode de traduction",
"translate.mode.classic": "Classique",
"translate.mode.classicDesc": "Rapide",
"translate.mode.proLlm": "Pro LLM",
"translate.mode.proLlmDesc": "Contextuel",
"translate.mode.tooltip": "Passez à Pro pour la traduction LLM",
"translate.mode.upgradeLink": "Passer à Pro",
"translate.mode.upgradeDesc": "pour des traductions alimentées par LLM",
"translate.glossary.title": "Glossaire",
"translate.glossary.select": "Sélectionner un glossaire",
"translate.glossary.none": "Aucun",
"translate.glossary.terms": "termes",
"translate.glossary.proOnly": "Passez à Pro pour utiliser les glossaires",
"translate.glossary.myGlossaries": "Mes glossaires",
"translate.glossary.fromTemplate": "Créer depuis un template",
"translate.glossary.noGlossaryForPair": "Aucun glossaire pour",
"translate.glossary.noGlossaries": "Aucun glossaire",
"translate.glossary.loading": "Chargement...",
"translate.glossary.classicMode": "Moteur neutre sans glossaire (IA uniquement)",
"translate.glossary.selectPlaceholder": "Sélectionner un glossaire...",
"translate.glossary.multilingual": "MULTILINGUE",
"translate.glossary.noGlossaryAvailable": "Aucun glossaire disponible",
"translate.glossary.filterByLang": "Filtrer par langue",
"translate.glossary.active": "Actif",
"translate.glossary.inactive": "Inactif",
"translate.glossary.availableTemplates": "Modèles disponibles",
"translate.glossary.importing": "Importation...",
"translate.glossary.imported": "(Importé)",
"translate.glossary.noGlossaryForSource": "Aucun glossaire ni modèle pour la langue source",
"translate.glossary.createGlossary": "Créer un glossaire",
"translate.glossary.showAll": "Afficher tous les glossaires",
"translate.glossary.activePreview": "Aperçu des correspondances actives :",
"translate.glossary.total": "au total",
"translate.glossary.moreTerms": "autres termes",
"translate.glossary.noTerms": "Aucun terme dans ce glossaire.",
"translate.glossary.sourceTerm": "Terme Source",
"translate.glossary.translation": "Traduction",
"translate.glossary.addTerm": "Ajouter le terme",
"translate.glossary.disabledMode": "Moteur neutre sans glossaire appliqué",
"translate.glossary.addTermError": "Erreur lors de l'ajout du terme",
"translate.glossary.networkError": "Erreur réseau",
"translate.glossary.importFailed": "Échec de l'importation ({status})",
"translate.glossary.helpText": "Le glossaire force la traduction de termes précis. Choisissez un glossaire dont la langue source correspond à la langue d'origine de votre document.",
"translate.glossary.sourceWarning": "Attention : Ce glossaire utilise la langue source",
"translate.glossary.sourceWarningBut": "mais votre document est configuré en",
"translate.glossary.targetWarning": "Incompatibilité de cible : Ce glossaire est prévu pour traduire vers",
"translate.glossary.targetWarningBut": "mais votre document cible",
"translate.glossary.targetWarningEnd": "Les termes risquent de ne pas être pertinents.",
"translate.header.processing": "Traitement en cours",
"translate.header.aiActive": "Analyse IA active",
"translate.header.aiActiveDesc": "Votre mise en page est en cours de préservation par notre moteur contextuel.",
"translate.header.completed": "Complété",
"translate.header.completedTitle": "Traduction terminée",
"translate.header.proSpace": "Espace Pro",
"translate.header.translateDoc": "Traduire un document",
"translate.header.translateDocDesc": "Conservez la mise en page d'origine grâce au moteur de traduction ultra-haute fidélité.",
"translate.upload.nativeFormat": "Format natif",
"translate.fileType.word": "Word (.docx)",
"translate.fileType.excel": "Excel (.xlsx)",
"translate.fileType.slides": "Slides (.pptx)",
"translate.fileType.pdf": "PDF (.pdf)",
"translate.startTranslation": "Lancer la traduction",
"translate.submit": "Soumission…",
"translate.chooseTargetLang": "Veuillez choisir une langue cible",
"translate.pleaseLoadFile": "Veuillez charger un fichier d'abord",
"translate.contextEngineActive": "Moteur contextuel actif",
"translate.phase1": "Phase 1 : Initialisation",
"translate.phase2": "Phase 2 : Reconstruction contextuelle",
"translate.stat.segments": "segments",
"translate.stat.precision": "précision",
"translate.stat.speedLabel": "vitesse",
"translate.stat.turbo": "Turbo",
"translate.stat.time": "temps",
"translate.complete.masterQuality": "✓ Qualité Maître",
"translate.download": "Télécharger",
"translate.newTranslation": "+ Nouvelle traduction",
"translate.failedTitle": "Erreur lors de la traduction",
"translate.retry": "Réessayer",
"translate.uploadAnother": "Téléverser un autre fichier",
"translate.monitor": "Moniteur IA",
"translate.summary": "Récapitulatif",
"translate.cancelProcess": "⟳ Annuler le processus",
"translate.layoutIntegrity": "Intégrité Layout",
"translate.secureHundred": "100% SÉCURISÉ",
"translate.okHundred": "100% OK",
"translate.preserveLayout": "Conserver la mise en page",
"translate.preserveLayoutDesc": "Conserver la mise en page",
"translate.textOnly": "Texte brut",
"translate.textOnlyDesc": "Traduction rapide du texte uniquement",
"translate.unavailableStandard": "Indisponible en mode Standard (IA uniquement)"
}

View File

@@ -0,0 +1,6 @@
{
"translateComplete.highQuality": "Haute qualité",
"translateComplete.segments": "Segments",
"translateComplete.characters": "Caractères",
"translateComplete.confidence": "Confiance"
}