- WorkflowBatchImportWizard:目录扫描/多文件 → dry-run 逐文件报告 → 确认导入; warn 可补用途、需确认与 fail 项不导入不标可运行、重复导入全量 conflict 跳过 - WorkflowLibrary:view=meta 轻量列表(搜索/分类/模型/媒介/收藏/最近/启停/ 去重/批量标注),完整 JSON 仅操作时按需加载;试运行复用 WorkflowTestDialog; 保留用途确认、输出指定、单文件导入等既有能力 - api/types:listMeta、convert、importBatch、importScanDry/Commit、touch、 dedupe 客户端与 WorkflowMeta/转换报告类型;update 支持 favorite/tags/ category/model_family - i18n 130 键 ×7 语言;changelog Co-authored-by: multica-agent <github@multica.ai>
2233 lines
115 KiB
TypeScript
2233 lines
115 KiB
TypeScript
import type { Dict } from './en';
|
||
|
||
export const fr: Dict = {
|
||
// --- Common ---
|
||
'common.add': 'Ajouter',
|
||
'common.cancel': 'Annuler',
|
||
'common.cancelButton': 'Annuler',
|
||
'common.delete': 'Supprimer',
|
||
'common.description': 'Description',
|
||
'common.edit': 'Modifier',
|
||
'common.failed': 'Échec',
|
||
'common.generating': 'Génération',
|
||
'common.loading': 'Chargement',
|
||
'common.missing': 'Manquant',
|
||
'common.name': 'Nom',
|
||
'common.pending': 'En attente',
|
||
'common.queued': 'En file',
|
||
'common.ready': 'Prêt',
|
||
'common.rename': 'Renommer',
|
||
'common.retry': 'Réessayer',
|
||
'common.running': 'En cours',
|
||
'common.save': 'Enregistrer',
|
||
'common.saved': 'Enregistré',
|
||
'common.saveFailed': "Échec de l'enregistrement",
|
||
'common.saving': 'Enregistrement',
|
||
'common.send': 'Envoyer',
|
||
'common.stop': 'Arrêter',
|
||
'common.title': 'Titre',
|
||
'common.language': 'Langue',
|
||
|
||
// --- App shell / nav ---
|
||
'nav.canvas': 'Canvas IA',
|
||
'nav.library': 'Bibliothèque d’assets',
|
||
'nav.projects': 'Projets',
|
||
'nav.buildScene': 'Composer la scène',
|
||
'nav.settings': 'Paramètres',
|
||
'nav.agents': 'Agents',
|
||
'nav.models': 'Modèles',
|
||
'nav.home': 'Accueil',
|
||
'nav.primary': 'Principal',
|
||
'nav.projectStages': 'Étapes du projet',
|
||
'nav.backProjects': 'Retour aux projets',
|
||
'nav.story': 'Histoire',
|
||
'nav.assets': 'Ressources',
|
||
'nav.script': 'Scénario',
|
||
'nav.video': 'Vidéo',
|
||
'nav.countActive': '{count} en cours',
|
||
'nav.eyebrow': 'Calliope',
|
||
'nav.unsaved': 'Modifications non enregistrées',
|
||
'nav.llm': 'LLM',
|
||
'nav.llmBlurb': "Configurez les modèles de langage utilisés par l'agent.",
|
||
'nav.comfy': 'ComfyUI',
|
||
'nav.comfyBlurb': "Où ComfyUI s'exécute.",
|
||
'nav.workflows': 'Workflows',
|
||
'nav.workflowsBlurb': 'Importez et enregistrez des workflows ComfyUI pour la génération.',
|
||
'nav.agent': 'Modèle agent',
|
||
'nav.agentBlurb': "Modèle utilisé pour la rédaction de l'histoire et les tâches de l'agent.",
|
||
'nav.skills': 'Compétences',
|
||
'nav.skillsBlurb': "Compétences de l'agent disponibles dans ce projet.",
|
||
'nav.queue': "File d'attente",
|
||
'nav.queueBlurb': 'Parallélisme et délais des tâches de génération.',
|
||
'nav.storage': 'Chemins système',
|
||
'nav.storageBlurb': "Où les fichiers sont stockés et où l'agent peut travailler.",
|
||
|
||
// --- Toast ---
|
||
'toast.dismiss': 'Ignorer',
|
||
'toast.undo': 'Annuler',
|
||
'toast.uploadFailed': "Échec de l'import",
|
||
|
||
// --- Modal ---
|
||
'modal.dialog': 'Boîte de dialogue',
|
||
'modal.closeDialog': 'Fermer la boîte de dialogue',
|
||
|
||
// --- Projects page ---
|
||
'projects.new': 'Nouveau projet',
|
||
'projects.title': 'Projets',
|
||
'projects.subtitle': "Votre espace local de l'histoire à la vidéo. Reprenez où vous en étiez.",
|
||
'projects.newReel': 'Nouveau montage',
|
||
'projects.close': 'Fermer',
|
||
'projects.titleField': 'Titre',
|
||
'projects.titlePlaceholder': 'Port au clair de lune',
|
||
'projects.ideaField': "Idée d'histoire",
|
||
'projects.ideaPlaceholder': 'Un gardien de phare découvre une bouteille lumineuse qui montre les souvenirs de marins perdus en mer…',
|
||
'projects.ideaHint': "Facultatif — vous pourrez l'affiner plus tard à l'étape Histoire.",
|
||
'projects.genre': 'Genre',
|
||
'projects.tone': 'Ton',
|
||
'projects.duration': 'Durée cible',
|
||
'projects.durationHint': "Guide le nombre de beats et de scènes à l'étape Histoire.",
|
||
'projects.cancel': 'Annuler',
|
||
'projects.create': 'Créer le projet',
|
||
'projects.searchPlaceholder': 'Rechercher des projets…',
|
||
'projects.searchLabel': 'Rechercher des projets',
|
||
'projects.filterBy': 'Filtrer par statut',
|
||
'projects.filterAll': 'Tous',
|
||
'projects.filterProgress': 'En cours',
|
||
'projects.filterCompleted': 'Terminés',
|
||
'projects.filterDraft': 'Brouillons',
|
||
'projects.loading': 'Chargement des projets',
|
||
'projects.loadError': 'Impossible de charger les projets',
|
||
'projects.loadErrorBody': "Le backend n'a pas répondu.",
|
||
'projects.emptyTitle': 'Aucun projet pour le moment',
|
||
'projects.emptyBody': "Calliope transforme une idée d'histoire en personnages, plans et vidéo finale — entièrement sur votre machine.",
|
||
'projects.firstProject': 'Créer votre premier projet',
|
||
'projects.noMatchSearch': 'Aucun projet ne correspond à « {q} »',
|
||
'projects.noMatchFilter': 'Aucun projet ne correspond au filtre actuel',
|
||
'projects.noMatchBody': 'Essayez une autre recherche ou effacez les filtres.',
|
||
'projects.clearFilters': 'Effacer les filtres',
|
||
'projects.newCard': 'Créer un nouveau projet',
|
||
'projects.newCardSub': "Commencez par une idée d'histoire",
|
||
'projects.created': 'Projet « {title} » créé',
|
||
'projects.createFailed': 'Impossible de créer le projet',
|
||
|
||
// --- Project form options (values stored in English) ---
|
||
'genres.adventure': 'Aventure / Mystère',
|
||
'genres.drama': 'Drame',
|
||
'genres.scifi': 'Science-fiction',
|
||
'genres.fantasy': 'Fantastique',
|
||
'genres.horror': 'Horreur',
|
||
'genres.romance': 'Romance',
|
||
'genres.thriller': 'Thriller',
|
||
'tones.cinematic': 'Cinématographique, atmosphérique',
|
||
'tones.dark': 'Sombre, tendu',
|
||
'tones.whimsical': 'Fantaisiste, chaleureux',
|
||
'tones.gritty': 'Cru, réaliste',
|
||
'tones.epic': 'Épique, grandiose',
|
||
'durations.30': '30 secondes',
|
||
'durations.1m': '1 minute',
|
||
'durations.2m': '2 minutes',
|
||
'durations.5m': '5 minutes',
|
||
'durations.10m': '10 minutes',
|
||
|
||
// --- Project card ---
|
||
'projectCard.actions': 'Actions du projet',
|
||
'projectCard.assets': 'Ressources',
|
||
'projectCard.changeCover': 'Changer la couverture',
|
||
'projectCard.characters': 'Personnages',
|
||
'projectCard.deleted': 'Projet supprimé',
|
||
'projectCard.deleteFailed': 'Impossible de supprimer le projet',
|
||
'projectCard.deleteMessage': 'Cela supprimera définitivement le projet et ses ressources. Cette action est irréversible.',
|
||
'projectCard.deleteTitle': 'Supprimer le projet',
|
||
'projectCard.menuLabel': 'Menu du projet',
|
||
'projectCard.noIdea': "Pas encore d'idée d'histoire",
|
||
'projectCard.open': 'Ouvrir le projet',
|
||
'projectCard.renamedTo': 'Renommé en « {title} »',
|
||
'projectCard.renameFailed': 'Impossible de renommer le projet',
|
||
'projectCard.renameTitle': 'Renommer le projet',
|
||
'projectCard.scenes': 'Scènes',
|
||
'projectCard.status.in_progress': 'En cours',
|
||
'projectCard.status.completed': 'Terminé',
|
||
'projectCard.status.draft': 'Brouillon',
|
||
'projectCard.timeJustNow': "à l'instant",
|
||
'projectCard.timeM': 'il y a {n} min',
|
||
'projectCard.timeH': 'il y a {n} h',
|
||
'projectCard.timeD': 'il y a {n} j',
|
||
'projectCard.timeMo': 'il y a {n} mois',
|
||
'projectCard.timeY': 'il y a {n} ans',
|
||
|
||
// --- Project detail page ---
|
||
'project.backToProjects': 'Retour aux projets',
|
||
'project.notFound': 'Projet introuvable',
|
||
'project.invalidIdBody': "« {id} » n'est pas un identifiant de projet valide — le lien est peut-être rompu ou le projet a été supprimé.",
|
||
'project.openVideoStage': "Ouvrir l'étape Vidéo",
|
||
'project.runningQueued': '{running} en cours · {queued} en file',
|
||
'project.queueIdle': "File d'attente inactive",
|
||
|
||
// --- API errors ---
|
||
'api.unknownError': "Une erreur s'est produite",
|
||
'api.networkError': 'Impossible de joindre le backend : vérifiez qu\'il tourne puis réessayez',
|
||
'api.httpError': 'Échec de la requête (HTTP {status}) : {detail}',
|
||
'playground.openFailed': "Échec de l'ouverture du bac à sable",
|
||
'playground.opening': 'Ouverture du bac à sable…',
|
||
'agents.opening': "Ouverture de l'agent…",
|
||
'agents.openFailed': "Échec de l'ouverture de l'agent",
|
||
|
||
// --- ActivityPanel ---
|
||
'activity.title': 'Activité',
|
||
'activity.agentLog': "Journal de l'agent",
|
||
'activity.agentWorking': "L'agent travaille…",
|
||
'activity.assetReady': 'Ressource prête',
|
||
'activity.busyCount': '{n} en cours',
|
||
'activity.connecting': 'Connexion',
|
||
'activity.reconnecting': 'Reconnexion',
|
||
'activity.quiet': 'Inactif',
|
||
'activity.quietHint': 'Aucune tâche en arrière-plan',
|
||
'activity.show': 'Afficher',
|
||
'activity.hide': 'Masquer',
|
||
'activity.done': 'Terminé',
|
||
'activity.failed': 'Échec',
|
||
'activity.files': 'Fichiers',
|
||
'activity.filesSaved': '{n} fichiers enregistrés',
|
||
'activity.finished': 'Terminé',
|
||
'activity.jobDeleted': 'Tâche supprimée',
|
||
'activity.outputSaved': 'Résultat enregistré',
|
||
'activity.queue': "File d'attente",
|
||
'activity.queueIdle': "File d'attente inactive",
|
||
'activity.queueStats': '{active} en cours · {queued} en file',
|
||
'activity.queued': 'En file',
|
||
'activity.removed': 'Supprimé',
|
||
'activity.running': 'En cours',
|
||
'activity.storylineDrafted': 'Trame rédigée',
|
||
'activity.storyReady': 'Histoire prête',
|
||
'activity.working': 'En cours…',
|
||
|
||
// --- SafeMedia ---
|
||
'safeMedia.noMedia': 'Aucun média',
|
||
|
||
// --- ImageLightbox ---
|
||
'lightbox.clickToFit': 'Cliquer pour ajuster',
|
||
'lightbox.clickToZoom': 'Cliquer pour zoomer',
|
||
'lightbox.closeEsc': 'Appuyez sur Échap pour fermer',
|
||
'lightbox.closeHint': 'Fermer',
|
||
'lightbox.closePreview': "Fermer l'aperçu",
|
||
'lightbox.download': 'Télécharger',
|
||
'lightbox.downloadMedia': 'Télécharger le média',
|
||
'lightbox.fitToScreen': "Ajuster à l'écran",
|
||
'lightbox.imagePreview': "Aperçu de l'image",
|
||
'lightbox.imageUnavailable': 'Image indisponible',
|
||
'lightbox.next': 'Suivant',
|
||
'lightbox.prev': 'Précédent',
|
||
'lightbox.openOriginal': "Ouvrir l'original",
|
||
'lightbox.videoPreview': 'Aperçu de la vidéo',
|
||
'lightbox.videoUnavailable': 'Vidéo indisponible',
|
||
'lightbox.zoom100': '100 %',
|
||
'lastFrame.export': 'Exporter la dernière image',
|
||
'lastFrame.exporting': 'Export de la dernière image…',
|
||
'lastFrame.hint': 'Enregistre la dernière image en PNG pleine taille, p. ex. comme référence de première image',
|
||
'lastFrame.fileTag': 'derniere-image',
|
||
'lastFrame.done': 'Dernière image exportée {name} ({size})',
|
||
'lastFrame.errTimeout': 'Le chargement de la vidéo a expiré. Réessayez plus tard.',
|
||
'lastFrame.errNotFound': 'Le fichier vidéo est introuvable ou a été supprimé.',
|
||
'lastFrame.errForbidden': "Vous n'avez pas l'autorisation de lire cette vidéo.",
|
||
'lastFrame.errNetwork': 'Lecture de la vidéo impossible (erreur réseau).',
|
||
'lastFrame.errDecode': 'La vidéo est endommagée ; sa fin ne peut pas être décodée.',
|
||
'lastFrame.errUnsupported': 'Ce navigateur ne prend pas en charge ce format vidéo, ou le fichier est endommagé.',
|
||
'lastFrame.errCrossOrigin':
|
||
"La vidéo provient d'un autre site qui bloque la lecture des images (cross-origin). Téléchargez d'abord la vidéo.",
|
||
'lastFrame.errNoPicture': "Ce fichier ne contient pas d'image vidéo.",
|
||
'lastFrame.errUnseekable':
|
||
"Impossible d'atteindre la fin de la vidéo (durée inconnue ou source sans recherche) ; aucune image exportée.",
|
||
'lastFrame.errBlack': 'La dernière seconde de la vidéo est noire ; aucune image exportée.',
|
||
'lastFrame.errEmpty': "Le navigateur n'a pas pu décoder la fin. Réessayez ou utilisez Chrome / Edge sur ordinateur.",
|
||
'lastFrame.errUnknown': "Échec de l'export de la dernière image : {msg}",
|
||
|
||
// --- Artifact / canvas nodes ---
|
||
'artifact.artifactLabel': 'Artefact',
|
||
'artifact.fileMissing': 'Fichier manquant',
|
||
'artifact.imageUnavailable': 'Image indisponible',
|
||
'artifact.playInViewer': 'Lire dans la visionneuse',
|
||
'artifact.playVideo': 'Lire la vidéo',
|
||
'artifact.videoUnavailable': 'Vidéo indisponible',
|
||
'artifact.viewImage': "Voir l'image",
|
||
'canvas.emptyHint': "Demandez à l'agent à droite de créer des personnages ou des scènes, ou de générer une image ou une vidéo — les résultats apparaissent ici sous forme de cartes.",
|
||
'canvas.loadFailed': 'Impossible de charger ce canevas',
|
||
'canvas.tidy': 'Ranger la disposition',
|
||
'canvas.tidyTitle': 'Réorganiser toutes les cartes en colonnes et grilles propres',
|
||
'canvas.savePosFailed': "Impossible d'enregistrer la position",
|
||
'canvas.openThatFailed': "Impossible d'ouvrir ce canevas",
|
||
'canvas.sessionCreateFailed': 'Impossible de créer la session',
|
||
'canvas.sessionDeleteFailed': 'Impossible de supprimer la session',
|
||
'canvas.renameFailed': 'Échec du renommage',
|
||
'canvas.suggestFilm': 'Créer un nouveau film',
|
||
'canvas.suggestStory': 'Rédiger une trame',
|
||
'canvas.emptyBoard': 'Tableau vide',
|
||
'canvas.noChatSelected': 'Aucune discussion sélectionnée',
|
||
'canvas.failed': 'échec',
|
||
'canvas.generating': 'génération…',
|
||
'canvas.noMedia': 'aucun média',
|
||
'canvas.openPreview': 'Ouvrir un grand aperçu',
|
||
'canvas.running': 'en cours',
|
||
'canvas.openFailed': "Échec de l'ouverture du tableau",
|
||
'canvas.opening': 'Ouverture du tableau…',
|
||
'canvas.invalidId': 'Identifiant de canevas invalide',
|
||
'canvas.confirmDeleteChat': 'Supprimer cette discussion et son historique de messages ?',
|
||
'canvas.sessionDeleted': 'Session supprimée',
|
||
'canvas.chatUnlinked': 'Discussion dissociée — déplacée vers le bac à sable',
|
||
'canvas.unlinkFailed': 'Échec de la dissociation',
|
||
'canvas.unlinkButton': 'Dissocier',
|
||
'canvas.resizePanel': 'Redimensionner le panneau de discussion (glisser ou touches fléchées), actuellement {width} pixels',
|
||
'canvas.sendFailed': "Échec de l'envoi",
|
||
'canvas.runCancelled': 'Exécution annulée',
|
||
'canvas.cancelFailed': "Échec de l'annulation",
|
||
'canvas.tidied': '{count} cartes rangées en colonnes',
|
||
'canvas.tidyFailed': 'Échec du rangement',
|
||
'canvas.rename': 'Renommer le canevas',
|
||
'canvas.waitFinish': "Attendez la fin de l'exécution",
|
||
'canvas.unlinkFrom': 'Dissocier cette discussion de {title}',
|
||
'canvas.noChatYet': 'Pas encore de discussion sur ce canevas',
|
||
'canvas.collapseChat': 'Réduire la discussion',
|
||
'canvas.expandChat': 'Développer la discussion',
|
||
'canvas.deleteBlocked': 'Les assets de projet et les jobs en cours ne peuvent pas être supprimés ici – remplacez-les depuis les assets du projet',
|
||
'canvas.deleteFailed': 'Impossible de supprimer {count} carte(s)',
|
||
'canvas.deletedWithFile': '{count} carte(s) et fichier(s) supprimés de la bibliothèque d’assets',
|
||
'canvas.deletedCardOnly': '{count} carte(s) retirée(s) – fichier conservé (données du projet)',
|
||
'canvas.deletedMixed': '{files} fichier(s) supprimé(s), {kept} conservé(s) (données du projet)',
|
||
"global.somethingWentWrong": "Une erreur s'est produite.",
|
||
|
||
// --- Memory ---
|
||
'memory.title': 'Mémoire',
|
||
'memory.lead': "Faits persistants que l'agent retient d'une session à l'autre.",
|
||
'memory.empty': 'Rien enregistré pour le moment',
|
||
'memory.loading': 'Chargement de la mémoire',
|
||
'memory.placeholder': "Ajouter un fait que l'agent doit retenir…",
|
||
'memory.saveFailed': "Impossible d'enregistrer la mémoire",
|
||
'memory.saved': 'Enregistré',
|
||
'memory.deleteFailed': 'Impossible de supprimer',
|
||
'memory.forget': 'Oublier',
|
||
'memory.chooseProject': 'Projet',
|
||
'memory.kindConvention': 'Convention',
|
||
'memory.kindCorrection': 'Correction',
|
||
'memory.kindPreference': 'Préférence',
|
||
'memory.groupGlobal': 'Global',
|
||
'memory.groupProject': 'Projet',
|
||
'memory.scopeGlobal': 'Tous les projets',
|
||
'memory.scopeProject': 'Ce projet',
|
||
'memory.sourceAgent': 'Agent',
|
||
'memory.sourceYou': 'Vous',
|
||
'memory.usedCount': 'Utilisé {n} fois',
|
||
|
||
// --- Skills ---
|
||
'skills.title': 'Compétences',
|
||
'skills.lead': "Compétences de l'agent disponibles dans ce projet.",
|
||
'skills.close': 'Fermer',
|
||
'skills.copied': 'Copié',
|
||
'skills.copy': 'Copier le chemin',
|
||
'skills.copyPath': 'Chemin copié dans le presse-papiers',
|
||
'skills.copyPathBtn': 'Copier',
|
||
'skills.couldNotRead': 'Impossible de lire la compétence',
|
||
'skills.filesIn': 'Fichiers de cette compétence',
|
||
'skills.hideFiles': 'Masquer les fichiers',
|
||
'skills.showFiles': 'Afficher les fichiers',
|
||
'skills.howto1': "Les compétences ajoutent des capacités réutilisables à l'agent.",
|
||
'skills.howto2': 'Référencez une compétence avec @name dans le composeur.',
|
||
'skills.howto3': "L'agent la charge à la demande.",
|
||
'skills.howto4': 'Ajoutez des compétences en plaçant des dossiers sous .agents/skills.',
|
||
'skills.howtoTitle': 'Fonctionnement des compétences',
|
||
'skills.loadingFile': 'Chargement du fichier…',
|
||
'skills.noFiles': 'Aucun fichier',
|
||
'skills.noSkills': 'Aucune compétence disponible',
|
||
'skills.note': 'Remarque',
|
||
'skills.refresh': 'Actualiser',
|
||
'skills.refreshed': 'Compétences actualisées',
|
||
'skills.truncated': 'Aperçu tronqué',
|
||
|
||
// --- Reasoning ---
|
||
'reasoning.title': 'Raisonnement',
|
||
'reasoning.thinking': 'Réflexion…',
|
||
'reasoning.show': 'Afficher le raisonnement',
|
||
|
||
// --- Agent chat/composer ---
|
||
'agentChat.approveRender': 'Approuver le rendu',
|
||
'agentChat.approveReplace': 'Approuver le remplacement',
|
||
'agentChat.emptyHint': "L'agent est prêt. Demandez-lui de rédiger des trames, de modifier des ressources ou de composer des scènes.",
|
||
'agentChat.emptyTitle': 'Démarrer une conversation',
|
||
'agentChat.loading': 'Chargement de la conversation',
|
||
'agentChat.pickOption': 'Choisir une option',
|
||
'agentChat.working': "L'agent travaille…",
|
||
'agent.task.story': 'Rédiger la trame',
|
||
'agent.task.script': 'Régénérer le scénario',
|
||
'agentComposer.aria': 'Composeur de message',
|
||
'agentComposer.attach': 'Joindre un fichier',
|
||
'agentComposer.attachLimit': 'Limite de pièces jointes atteinte',
|
||
'agentComposer.attachments': 'Pièces jointes',
|
||
'agentComposer.mentionLock': 'Verrouillé sur ce projet',
|
||
'agentComposer.message': 'Message',
|
||
'agentComposer.placeholder': "Demandez à l'agent ou @mentionnez une compétence…",
|
||
'agentComposer.remove': 'Retirer la pièce jointe',
|
||
'agentComposer.sendTitle': 'Envoyer le message',
|
||
'agentComposer.stopTitle': "Arrêter l'agent",
|
||
'agentComposer.working': 'Envoi…',
|
||
'agentComposer.steer': 'Piloter',
|
||
'agentComposer.steerTitle': "Envoyer une correction pendant que l'agent travaille",
|
||
'agentComposer.steerPlaceholder': "Pilotez l'agent pendant qu'il travaille…",
|
||
'agentChat.steering': 'Pilotage',
|
||
'agentPlan.planner': 'Plan',
|
||
'agentPlan.skipped': 'Ignoré',
|
||
'agentTool.args': 'Arguments',
|
||
'agentTool.done': 'Terminé',
|
||
'agentTool.failed': 'Échec',
|
||
'agentTool.result': 'Résultat',
|
||
'agentTool.running': 'En cours…',
|
||
'mentionMenu.noSkill': 'Aucune compétence correspondante',
|
||
'mentionMenu.noWorkflow': 'Aucun workflow correspondant',
|
||
'mentionMenu.skills': 'Compétences',
|
||
'mentionMenu.workflows': 'Workflows',
|
||
|
||
// --- Agent session sidebar ---
|
||
'sessionSidebar.collapse': 'Réduire la barre latérale',
|
||
'sessionSidebar.expand': 'Développer la barre latérale',
|
||
'sessionSidebar.deleteSession': 'Supprimer la session',
|
||
'sessionSidebar.newProjectChat': 'Nouvelle discussion de projet',
|
||
'sessionSidebar.newSandbox': 'Nouveau bac à sable',
|
||
'sessionSidebar.newSandboxButton': 'Nouvelle session bac à sable',
|
||
'sessionSidebar.noSessions': 'Aucune session pour le moment',
|
||
'sessionSidebar.open': 'Ouvrir la session',
|
||
'sessionSidebar.projectFallback': 'Discussion de projet',
|
||
'sessionSidebar.sandbox': 'Bac à sable',
|
||
|
||
// --- Story stage ---
|
||
'story.stageTitle': 'Histoire',
|
||
'story.ideaTitle': "Idée d'histoire",
|
||
'story.ideaPlaceholder': "Décrivez l'histoire que vous voulez raconter…",
|
||
'story.targetLength': 'Durée cible',
|
||
'story.lengthsHint': 'Quelle durée doit avoir la vidéo finale ?',
|
||
'story.lengthHint': 'Guide le nombre de beats et de scènes.',
|
||
'story.draftStoryline': 'Rédiger la trame',
|
||
'story.draftPromptTitle': 'Prompt de rédaction',
|
||
'story.promptExplain': "Le brief final que l'agent utilise pour structurer l'histoire.",
|
||
'story.showPrompt': 'Afficher le prompt',
|
||
'story.hidePrompt': 'Masquer le prompt',
|
||
'story.promptCollapsedHint': 'Modifiez le prompt de rédaction avant de générer les beats.',
|
||
'story.addBeat': 'Ajouter un beat',
|
||
'story.addBeatManual': 'Ajouter un beat manuellement',
|
||
'story.addBeatFailed': "Impossible d'ajouter le beat",
|
||
'story.beatAdded': 'Beat ajouté',
|
||
'story.beatDeleted': 'Beat supprimé',
|
||
'story.beatSaved': 'Beat enregistré',
|
||
'story.deleteBeat': 'Supprimer le beat',
|
||
'story.deleteBeatFailed': 'Impossible de supprimer le beat',
|
||
'story.beats': 'Beats',
|
||
'story.editBeatTitle': 'Modifier le beat',
|
||
'story.editCharTitle': 'Modifier le personnage',
|
||
'story.editLocTitle': 'Modifier le lieu',
|
||
'story.editItemTitle': "Modifier l'objet",
|
||
'story.fieldAge': 'Âge',
|
||
'story.fieldAppearance': 'Apparence',
|
||
'story.fieldConsistency': 'Cohérence',
|
||
'story.fieldDescription': 'Description',
|
||
'story.fieldName': 'Nom',
|
||
'story.fieldPersonality': 'Personnalité',
|
||
'story.fieldRole': 'Rôle',
|
||
'story.fieldTitle': 'En-tête',
|
||
'story.noBeats': 'Aucun beat pour le moment',
|
||
'story.noBeatsBody': "Ajoutez des beats manuellement ou laissez l'agent rédiger une trame.",
|
||
'story.continueAssets': 'Continuer vers les ressources',
|
||
'story.confirmDeleteBeatMsg': 'Ce beat sera définitivement supprimé. Continuer ?',
|
||
'story.confirmDeleteBeatTitle': 'Supprimer le beat ?',
|
||
'story.confirmExampleMsg': "Cela remplace votre idée d'histoire actuelle par l'exemple.",
|
||
'story.confirmExampleTitle': "Charger l'exemple ?",
|
||
'story.exampleLoaded': 'Exemple chargé',
|
||
'story.extracted': "Extrait de l'histoire",
|
||
'story.charTag': 'PERSONNAGE',
|
||
'story.envTag': 'LIEU',
|
||
'story.itemTag': 'OBJET',
|
||
'story.beatsTitle': "Beats de l'histoire",
|
||
'story.characterSaved': 'Personnage enregistré',
|
||
'story.locationSaved': 'Lieu enregistré',
|
||
'story.itemSaved': 'Objet enregistré',
|
||
'story.openAssets': 'Ouvrir les ressources',
|
||
'story.loadExample': "Charger l'exemple",
|
||
'story.saveBeatFailed': "Impossible d'enregistrer le beat",
|
||
'story.saveCharacterFailed': "Impossible d'enregistrer le personnage",
|
||
'story.saveItemFailed': "Impossible d'enregistrer l'objet",
|
||
'story.saveLocationFailed': "Impossible d'enregistrer le lieu",
|
||
'story.saveSettingsFailed': "Impossible d'enregistrer les paramètres",
|
||
'story.settingsTitle': "Paramètres de l'histoire",
|
||
'story.llmBanner': "L'étape Histoire utilise le LLM actif pour rédiger et affiner les beats.",
|
||
'story.newBeat': 'Nouveau beat {n}',
|
||
|
||
// --- Assets stage ---
|
||
'assets.title': 'Ressources',
|
||
'assets.lead': 'Personnages, lieux et objets générés pour votre histoire.',
|
||
'assets.tabCharacters': 'Personnages',
|
||
'assets.tabEnvironments': 'Lieux',
|
||
'assets.tabItems': 'Objets',
|
||
'assets.tabAria': 'Onglets de type de ressource',
|
||
'assets.kind.character': 'Personnage',
|
||
'assets.kind.environment': 'Lieu',
|
||
'assets.kind.item': 'Objet',
|
||
'assets.charSheets': 'Feuilles de personnage',
|
||
'assets.envRefs': 'Références de lieu',
|
||
'assets.itemRefs': "Références d'objet",
|
||
'assets.charSheetPlaceholder': 'Feuille de référence',
|
||
'assets.optionEnvironment': 'Référence de lieu',
|
||
'assets.optionItem': "Référence d'objet",
|
||
'assets.optionSheet': 'Feuille de personnage',
|
||
'assets.generateImage': 'Générer une image',
|
||
'assets.generateSheet': 'Générer une feuille',
|
||
'assets.replaceImage': "Remplacer l'image",
|
||
'assets.regenImage': "Régénérer l'image",
|
||
'assets.regenSheet': 'Régénérer la feuille',
|
||
'assets.regenImageFor': "Régénérer l'image de « {name} »",
|
||
'assets.regenSheetFor': 'Régénérer la feuille de « {name} »',
|
||
'assets.generating': 'Génération…',
|
||
'assets.generatingEllipsis': 'Génération',
|
||
'assets.queuing': 'Mise en file…',
|
||
'assets.generateMissing': 'Générer les manquants',
|
||
'assets.generateMissingTitle': 'Générer les ressources manquantes',
|
||
'assets.editPrompt': 'Modifier le prompt',
|
||
'assets.savePrompt': 'Enregistrer le prompt',
|
||
'assets.resetSheetTemplate': 'Réinitialiser le modèle de feuille',
|
||
'assets.resetEnvTemplate': 'Réinitialiser le modèle de lieu',
|
||
'assets.resetItemTemplate': "Réinitialiser le modèle d'objet",
|
||
'assets.noCharsTitle': 'Aucun personnage pour le moment',
|
||
'assets.noCharsBody': "Les personnages apparaissent ici une fois définis par l'histoire.",
|
||
'assets.noEnvsTitle': 'Aucun lieu pour le moment',
|
||
'assets.noEnvsBody': "Les lieux apparaissent ici une fois définis par l'histoire.",
|
||
'assets.noItemsTitle': 'Aucun objet pour le moment',
|
||
'assets.noItemsBody': "Les objets apparaissent ici une fois définis par l'histoire.",
|
||
'assets.confirmDeleteTitle': 'Supprimer la ressource',
|
||
'assets.confirmDeleteLabel': 'Supprimer',
|
||
'assets.confirmDeleteBody': 'Cette ressource et ses images générées seront supprimées. Continuer ?',
|
||
'assets.confirmDeleteFallback': 'Supprimer cette ressource ?',
|
||
'assets.deleteCharacter': 'Supprimer le personnage',
|
||
'assets.deleteEnvironment': 'Supprimer le lieu',
|
||
'assets.deleteItem': "Supprimer l'objet",
|
||
'assets.deleteFor': 'Supprimer « {name} »',
|
||
'assets.description': 'Description',
|
||
'assets.appearance': 'Apparence',
|
||
'assets.personality': 'Personnalité',
|
||
'assets.cover': 'Couverture',
|
||
'assets.removeCover': 'Retirer la couverture',
|
||
'assets.removeCoverChar': 'Retirer la couverture du personnage',
|
||
'assets.removeCoverRef': 'Retirer la couverture de référence',
|
||
'assets.setCover': 'Définir comme couverture',
|
||
'assets.setCoverChar': 'Définir comme couverture du personnage',
|
||
'assets.setCoverRef': 'Définir comme couverture de référence',
|
||
'assets.refPlaceholder': 'Référence',
|
||
'assets.sentToComfy': 'Envoyé à ComfyUI',
|
||
'assets.uploadImage': 'Importer une image',
|
||
'assets.viewCharFull': 'Voir le personnage en entier',
|
||
'assets.viewRefFull': 'Voir la référence en entier',
|
||
'assets.viewFull': 'Voir en taille réelle',
|
||
'assets.charSheetAlt': 'Feuille de personnage pour {name}',
|
||
'assets.goToStory': "Aller à l'Histoire",
|
||
'assets.genSettings': 'Paramètres de génération',
|
||
'assets.toast.addImageFailed': "Impossible d'ajouter l'image",
|
||
'assets.toast.chooseImage': 'Choisissez une image',
|
||
'assets.toast.coverFail': 'Impossible de définir la couverture',
|
||
'assets.toast.coverRemoved': 'Couverture retirée',
|
||
'assets.toast.coverUpdated': 'Couverture mise à jour',
|
||
'assets.toast.deleted': 'Ressource supprimée',
|
||
'assets.toast.deleteFailed': 'Impossible de supprimer la ressource',
|
||
'assets.toast.imageAdded': 'Image ajoutée',
|
||
'assets.toast.jobRequeued': 'Demandé à nouveau',
|
||
'assets.toast.nothingMissing': 'Rien ne manque',
|
||
'assets.toast.notImage': "Ce fichier n'est pas une image",
|
||
'assets.toast.queued': 'Image mise en file',
|
||
'assets.toast.queuedMany': '{n} images mises en file',
|
||
'assets.toast.queuedOne': 'Image mise en file',
|
||
'assets.toast.retryFailed': 'Impossible de réessayer',
|
||
'assets.toast.savedPrompt': 'Prompt enregistré',
|
||
'assets.toast.savePromptFailed': "Impossible d'enregistrer le prompt",
|
||
'assets.wf.sheet': 'Workflow de feuille de personnage',
|
||
'assets.wf.environment': 'Workflow de référence de lieu',
|
||
'assets.wf.item': "Workflow de référence d'objet",
|
||
'assets.wf.selectSheet': 'Sélectionner un workflow de feuille',
|
||
'assets.wf.selectEnv': 'Sélectionner un workflow de lieu',
|
||
'assets.wf.selectItem': "Sélectionner un workflow d'objet",
|
||
'assets.wf.needWorkflow': "Configurez d'abord un workflow dans les Paramètres.",
|
||
'assets.wf.missingInputs': 'Ce workflow a des entrées obligatoires manquantes.',
|
||
'assets.wf.none': 'Aucun workflow sélectionné',
|
||
'assets.wf.noPromptPre': "Ce workflow n'a pas d'entrée de prompt.",
|
||
'assets.wf.noPromptPost': "Ajoutez un champ prompt pour l'utiliser ici.",
|
||
'assets.noWorkflowPre': 'La génération nécessite un workflow.',
|
||
'assets.noWorkflowPost': 'Configurez-en un dans les Paramètres.',
|
||
'assets.noWorkflowLink': 'Ouvrir les Paramètres',
|
||
|
||
// --- Build scene ---
|
||
'buildScene.title': 'Composer la scène',
|
||
'buildScene.builderBadge': 'Éditeur 3D',
|
||
'buildScene.preparing': 'Préparation de la scène…',
|
||
'buildScene.stillLoading': 'Scène en cours de chargement…',
|
||
'buildScene.expandChat': 'Développer la discussion',
|
||
'buildScene.collapseChat': 'Réduire la discussion',
|
||
'buildScene.videoExported': 'Vidéo exportée',
|
||
'buildScene.legacyNeedsViewport': 'Viewport pas prêt pour l\'export',
|
||
'buildScene.videoExportFailed': "Échec de l'export vidéo",
|
||
'buildScene.captureSaved': 'Capture enregistrée',
|
||
'buildScene.createSceneFailed': 'Impossible de créer la scène',
|
||
'buildScene.deleteSceneFailed': 'Impossible de supprimer la scène',
|
||
'buildScene.sendFailed': "Impossible d'envoyer le message",
|
||
'buildScene.runCancelled': 'Exécution annulée',
|
||
'buildScene.cancelFailed': "Impossible d'annuler",
|
||
'buildScene.openCompositionFailed': "Impossible d'ouvrir la composition",
|
||
'buildScene.uploadSizeFail': 'Fichier trop volumineux',
|
||
|
||
// --- Script stage ---
|
||
'script.actionField': 'Action',
|
||
'script.actionPlaceholder': 'Ce qui se passe dans cette scène…',
|
||
'script.dialogField': 'Dialogue',
|
||
'script.dialogPlaceholder': 'Qui dit quoi…',
|
||
'script.headingField': 'En-tête',
|
||
'script.headingPlaceholder': 'INT. PORT — NUIT',
|
||
'script.sceneNumber': 'Scène {n}',
|
||
'script.edit': 'Modifier la scène',
|
||
'script.editScene': 'Modifier la scène',
|
||
'script.editSceneNumbered': 'Modifier la scène {n}',
|
||
'script.durationField': 'Durée',
|
||
'script.addScene': 'Ajouter une scène',
|
||
'script.deleteSceneTitle': 'Supprimer la scène',
|
||
'script.deleteSceneMessage': 'Cette scène et ses plans seront supprimés. Continuer ?',
|
||
'script.delete': 'Supprimer la scène',
|
||
'script.loadingScenes': 'Chargement des scènes',
|
||
'script.noScenesTitle': 'Aucune scène pour le moment',
|
||
'script.noScenesBody': 'Découpez votre histoire en scènes pour commencer le tournage.',
|
||
'script.regenerate': 'Régénérer le scénario',
|
||
'script.break': 'Découper en plans',
|
||
'script.breakTitle': 'Découper la scène en plans',
|
||
'script.rebreak': 'Redécouper les plans',
|
||
'script.rebreakTitle': 'Redécouper les plans de cette scène',
|
||
'script.breakAllIntoShots': 'Tout découper en plans',
|
||
'script.breakAllTitle': 'Découper chaque scène en plans',
|
||
'script.chainOn': 'Activer le chaînage',
|
||
'script.chainOff': 'Désactiver le chaînage',
|
||
'script.chainTitle': 'Basculer le chaînage des clips',
|
||
'script.save': 'Enregistrer',
|
||
'script.untitledScene': 'Scène sans titre',
|
||
'script.untitledShot': 'Plan sans titre',
|
||
'script.justAdded': 'Ajouté',
|
||
'script.rendering': 'Rendu en cours…',
|
||
'script.renderedCount': '{n} clips rendus',
|
||
'script.clipDone': 'Clip terminé',
|
||
'script.noActionYet': 'Aucune action écrite pour le moment',
|
||
'script.shotClipSingular': '1 clip',
|
||
'script.shotClipPlural': '{n} clips',
|
||
'script.moveSceneUp': 'Déplacer la scène vers le haut',
|
||
'script.moveSceneDown': 'Déplacer la scène vers le bas',
|
||
'script.deleteShotAria': 'Supprimer le plan',
|
||
'script.deleteShotTitle': 'Supprimer le plan',
|
||
'script.status.rendering': 'Rendu',
|
||
'script.status.renderFailed': 'Échec',
|
||
'script.status.clipReady': 'Prêt',
|
||
'script.status.noClip': 'Aucun clip',
|
||
'script.toast.addSceneFail': "Impossible d'ajouter la scène",
|
||
'script.toast.boardExpanded': 'Scène ouverte sur le tableau',
|
||
'script.toast.breakAllConfirm': 'Découper toutes les scènes en plans ?',
|
||
'script.toast.breakAllFail': 'Impossible de découper les scènes',
|
||
'script.toast.breakFail': 'Impossible de découper la scène',
|
||
'script.toast.breakIntoShots': 'Scène découpée en plans',
|
||
'script.toast.deleteClipFail': 'Impossible de supprimer le clip',
|
||
'script.toast.deleted': 'Scène supprimée',
|
||
'script.toast.deletedShot': 'Plan supprimé',
|
||
'script.toast.deleteFailed': 'Impossible de supprimer',
|
||
'script.toast.saveSceneFail': "Impossible d'enregistrer la scène",
|
||
'script.toast.sceneAdded': 'Scène ajoutée',
|
||
'script.toast.sceneSaved': 'Scène enregistrée',
|
||
'script.toast.updateSceneFail': 'Impossible de mettre à jour la scène',
|
||
|
||
// --- Script drawer ---
|
||
'scriptDrawer.script': 'Scénario',
|
||
'scriptDrawer.heading': 'En-tête',
|
||
'scriptDrawer.action': 'Action',
|
||
'scriptDrawer.dialog': 'Dialogue',
|
||
'scriptDrawer.characters': 'Personnages',
|
||
'scriptDrawer.noAction': 'Aucune action écrite',
|
||
'scriptDrawer.noDialog': 'Aucun dialogue',
|
||
'scriptDrawer.regionAria': 'Zone du scénario',
|
||
'scriptDrawer.untitled': 'Sans titre',
|
||
'scriptDrawer.untitledScene': 'Scène sans titre',
|
||
|
||
// --- Queue stage ---
|
||
'queue.sceneLabel': 'Scène',
|
||
'queue.clipLabel': 'Clip n° {n}',
|
||
'queue.jobLabel': 'Tâche n° {n}',
|
||
'queue.scene': 'Scène {n}',
|
||
'queue.sceneRef': 'Référence de scène',
|
||
'queue.clipRef': 'Référence de clip',
|
||
'queue.clipQueued': 'Clip mis en file',
|
||
'queue.clipsDoneSummary': '{done}/{total} clips terminés',
|
||
'queue.clipsMissing': "Certains plans n'ont pas encore de clip",
|
||
'queue.clipRenderUpdated': 'Rendu du clip mis à jour',
|
||
'queue.clipsChanged': 'Clips modifiés',
|
||
'queue.blockoutLabel': 'Blockout',
|
||
'queue.blockoutSuffix': 'blockout',
|
||
'queue.blockoutClipSuffix': 'clip blockout',
|
||
'queue.uploadSuffix': 'import',
|
||
'queue.generateAllTitle': 'Générer tous les clips',
|
||
'queue.generateMissing': 'Générer les manquants',
|
||
'queue.regenerateAll': 'Tout régénérer',
|
||
'queue.queueingProgress': '{n}/{total} tâches mises en file',
|
||
'queue.queued': 'En file',
|
||
'queue.queuedInSequence': "S'exécutera en séquence",
|
||
'queue.pauseQueue': "Mettre la file en pause",
|
||
'queue.resumeQueue': "Reprendre la file",
|
||
'queue.paused': "File en pause",
|
||
'queue.pausedText': 'Les nouvelles tâches attendent que vous repreniez.',
|
||
'queue.resumeNow': 'Reprendre maintenant',
|
||
'queue.editTab': 'Scènes',
|
||
'queue.filmTab': 'Film',
|
||
'queue.filmViewAria': 'Vue film',
|
||
'queue.viewAria': "Vue de la file",
|
||
'queue.emptyHeader': 'Rien en file pour le moment',
|
||
'queue.noTimeline': 'Aucune timeline pour le moment',
|
||
'queue.noTimelineBody': "Générez d'abord des clips, puis exportez le film.",
|
||
'queue.savedDrafts': 'Brouillons enregistrés ici',
|
||
'queue.exportFilm': 'Exporter le film',
|
||
'queue.downloadFilm': 'Télécharger le film',
|
||
'queue.exporting': 'Export en cours…',
|
||
'queue.exportingTitle': 'Export du film',
|
||
'queue.exportingSub': 'Combinaison de {n} clips en une seule vidéo.',
|
||
'queue.exportQueued': 'Export mis en file',
|
||
'queue.exportedAgo': 'Exporté {ago}',
|
||
'queue.exportFailed': "Échec de l'export",
|
||
'queue.retryExport': "Réessayer l'export",
|
||
'queue.exportUnavailable': "Export pas encore disponible",
|
||
'queue.notExported': 'Non exporté',
|
||
'queue.notExportedTitle': 'Aucun export pour le moment',
|
||
'queue.slateSub': '{clips} clips · {time} · fondus de 0,5 s · volume homogénéisé',
|
||
'queue.staleBanner': "Clips modifiés depuis l'export",
|
||
'queue.exportDisabledTitle': 'Ajoutez au moins un clip à exporter',
|
||
'queue.chainDisabledReason': "Sélectionnez d'abord une scène ou un clip",
|
||
'queue.editInTimeline': 'Modifier dans la timeline',
|
||
'queue.inThisFilm': 'Dans ce film',
|
||
'queue.filmMeta': '{scenes} scènes · {clips} clips · {duration}',
|
||
'queue.reexport': 'Réexporter',
|
||
|
||
// --- Job / job drawer ---
|
||
'job.title': 'Tâche',
|
||
'job.status.generating': 'Génération',
|
||
'job.status.generatingPulse': 'Génération',
|
||
'job.status.queued': 'En file',
|
||
'job.status.running': 'En cours',
|
||
'job.status.done': 'Terminé',
|
||
'job.status.failed': 'Échec',
|
||
'job.cancelJob': 'Annuler la tâche',
|
||
'job.cancelFailed': "Impossible d'annuler la tâche",
|
||
'job.cancelled': 'Annulée',
|
||
'job.requeued': 'Remise en file',
|
||
'job.retryJob': 'Réessayer la tâche',
|
||
'job.retryFailed': 'Impossible de réessayer la tâche',
|
||
'job.exportFilm': 'Exporter le film',
|
||
'jobDrawer.title': 'Détails de la tâche',
|
||
'jobDrawer.historyAria': 'Historique des tâches',
|
||
'jobDrawer.noJobs': 'Aucune tâche pour le moment',
|
||
'jobDrawer.noPrompt': 'Aucun prompt pour cette tâche',
|
||
'jobDrawer.output': 'Résultat',
|
||
'jobDrawer.prompt': 'Prompt',
|
||
'jobDrawer.references': 'Références',
|
||
'jobDrawer.characterRef': 'Référence de personnage',
|
||
'jobDrawer.locationRef': 'Référence de lieu',
|
||
'jobDrawer.audioInput': 'Entrée audio',
|
||
'jobDrawer.videoInput': 'Entrée vidéo',
|
||
'jobDrawer.refImage': 'Image de référence',
|
||
'jobDrawer.currentClip': 'Clip actuel',
|
||
'jobDrawer.otherInputs': 'Autres entrées',
|
||
'jobDrawer.copy': 'Copier',
|
||
'jobDrawer.copied': 'Copié',
|
||
'jobDrawer.copySettings': 'Copier les paramètres',
|
||
'jobDrawer.applying': 'Application…',
|
||
'jobDrawer.applyToScene': 'Appliquer à la scène',
|
||
'jobDrawer.h3Hint': 'La sélection ci-dessus a été utilisée pour cette tâche.',
|
||
|
||
// --- Filmstrip ---
|
||
'filmstrip.title': 'Pellicule',
|
||
'filmstrip.clipTitle': '{scene} · plan {shot} · {time}',
|
||
'filmstrip.scene': 'Scène',
|
||
'filmstrip.sceneClips': '{n} clips',
|
||
'filmstrip.prev': 'Clip précédent',
|
||
'filmstrip.next': 'Clip suivant',
|
||
|
||
// --- Clip monitor / clip source ---
|
||
'clipMonitor.untitled': 'Clip sans titre',
|
||
'clipMonitor.id': 'ID du clip',
|
||
'clipMonitor.sceneId': 'ID de la scène',
|
||
'clipMonitor.generating': 'Génération…',
|
||
'clipMonitor.generationFailed': 'Échec de la génération',
|
||
'clipMonitor.queued': 'En file',
|
||
'clipMonitor.noRenderHint': "Ce clip n'a pas encore de rendu.",
|
||
'clipMonitor.downloadClip': 'Télécharger le clip',
|
||
'clipMonitor.videoUnavailable': 'Vidéo indisponible',
|
||
'clipMonitor.showDetails': 'Afficher les détails',
|
||
'clipMonitor.hideDetails': 'Masquer les détails',
|
||
'clipSource.title': 'Source du clip',
|
||
'clipSource.projectClips': 'Clips du projet',
|
||
'clipSource.noClips': 'Aucun clip disponible',
|
||
'clipSource.autoName': 'Auto',
|
||
'clipSource.autoDesc': 'Libellé automatique',
|
||
'clipSource.uploadName': 'Importer',
|
||
'clipSource.uploadDesc': 'Importer un fichier',
|
||
|
||
// --- Video edit workspace ---
|
||
'videoEdit.clipId': 'ID du clip',
|
||
'videoEdit.sceneId': 'ID de la scène',
|
||
'videoEdit.generateLabel': 'Générer',
|
||
'videoEdit.videoSource': 'Source vidéo',
|
||
'videoEdit.noVideoInputWf': "Ce workflow n'a pas d'entrée vidéo",
|
||
'videoEdit.noWf': 'Aucun workflow sélectionné',
|
||
'videoEdit.wfLink': 'Configurer les workflows dans les Paramètres',
|
||
'videoEdit.enableWfPre': 'Effectuer le rendu avec le workflow actif ?',
|
||
'videoEdit.enableWfPost': 'Il détermine le format de sortie.',
|
||
'videoEdit.assetHint': 'Choisissez la cible de génération',
|
||
'videoEdit.continueHint': 'Continuer avec le workflow sélectionné',
|
||
'videoEdit.viewPrompt': 'Voir le prompt',
|
||
'videoEdit.dockAria': 'Entrées de génération du clip',
|
||
|
||
// --- Shot brief ---
|
||
'shotBrief.copyTitle': 'Copier la description du plan',
|
||
'shotBrief.copied': 'Copié',
|
||
'shotBrief.copy': 'Copier',
|
||
'shotBrief.collapse': 'Réduire le brief du plan',
|
||
'shotBrief.expand': 'Développer le brief du plan',
|
||
'shotBrief.noDesc': 'Aucune description de plan — ce clip a hérité des valeurs par défaut de la scène.',
|
||
'shotBrief.notePre': "Ce clip n'a pas encore de description propre au plan — le texte ci-dessus est l'action complète de la scène. Utilisez",
|
||
'shotBrief.breakIntoShots': 'Découper en plans',
|
||
'shotBrief.notePost': "à l'étape Scénario pour le diviser en couverture.",
|
||
'shotBrief.dialogKey': 'Dialogue dans ce plan',
|
||
'shotBrief.characters': 'Personnages',
|
||
|
||
// --- Prompt preview modal ---
|
||
'promptPreview.title': 'Aperçu du prompt',
|
||
'promptPreview.generate': 'Générer',
|
||
'promptPreview.regenerate': 'Régénérer',
|
||
'promptPreview.resolving': 'Résolution du prompt…',
|
||
'promptPreview.saveDraft': 'Enregistrer le brouillon',
|
||
'promptPreview.draftSaved': 'Brouillon enregistré',
|
||
'promptPreview.promptEmpty': 'Rien à prévisualiser pour le moment',
|
||
'promptPreview.noClip': 'Aucun clip',
|
||
'promptPreview.noClipSelected': 'Aucun clip sélectionné',
|
||
'promptPreview.untitled': 'Sans titre',
|
||
'promptPreview.failedHint': "Échec de la résolution du prompt — affichage d'une solution de repli.",
|
||
'promptPreview.staleHint': 'La résolution est obsolète — renvoyez pour obtenir le prompt actuel.',
|
||
'promptPreview.fromDraftHint': 'Basé sur votre brouillon, pas sur le workflow actuel.',
|
||
'promptPreview.proseHint': 'Prompt en prose modifiable — les modifications restent locales.',
|
||
'promptPreview.h3Hint': 'Prompt construit à partir de la sélection ci-dessus.',
|
||
'promptPreview.criticTitle': 'Contrôle de continuité',
|
||
'promptPreview.h3Rewrite': 'Réécrit',
|
||
'promptPreview.editorAria': 'Éditeur de prompt',
|
||
'promptPreview.defaultWorkflow': 'par défaut',
|
||
'promptPreview.sceneMeta': 'Scène n° {index} · {heading}',
|
||
'promptPreview.shotMeta': 'Plan {label} · {heading}',
|
||
|
||
// --- Workflows (wf) ---
|
||
'wf.title': 'Workflows',
|
||
'wf.lead': 'Importez et enregistrez des workflows ComfyUI pour la génération.',
|
||
'wf.loadingWorkflows': 'Chargement des workflows',
|
||
'wf.noWorkflows': 'Aucun workflow enregistré',
|
||
'wf.noWorkflowsHint': 'Déposez un fichier JSON de workflow ci-dessous pour commencer.',
|
||
'wf.detectedInputs': 'Entrées détectées',
|
||
'wf.detectedOutputs': 'Sorties détectées',
|
||
'wf.inputs': 'Entrées',
|
||
'wf.outputs': 'Sorties',
|
||
'wf.inputsCount': '{n} entrées',
|
||
'wf.outputsCount': '{n} sorties',
|
||
'wf.kind': 'Type',
|
||
'wf.kindImage': 'Image',
|
||
'wf.kindVideo': 'Vidéo',
|
||
'wf.enable': 'Activer',
|
||
'wf.disable': 'Désactiver',
|
||
'wf.disabled': 'Désactivé',
|
||
'wf.stateEnabled': 'Activé',
|
||
'wf.stateDisabled': 'Désactivé',
|
||
'wf.enabledState': 'Activé',
|
||
'wf.hideIo': 'Masquer les entrées/sorties',
|
||
'wf.viewIo': 'Afficher les entrées/sorties',
|
||
'wf.dropHint': 'Déposez le JSON du workflow ici',
|
||
'wf.dropSub': 'ou cliquez pour parcourir',
|
||
'wf.namePlaceholder': 'Nom du workflow',
|
||
'wf.descPlaceholder': 'Brève description (facultatif)',
|
||
'wf.invalidJson': "Ce fichier n'est pas un JSON de workflow valide",
|
||
'wf.jsonLocked': 'Verrouillé par une tâche active',
|
||
'wf.jsonPreview': 'JSON du workflow',
|
||
'wf.reanalyze': 'Réanalyser',
|
||
'wf.saveToLibrary': 'Enregistrer dans la bibliothèque',
|
||
'wf.savedWorkflows': 'Workflows enregistrés',
|
||
'wf.savedToLibrary': 'Enregistré dans la bibliothèque',
|
||
'wf.saveFailed': "Impossible d'enregistrer le workflow",
|
||
'wf.updateFailed': 'Impossible de mettre à jour le workflow',
|
||
'wf.updated': 'Workflow mis à jour',
|
||
'wf.deleted': 'Workflow supprimé',
|
||
'wf.deleteFailed': 'Impossible de supprimer le workflow',
|
||
'wf.deleteTitle': 'Supprimer le workflow',
|
||
'wf.deleteMessage': 'Ce workflow et son JSON enregistré seront supprimés.',
|
||
'wf.analyzeRegister': 'Analyser et enregistrer',
|
||
'wf.countImage': '{n} images',
|
||
'wf.countVideo': '{n} vidéos',
|
||
'wf.countSaved': '{n} enregistrés',
|
||
'wf.profileH3': "Cas d'usage",
|
||
'wf.profileProse': 'Ce workflow génère {kind} à partir de {target}.',
|
||
'wf.promptFormat': 'Format du prompt',
|
||
'wf.noInputs': 'Aucune entrée détectée',
|
||
'wf.noInputsCached': 'Aucune entrée',
|
||
'wf.noOutputs': 'Aucune sortie détectée',
|
||
'wf.noOutputsCached': 'Aucune sortie',
|
||
|
||
// --- Comfy dynamic form (cdf) ---
|
||
'cdf.browse': 'Parcourir',
|
||
'cdf.chooseAsset': 'Choisir une ressource',
|
||
'cdf.clear': 'Effacer',
|
||
'cdf.clearAria': 'Effacer le champ',
|
||
'cdf.dropPre': 'Déposez un fichier',
|
||
'cdf.localPath': 'Chemin local',
|
||
'cdf.noAssets': 'Aucune ressource pour le moment',
|
||
'cdf.noInputs': 'Aucune entrée configurable',
|
||
'cdf.orChooseAsset': 'ou choisissez une ressource',
|
||
'cdf.required': 'obligatoire',
|
||
'cdf.requiredMsg': 'Ce champ est obligatoire',
|
||
'cdf.selectedPreviewAlt': 'Aperçu sélectionné',
|
||
'cdf.uploadedPreviewAlt': 'Aperçu importé',
|
||
'cdf.uploadFailed': "Échec de l'import",
|
||
'cdf.uploading': 'Import en cours…',
|
||
|
||
// --- Omni composer ---
|
||
'omni.advanced': 'Avancé',
|
||
'omni.assetType': 'Type de ressource',
|
||
'omni.choose': 'Choisir',
|
||
'omni.chooseReference': 'Choisir une référence',
|
||
'omni.clearSlot': "Vider l'emplacement",
|
||
'omni.decrease': 'Diminuer',
|
||
'omni.increase': 'Augmenter',
|
||
'omni.duration': 'Durée',
|
||
'omni.resolution': 'Résolution',
|
||
'omni.seed': 'Graine',
|
||
'omni.emptyCharacters': 'Aucun personnage pour le moment',
|
||
'omni.emptyLocations': 'Aucun lieu pour le moment',
|
||
'omni.emptyItems': 'Aucun objet pour le moment',
|
||
'omni.emptyShots': 'Aucun plan pour le moment',
|
||
'omni.emptyClips': 'Aucun clip pour le moment',
|
||
'omni.emptyUploads': 'Aucun import pour le moment',
|
||
'omni.emptyUploadsNew': 'Aucun import pour le moment',
|
||
'omni.generate': 'Générer',
|
||
'omni.generateAria': 'Générer',
|
||
'omni.negativeAria': 'Prompt négatif',
|
||
'omni.negativePlaceholder': 'Prompt négatif…',
|
||
'omni.negativeToggle': 'Prompt négatif',
|
||
'omni.noMatches': 'Aucun résultat',
|
||
'omni.noPromptRole': "Ce workflow n'a pas d'entrée de prompt",
|
||
'omni.promptAria': 'Prompt',
|
||
'omni.promptPlaceholder': "Décrivez l'image…",
|
||
'omni.queuing': 'Mise en file…',
|
||
'omni.removeSlot': 'Retirer',
|
||
'omni.required': 'Obligatoire',
|
||
'omni.roleAudio': 'Audio',
|
||
'omni.roleCharacter': 'Personnage',
|
||
'omni.roleLocation': 'Lieu',
|
||
'omni.roleVideo': 'Vidéo',
|
||
'omni.searchAssets': 'Rechercher des ressources',
|
||
'omni.searchIn': 'Rechercher dans',
|
||
'omni.thisList': 'cette liste',
|
||
'omni.uploadNew': 'Importer',
|
||
|
||
// --- Attach to project dialog ---
|
||
'attach.panelAria': 'Joindre au projet',
|
||
'attach.title': 'Joindre au projet',
|
||
'attach.addToProject': 'Ajouter au projet',
|
||
'attach.noScenes': 'Aucune scène pour le moment',
|
||
'attach.noCharacters': 'Aucun personnage pour le moment',
|
||
'attach.noLocations': 'Aucun lieu pour le moment',
|
||
'attach.pickProject': 'Choisir un projet',
|
||
'attach.selectProject': 'Sélectionner un projet',
|
||
'attach.selectScene': 'Sélectionner une scène',
|
||
'attach.selectCharacter': 'Sélectionner un personnage',
|
||
'attach.selectLocation': 'Sélectionner un lieu',
|
||
'attach.pickCharacter': 'Choisir un personnage',
|
||
'attach.pickLocation': 'Choisir un lieu',
|
||
'attach.pickScene': 'Choisir une scène',
|
||
'attach.projectField': 'Projet',
|
||
'attach.sceneField': 'Scène',
|
||
'attach.characterField': 'Personnage',
|
||
'attach.locationField': 'Lieu',
|
||
'attach.nameField': 'Nom',
|
||
'attach.asCharacterSheet': 'comme feuille de personnage',
|
||
'attach.asItem': 'comme objet',
|
||
'attach.asLocation': 'comme lieu',
|
||
'attach.addAs': 'Ajouter comme',
|
||
'attach.addBtn': 'Ajouter',
|
||
'attach.added': 'Joint',
|
||
'attach.addedTo': 'Ajouté à « {title} »',
|
||
'attach.failed': 'Impossible de joindre',
|
||
'attach.dismiss': 'Ignorer',
|
||
'attach.viewInProject': 'Voir dans le projet',
|
||
'attach.newItem': 'Nouvel objet',
|
||
'attach.newItemHint': 'Créer un objet à partir de ce média.',
|
||
'attach.newItemPlaceholder': "Nom de l'objet",
|
||
'attach.projectFallback': 'Projet sans titre',
|
||
'attach.scene': 'Scène',
|
||
|
||
// --- Asset Library ---
|
||
'library.selectAll': 'Tout sélectionner',
|
||
'library.deselectAll': 'Tout désélectionner',
|
||
'library.itemCount': '{count} élément(s)',
|
||
'library.loadError': 'Échec du chargement de la bibliothèque',
|
||
'library.subtitle': 'Les ressources générées au même endroit : prévisualisez, filtrez et supprimez les images et vidéos sans projet',
|
||
'library.deleteSelected': 'Supprimer ({count})',
|
||
'library.addToProject': 'Ajouter au projet',
|
||
'library.filterLabel': 'Filtrer par type',
|
||
'library.filterAll': 'Tout',
|
||
'library.filterImage': 'Images',
|
||
'library.filterVideo': 'Vidéos',
|
||
'library.loadMore': 'Charger plus ({count} restants)',
|
||
'library.loadingMore': 'Chargement…',
|
||
'library.confirmDelete': 'Supprimer {count} fichier(s) sélectionné(s) de la bibliothèque d’assets ? Cette action est irréversible.',
|
||
'library.deleted': '{count} fichier(s) supprimé(s)',
|
||
'library.deletedPartial': '{kept} fichier(s) conservé(s) – encore référencé(s) par des données du projet',
|
||
'library.deleteFailed': 'Échec de la suppression',
|
||
'library.emptyTitle': 'La bibliothèque d’assets est vide',
|
||
'library.emptyBody': 'Les images et vidéos non liées à un projet arrivent ici – via un import sur un canvas ou une génération dans un chat sandbox.',
|
||
'library.emptyFilterTitle': 'Aucun élément {kind} dans la bibliothèque',
|
||
'library.emptyFilterBody': 'Rien ne correspond à ce filtre pour l’instant – essayez « Tout » ou générez quelque chose de nouveau.',
|
||
|
||
// --- Settings ---
|
||
'settings.pageSub': 'File de génération, exécution des agents et chemins · LLM, connexions ComfyUI et Skills ont leur propre page',
|
||
'settings.secQueue': 'File et génération',
|
||
'settings.secQueueBlurb': 'Parallélisme, relances, interrogation et essai',
|
||
'settings.secAgent': 'Exécution des agents',
|
||
'settings.secAgentBlurb': 'Étapes, contexte, durcissement des prompts et shell',
|
||
'settings.secStorage': 'Chemins de stockage',
|
||
'settings.secStorageBlurb': 'Dossiers de données, ressources et espace de travail',
|
||
'settings.elsewhere': 'Géré ailleurs',
|
||
'settings.linkModelsBlurb': 'LLM et modèle par défaut de chaque agent',
|
||
'settings.linkConnectionsBlurb': 'Adresses, tests de connexion et bibliothèque de workflows',
|
||
'settings.linkAgentsBlurb': 'Skills et discussions dédiées des cinq agents',
|
||
'settings.dryRunTitle': 'Mode essai',
|
||
'settings.dryRunHint': 'Activé : ComfyUI n’est pas appelé et les tâches renvoient des images / vidéos factices ; désactivez pour générer réellement.',
|
||
'settings.agentRunSection': 'Exécution des agents',
|
||
'settings.agentRunLead': 'Limite les étapes d’outils par exécution et l’historique transmis.',
|
||
'settings.rangeHint': 'Plage {min}–{max}',
|
||
'settings.loadFailed': 'Impossible de charger les réglages : vérifiez que le serveur tourne',
|
||
'skillName.character-consistency': 'Cohérence des personnages',
|
||
'skillName.h3-video-prompt-enhancer': 'Amélioration de prompts vidéo H3',
|
||
'skillName.scene-to-video': 'Scène en vidéo',
|
||
'skillName.shot-composer-blockout': 'Pré-cadrage du plan',
|
||
'settings.loading': 'Chargement des paramètres',
|
||
'settings.allSaved': 'Toutes les modifications sont enregistrées',
|
||
'settings.unsaved': 'Modifications non enregistrées',
|
||
'settings.saveChanges': 'Enregistrer les modifications',
|
||
'settings.discard': 'Abandonner',
|
||
'settings.saved': 'Enregistré',
|
||
'settings.saveFailed': "Impossible d'enregistrer les paramètres",
|
||
'settings.savedDryRun': 'Exécution à blanc enregistrée',
|
||
'settings.current': 'Actuel',
|
||
'settings.useThis': 'Utiliser',
|
||
'settings.useActiveLlm': 'Actuellement actif',
|
||
'settings.llmSection': 'LLM',
|
||
'settings.llmLead': "Configurez les modèles de langage utilisés par l'agent.",
|
||
'settings.addLlm': 'Ajouter un LLM',
|
||
'settings.addAtLeastOneLlm': 'Ajoutez au moins un LLM.',
|
||
'settings.llmNamePlaceholder': 'Mon LLM',
|
||
'settings.llmDefaultName': 'Modèle générique',
|
||
'settings.newLlmDefault': 'Nouveau LLM',
|
||
'settings.model': 'Modèle',
|
||
'settings.baseUrl': 'URL de base',
|
||
'settings.apiKey': 'Clé API',
|
||
'settings.apiKeyOptional': 'Facultatif',
|
||
'settings.apiKeyHint': "Certains fournisseurs n'exigent aucune clé.",
|
||
'settings.apiKeySaved': 'Clé enregistrée',
|
||
'settings.requiredName': 'Le nom est obligatoire',
|
||
'settings.requiredModel': 'Le modèle est obligatoire',
|
||
'settings.requiredBaseUrl': "L'URL de base est obligatoire",
|
||
'settings.invalidValue': 'Valeur invalide',
|
||
'settings.invalidField': 'Invalide',
|
||
'settings.remove': 'Retirer',
|
||
'settings.removeLlmTitle': 'Retirer le LLM',
|
||
'settings.name': 'Nom',
|
||
'settings.active': 'Actif',
|
||
'settings.testLlm': 'Tester la connexion',
|
||
'settings.llmTestOk': 'Connexion réussie ({ms} ms)',
|
||
'settings.llmTestFail': 'Échec de connexion : {detail}',
|
||
'settings.llmTestAuth': 'Clé refusée ({detail})',
|
||
'settings.llmTestTimeout': 'Aucune réponse sous 15 s',
|
||
'settings.llmTestConnect': 'Serveur injoignable ({detail})',
|
||
'settings.agentModelsSection': 'Modèle agent',
|
||
'settings.agentModelsLead': "Modèle utilisé pour la rédaction de l'histoire et les tâches de l'agent.",
|
||
'settings.agentMaxStepsField': 'Étapes max.',
|
||
'settings.agentMaxStepsHint': "Limite d'appels d'outils par exécution de l'agent.",
|
||
'settings.queueSection': "File d'attente",
|
||
'settings.queueLead': 'Parallélisme et délais des tâches de génération et des appels d’outils de l’agent.',
|
||
'settings.concurrencyField': 'Tâches simultanées',
|
||
'settings.pollIntervalField': 'Intervalle de vérification (s)',
|
||
'settings.pollTimeoutField': 'Délai de la tâche (s)',
|
||
'settings.pollTimeoutHint': 'Durée maximale d’un job ComfyUI ou d’un appel d’outil de l’agent. 0 attend la fin.',
|
||
'settings.maxRetriesField': 'Tentatives max.',
|
||
'settings.maxError': 'Trop élevé',
|
||
'settings.minError': 'Trop faible',
|
||
'settings.notNumber': 'Doit être un nombre',
|
||
'settings.comfySection': 'ComfyUI',
|
||
'settings.comfyLead': "Où ComfyUI s'exécute.",
|
||
'settings.comfyHint': 'Doit être accessible depuis cette machine.',
|
||
'settings.storageSection': 'Chemins système',
|
||
'settings.storageLead': "Où les fichiers sont stockés et où l'agent peut travailler.",
|
||
'settings.storageCalloutStrong': 'Changer le répertoire de données',
|
||
'settings.storageCalloutBody': "déplace les ressources. Les chemins existants continuent de fonctionner jusqu'à la définition ici.",
|
||
'settings.dataDir': 'Répertoire de données',
|
||
'settings.assetsDir': 'Répertoire des ressources',
|
||
'settings.workspaceDir': "Espace de travail de l'agent",
|
||
'settings.workspaceDirHint':
|
||
"Dossier isolé où le shell de l'agent (run_command) peut travailler. Vide = DATA_DIR/workspace. L'agent ne peut rien toucher en dehors.",
|
||
'settings.shellSection': "Shell de l'agent",
|
||
'settings.shellLead': "Permet à l'agent d'exécuter des outils en ligne de commande dans son espace de travail.",
|
||
'settings.shellCalloutStrong': 'Sur activation :',
|
||
'settings.shellCalloutBody':
|
||
"les commandes s'exécutent sur cette machine, isolées dans l'espace de travail de l'agent. Les fichiers sensibles (config, base de données, identifiants) sont toujours refusés ; tout ce qui n'est pas en lecture seule vous est demandé avant.",
|
||
'settings.shellLabel': "Activer le shell de l'agent (run_command)",
|
||
'settings.shellHint':
|
||
'Désactivé par défaut. Une fois activé, l\'agent peut lancer librement des commandes d\'inspection (ffprobe) ; les commandes modifiantes ne passent qu\'après approbation via une carte de question scope="shell".',
|
||
'settings.historyBudgetSection': 'Budget d\'historique du contexte',
|
||
'settings.historyBudgetLead':
|
||
'Limite la quantité d\'historique de conversation rejouée à chaque requête de l\'agent, afin que les longues sessions ne débordent jamais de la fenêtre de contexte du modèle.',
|
||
'settings.historyBudgetField': 'Budget d\'historique (caractères)',
|
||
'settings.historyBudgetHint':
|
||
'≈4 caractères par token. Les tours les plus anciens sont d\'abord retirés ; les préréglages ci-dessous sont de bons points de départ.',
|
||
'settings.historyBudgetSmall': 'Petit · 60k',
|
||
'settings.historyBudgetMedium': 'Moyen · 120k',
|
||
'settings.historyBudgetLarge': 'Grand · 400k',
|
||
'settings.hardeningSection': 'Renforcement du prompt',
|
||
'settings.hardeningLead': 'Règles ajoutées au début des prompts de génération.',
|
||
'settings.hardeningHint': 'Sert à imposer des contraintes négatives ou des garde-fous de style.',
|
||
'settings.hardeningPlaceholder': 'Pas de violence, pas de gore, pas de contenu explicite.',
|
||
'settings.hardeningRulesLabel': 'Règles de renforcement',
|
||
'settings.hardeningCalloutStrong': "Le renforcement s'applique",
|
||
'settings.hardeningCalloutBody': 'à chaque prompt envoyé dans le pipeline.',
|
||
'settings.leaveTitle': 'Quitter sans enregistrer ?',
|
||
'settings.leaveMessage': 'Vous avez des modifications non enregistrées qui seront perdues.',
|
||
'settings.leaveConfirm': 'Quitter',
|
||
'settings.dryRunLabel': 'Valider uniquement (exécution à blanc)',
|
||
|
||
// --- Shot editor ---
|
||
'shot.scene': 'Scène',
|
||
'shot.hint': 'Ajoutez des objets, cadrez le plan, puis capturez.',
|
||
'shot.addObject': 'Ajouter un objet',
|
||
'shot.clearScene': 'Vider la scène',
|
||
'shot.visibility': 'Basculer la visibilité',
|
||
'shot.lock': 'Basculer le verrouillage',
|
||
'shot.emptyScene': 'La scène est vide',
|
||
'shot.objName.male': 'Homme',
|
||
'shot.objName.female': 'Femme',
|
||
'shot.objName.child': 'Enfant',
|
||
'shot.objName.cube': 'Cube',
|
||
'shot.objName.plane': 'Plan',
|
||
'shot.objName.cylinder': 'Cylindre',
|
||
'shot.objName.sphere': 'Sphère',
|
||
'shot.objName.capsule': 'Capsule',
|
||
'shot.objName.cone': 'Cône',
|
||
'shot.objName.torus': 'Tore',
|
||
'shot.objName.camera': 'Caméra',
|
||
'shot.selectObject': 'Sélectionner un objet',
|
||
'shot.selectObjectPose': 'Sélectionner un objet et le mettre en pose',
|
||
'shot.fov': 'Champ de vision',
|
||
'shot.transform': 'Transformation',
|
||
'shot.pose': 'Pose',
|
||
'shot.shotSection': 'Plan',
|
||
'shot.shotSize': 'Taille du plan',
|
||
'shot.angle': 'Angle de caméra',
|
||
'shot.elevation': 'Élévation',
|
||
'shot.composition': 'Composition',
|
||
'shot.center': 'Centre',
|
||
'shot.captureRef': 'Capture de référence',
|
||
'shot.railExpand': 'Développer la barre des sessions',
|
||
'shot.railCollapse': 'Réduire la barre des sessions',
|
||
'shot.railOpen': 'Ouvrir {title}',
|
||
'shot.railNoScenes': 'Aucune scène pour le moment',
|
||
'shot.railDeleteScene': 'Supprimer la scène',
|
||
'shot.newScene': 'Nouvelle scène',
|
||
'shot.captures': '{count} captures',
|
||
'shot.videoBadge': 'Vidéo',
|
||
'shot.captureAlt': 'Capture de scène',
|
||
'shot.noCaptures': 'Aucune capture pour le moment',
|
||
'shot.timelinePlay': 'Lecture',
|
||
'shot.timelinePause': 'Pause',
|
||
'shot.timelinePlayhead': 'Tête de lecture',
|
||
'shot.camKeyframe': 'Caméra à {time} s',
|
||
'shot.objKeyframe': '{name} à {time} s',
|
||
'shot.keyframeCamAdd': 'Ajouter une image clé de caméra',
|
||
'shot.keyframeCamRemove': "Supprimer l'image clé de caméra",
|
||
'shot.keyframeObjAdd': 'Ajouter une image clé pour {name}',
|
||
'shot.keyframeObjDelete': "Supprimer l'image clé",
|
||
'shot.keyframeObjSelectFirst': "Sélectionnez d'abord un objet",
|
||
'shot.exportHint': 'Objets de scène ou au moins 2 images clés de caméra requis (captures facultatives).',
|
||
'shot.exportHintNeedBeats': 'Ajoutez des objets de scène ou ≥2 images clés de caméra pour exporter. Captures facultatives.',
|
||
'shot.exportTitle': 'Exporter la timeline',
|
||
'shot.exportImage': 'Exporter l\'image',
|
||
'shot.exportVideo': 'Exporter la vidéo',
|
||
'shot.viewportTools': 'Outils',
|
||
'shot.toolSelect': 'Sélection',
|
||
'shot.toolSelectTitle': 'Outil de sélection',
|
||
'shot.toolMove': 'Déplacement',
|
||
'shot.toolMoveTitle': 'Outil de déplacement',
|
||
'shot.toolRotate': 'Rotation',
|
||
'shot.toolRotateTitle': 'Outil de rotation',
|
||
'shot.toolScale': 'Échelle',
|
||
'shot.toolScaleTitle': "Outil d'échelle",
|
||
'shot.toolPose': 'Pose',
|
||
'shot.toolPoseTitle': 'Outil de pose',
|
||
'shot.toolPoseDisabled': 'Sélectionnez un objet pour le mettre en pose',
|
||
'shot.undoTitle': 'Annuler',
|
||
'shot.redoTitle': 'Rétablir',
|
||
'shot.gridTitle': 'Basculer la grille',
|
||
'shot.grid': 'Grille',
|
||
'shot.compositionTitle': 'Basculer les guides de composition',
|
||
'shot.captureTitle': 'Capturer une image',
|
||
'shot.capture': 'Capturer',
|
||
'shot.errBlob': "Impossible de lire l'image capturée",
|
||
'shot.errRecorder': "Impossible de démarrer l'enregistreur",
|
||
'shot.errNoData': 'Aucune donnée de scène à exporter',
|
||
|
||
// Models settings page (spec-v2 §9)
|
||
'models.title': 'Modèles',
|
||
'models.subtitle': 'Ajoutez des LLM personnalisés pour vos agents · la phase 1 ne couvre que les LLM ; les modèles image / vidéo arriveront ensuite',
|
||
'models.statusCount': '{n} modèles · {m} disponibles',
|
||
'models.add': 'Ajouter un modèle',
|
||
'models.tabLlm': 'Modèles de langage',
|
||
'models.tabImage': "Modèles d'image",
|
||
'models.tabVideo': 'Modèles vidéo',
|
||
'models.comingSoon': 'À venir',
|
||
'models.empty': 'Aucun modèle pour l’instant — cliquez sur « Ajouter un modèle » en haut à droite pour connecter votre premier LLM',
|
||
'models.typeLocal': 'Local',
|
||
'models.typeLan': 'LAN',
|
||
'models.typeCloud': 'Cloud',
|
||
'models.defaultBadge': 'Par défaut',
|
||
'models.setDefault': 'Définir par défaut',
|
||
'models.defaultSetToast': 'Modèle par défaut des agents défini',
|
||
'models.test': 'Tester la connexion',
|
||
'models.testing': 'Test en cours…',
|
||
'models.edit': 'Modifier',
|
||
'models.delete': 'Supprimer',
|
||
'models.statusUntested': 'Non testé',
|
||
'models.statusConnected': 'Connecté',
|
||
'models.statusFailed': 'Échec de connexion',
|
||
'models.latency': 'latence {ms}ms',
|
||
'models.agentsUsing': 'utilisé par {n} agents',
|
||
'models.lastTestAt': 'dernier test {time}',
|
||
'models.consecutiveFails': '{n} échecs consécutifs',
|
||
'models.cloudPaused': 'Appels cloud suspendus',
|
||
'models.formTitleAdd': 'Ajouter un modèle',
|
||
'models.formTitleEdit': 'Modifier le modèle',
|
||
'models.formClose': 'Fermer',
|
||
'models.fName': 'Nom',
|
||
'models.fNamePh': 'Nommez le modèle, ex. DeepSeek officiel',
|
||
'models.fApiType': 'Type d’API',
|
||
'models.apiOpenai': 'Compatible OpenAI',
|
||
'models.apiAnthropic': 'Anthropic',
|
||
'models.apiOther': 'Autre',
|
||
'models.apiTypeHelp': 'La phase 1 ne prend en charge que les API compatibles OpenAI ; les autres protocoles arriveront avec les modèles image / vidéo',
|
||
'models.fBaseUrl': 'URL de base',
|
||
'models.baseUrlHelp': 'Avec protocole et port, ex. http://192.168.200.18:11434/v1',
|
||
'models.fModel': 'Nom du modèle',
|
||
'models.modelHelp': 'Utilisez l’identifiant de modèle fourni par votre prestataire',
|
||
'models.fApiKey': 'Clé API',
|
||
'models.keyNoEcho': 'jamais affichée',
|
||
'models.keyHelp': 'Stockée uniquement sur ce serveur ; la clé complète n’apparaît jamais dans l’interface',
|
||
'models.keyKeepHint': 'Clé enregistrée — laissez vide pour la conserver',
|
||
'models.fTimeout': 'Délai d’attente',
|
||
'models.timeoutSec': '{n}s',
|
||
'models.testOk': '✓ Test réussi · {ms}ms · {model} disponible',
|
||
'models.testFail': '✕ Échec du test · {reason}',
|
||
'models.needTest': 'Enregistrement possible après un test réussi',
|
||
'models.testBtn': 'Test connection',
|
||
'models.save': 'Enregistrer le modèle',
|
||
'models.errName': 'Veuillez nommer le modèle',
|
||
'models.errUrl': 'URL invalide — protocole et chemin requis, ex. https://api.deepseek.com/v1',
|
||
'models.errModel': 'Saisissez le nom du modèle fourni par votre prestataire',
|
||
'models.errKey': 'Saisissez la clé API',
|
||
'models.failTimeout': 'Délai dépassé ({sec}s sans réponse) : le serveur n’atteint pas cette adresse — vérifiez adresse, port et pare-feu',
|
||
'models.failAuth': 'Échec d’authentification (401) : vérifiez que la clé API est correcte et non expirée ; avec les agrégateurs, confirmez que le modèle est activé',
|
||
'models.failNotFound': 'Joignable mais modèle introuvable (404) : vérifiez l’orthographe du nom',
|
||
'models.failNotOpenai': 'Joignable mais non reconnue comme API compatible OpenAI — le chemin doit se terminer par /v1',
|
||
'models.failConnect': 'Le serveur ne peut pas se connecter à cette adresse — vérifiez adresse et port',
|
||
'models.failHttp': 'Test failed (HTTP {status})',
|
||
'models.delTitle': 'Supprimer le modèle',
|
||
'models.delConfirmUsed': '{n} agents utilisent ce modèle ; après suppression ils reviendront au modèle par défaut. Supprimer ?',
|
||
'models.delConfirmFree': 'Supprimer ce modèle ? Action irréversible.',
|
||
'models.delDefaultHint': 'Ce modèle est celui par défaut — choisissez d’abord un autre défaut',
|
||
'models.agentsTitle': 'Modèles par défaut des agents',
|
||
'models.agentsHint': 'Appliqué aux nouvelles sessions · réglage par agent sur la page Agents',
|
||
'models.agentDefault': 'Par défaut',
|
||
'models.agentStory': 'Scénario',
|
||
'models.agentStyle': 'Direction visuelle',
|
||
'models.agentScript': 'Storyboards',
|
||
'models.agentAssets': 'Bibliothèque d’assets',
|
||
'models.agentVideo': 'Plans de tournage',
|
||
'models.unavailable': '(indisponible)',
|
||
'models.noticeStrong': 'La connectivité est mesurée depuis le serveur du workbench :',
|
||
'models.noticeBody': 'une URL qui s’ouvre dans votre navigateur n’est pas forcément accessible au serveur ; les tests de connexion et les requêtes sont faits par le serveur. Les clés API restent sur le serveur et ne sont jamais affichées.',
|
||
'models.saved': 'Modèle enregistré',
|
||
'models.deleted': 'Modèle supprimé',
|
||
'models.assignSaved': 'Modèles des agents mis à jour',
|
||
'models.saveFailed': 'Échec de l’enregistrement : {detail}',
|
||
'models.loading': 'Chargement…',
|
||
'models.loadFailed': 'Impossible de charger les paramètres',
|
||
'models.idleFormHint': 'Cliquez « Modifier » sur une carte ou « Ajouter un modèle » ci-dessus',
|
||
|
||
// --- A shell + projects overview (HEL-608) ---
|
||
'shell.brand': 'Atelier Cinéma',
|
||
'shell.brandMark': 'A',
|
||
'shell.brandHome': 'Retour à l\'aperçu des projets',
|
||
'shell.navAria': 'Navigation principale',
|
||
'shell.navProjects': 'Projets',
|
||
'shell.navWorkbench': 'Atelier',
|
||
'shell.navImage': 'Génération d\'image',
|
||
'shell.navVideo': 'Génération vidéo',
|
||
'shell.navTasks': 'Tâches',
|
||
'shell.navAgents': 'Agents',
|
||
'shell.navConnections': 'Connexions ComfyUI',
|
||
'shell.navModels': 'Modèles',
|
||
'shell.navLibrary': 'Bibliothèque d’assets',
|
||
'shell.navSettings': 'Réglages',
|
||
'shell.comfy_ok': '{name} connecté',
|
||
'shell.comfy_fail': '{name} injoignable',
|
||
'shell.comfy_testing': 'Test de {name}…',
|
||
'shell.comfyUnset': 'ComfyUI · non configuré',
|
||
'shell.scopeHint': 'Changer de projet',
|
||
'shell.scopeAll': 'Tous les projets',
|
||
'shell.scopeAllList': 'Liste des projets',
|
||
'shell.scopeRecent': 'Projets récents',
|
||
'shell.scopeLoadFailed': 'Impossible de charger les projets',
|
||
'shell.scopeEmpty': 'Aucun projet — en créer un',
|
||
'shell.scopeStage': '{n}/5 validées',
|
||
'shell.queueRunning': '{n} en cours',
|
||
'shell.queueQueued': '{n} en file',
|
||
'shell.queueIdle': 'File libre',
|
||
'shell.queueActive': '{n} actifs',
|
||
'shell.trayTitle': 'Plateau des tâches',
|
||
'shell.trayRecent': 'Tâches récentes · cliquer pour tout voir',
|
||
'shell.trayEmpty': 'Aucune tâche de génération',
|
||
'shell.trayAll': 'Voir toutes les tâches',
|
||
'shell.searchTitle': 'Rechercher pages et projets',
|
||
'shell.searchPlaceholder': 'Rechercher pages, projets',
|
||
'shell.searchShortcut': 'Rechercher (Ctrl/⌘ + K)',
|
||
'shell.searchEmpty': 'Aucune page ni projet ne correspond à « {q} »',
|
||
'shell.searchGroupPages': 'Pages',
|
||
'shell.searchGroupProjects': 'Projets · ouvrir l’atelier',
|
||
'shell.searchHintMove': 'choisir',
|
||
'shell.searchHintOpen': 'ouvrir',
|
||
'shell.searchHintClose': 'fermer',
|
||
'shell.reduceMotion': 'Réduire les animations',
|
||
'shell.reduceHint': 'Coupe déplacements, zooms et halos ; garde seulement de courts fondus',
|
||
'shell.reduceSystem': 'Réglage système « Réduire les animations » appliqué',
|
||
'shell.tabAria': 'Navigation principale (étroite)',
|
||
'shell.tabProjects': 'Projets',
|
||
'shell.tabCreate': 'Créer',
|
||
'shell.tabGenerate': 'Générer',
|
||
'shell.tabMore': 'Plus',
|
||
'shell.morePages': 'Autres pages',
|
||
'shell.moreTools': 'Outils',
|
||
'home.title': 'Aperçu des projets',
|
||
'home.subtitle': 'Gérez vos projets — commencez avec une idée ou un scénario prêt.',
|
||
'home.projectCount': '{n} projets · {m} en cours',
|
||
'home.startIdea': 'Commencer avec une idée',
|
||
'home.importScript': 'Importer un scénario',
|
||
'home.entryIdeaTitle': 'Commencer avec une idée',
|
||
'home.entryIdeaBody': 'Décrivez une idée ; les agents la mènent étape par étape à travers l\'histoire, le storyboard et les plans.',
|
||
'home.entryScriptTitle': 'Importer un scénario',
|
||
'home.entryScriptBody': 'Vous avez déjà un scénario ? Collez-le, créez le projet et l\'agent scénario le découpe en scènes ordonnées.',
|
||
'home.ideaPlaceholder': 'Un petit port pluvieux où le gardien de phare découvre…',
|
||
'home.scriptField': 'Scénario complet',
|
||
'home.scriptPlaceholder': 'Collez ici le scénario complet…',
|
||
'home.scriptHint': 'Après création, la page Agents s\'ouvre et l\'agent scénario transforme le texte en scènes ordonnées.',
|
||
'home.errTitle': 'Donnez un titre au projet',
|
||
'home.errScript': 'Collez le scénario complet',
|
||
'home.myProjects': 'Mes projets',
|
||
'home.myProjectsHint': 'Cliquez sur un projet pour continuer',
|
||
'home.emptyProjects': 'Aucun projet pour le moment. Créez le premier avec « Commencer avec une idée » ou « Importer un scénario ».',
|
||
'home.noIdea': 'Pas encore de description',
|
||
'home.statScenes': '{n} scènes',
|
||
'home.statCharacters': '{n} personnages',
|
||
'home.statAssets': 'ressources {ready}/{total}',
|
||
'home.statusDraft': 'Brouillon',
|
||
'home.statusProgress': 'En cours',
|
||
'home.statusDone': 'Terminé',
|
||
'home.tasksTitle': 'Tâches',
|
||
'home.activeJobs': '{n} actives',
|
||
'home.emptyJobs': 'Aucune tâche de génération',
|
||
'home.emptyJobsSub': 'Les tâches lancées depuis un projet ou l\'atelier s\'afficheront ici.',
|
||
'home.tasksNote': 'L\'historique complet et les filtres se trouvent sur la page Tâches (navigation → 生成任务).',
|
||
'home.kindImage': 'image',
|
||
'home.kindVideo': 'vidéo',
|
||
'home.kindExport': 'film',
|
||
'home.jobDone': 'terminée',
|
||
'home.jobRunning': 'en cours',
|
||
'home.jobQueued': 'en attente',
|
||
'home.jobFailed': 'échouée',
|
||
'home.jobRequeued': 'Tâche remise en file',
|
||
'home.jobRetryFailed': 'Impossible de remettre la tâche en file',
|
||
'home.jobProject': 'Projet #{id}',
|
||
|
||
// --- ComfyUI connections page (a6, HEL-611) ---
|
||
'settings.comfyMultiHint': 'Les adresses ComfyUI prennent désormais en charge plusieurs connexions (local / LAN / cloud), associables par workflow.',
|
||
'settings.comfyGoto': 'Gérer dans « Connexions ComfyUI » →',
|
||
'conn.title': 'Connexions ComfyUI',
|
||
'conn.subtitle': 'Enregistrez des adresses API ComfyUI locales, LAN ou cloud · la connectivité est testée par le serveur',
|
||
'conn.statusCount': '{n} connexions · {m} réussies',
|
||
'conn.add': 'Ajouter une connexion',
|
||
'conn.loading': 'Chargement des connexions…',
|
||
'conn.loadFailed': 'Échec du chargement des connexions',
|
||
'conn.empty': 'Aucune connexion ComfyUI pour l\'instant — ajoutez la première adresse via « Ajouter une connexion ».',
|
||
'conn.targetsTitle': 'Cible des tâches',
|
||
'conn.targetImage': 'Image autonome',
|
||
'conn.targetVideo': 'Vidéo autonome',
|
||
'conn.targetFlow': 'Tâches du flux créatif',
|
||
'conn.targetChange': 'Modifier',
|
||
'conn.targetMixed': '{n} connexions',
|
||
'conn.targetNote': 'Les tâches suivent la liaison de chaque workflow ; sans liaison, la connexion par défaut est utilisée. Modifiez les liaisons dans la bibliothèque — les pages image / vidéo peuvent aussi changer avant génération.',
|
||
'conn.defaultBadge': 'Par défaut',
|
||
'conn.test': 'Tester la connexion',
|
||
'conn.testing': 'Test…',
|
||
'conn.edit': 'Modifier',
|
||
'conn.delete': 'Supprimer',
|
||
'conn.setDefault': 'Définir par défaut',
|
||
'conn.delDefaultHint': 'La connexion par défaut ne peut pas être supprimée ; choisissez-en une autre d\'abord',
|
||
'conn.delTitle': 'Supprimer la connexion',
|
||
'conn.delConfirmUsed': 'Les workflows liés à cette connexion reviendront à la connexion par défaut. Les instantanés existants sont conservés. Supprimer « {name} » ?',
|
||
'conn.delConfirmFree': 'Supprimer la connexion « {name} » ?',
|
||
'conn.statusUntested': 'Non testée',
|
||
'conn.statusConnected': 'Test réussi',
|
||
'conn.statusFailed': 'Échec du test',
|
||
'conn.latency': '{ms} ms de latence',
|
||
'conn.version': 'version {v}',
|
||
'conn.lastTestAt': 'dernier test {time}',
|
||
'conn.boundWorkflows': '{n} workflows liés',
|
||
'conn.tokenSaved': 'Jeton enregistré — laissez vide pour le conserver',
|
||
'conn.saved': 'Connexion enregistrée',
|
||
'conn.deleted': 'Connexion supprimée',
|
||
'conn.saveFailed': 'Échec de l\'enregistrement : {detail}',
|
||
'conn.defaultSetToast': 'Définie comme connexion par défaut',
|
||
'conn.formTitleAdd': 'Ajouter une connexion ComfyUI',
|
||
'conn.formTitleEdit': 'Modifier la connexion ComfyUI',
|
||
'conn.formClose': 'Fermer',
|
||
'conn.fName': 'Nom',
|
||
'conn.fNamePh': 'ex. ComfyUI local / machine de rendu',
|
||
'conn.fBaseUrl': 'Adresse API',
|
||
'conn.fBaseUrlPh': 'http://192.168.200.18:8188',
|
||
'conn.baseUrlHelp': 'Adresse HTTP de l\'API ComfyUI (port 8188 par défaut) ; même format pour local, LAN et cloud.',
|
||
'conn.fAuth': 'Authentification',
|
||
'conn.authNone': 'Aucune',
|
||
'conn.authBearer': 'Jeton Bearer',
|
||
'conn.authHeader': 'En-tête personnalisé',
|
||
'conn.authHelp': 'Nécessaire seulement si le point de terminaison est derrière une auth (clé de reverse proxy, etc.).',
|
||
'conn.fToken': 'Jeton d\'accès',
|
||
'conn.fHeaderName': 'Nom d\'en-tête',
|
||
'conn.fHeaderNamePh': 'X-Api-Key',
|
||
'conn.keyNoEcho': 'stocké côté serveur uniquement, jamais renvoyé',
|
||
'conn.keyHelp': 'Le jeton reste dans le fichier de configuration du serveur et n\'atteint jamais le navigateur.',
|
||
'conn.fNotes': 'Notes',
|
||
'conn.fNotesPh': 'facultatif : ce que fait la machine, VRAM…',
|
||
'conn.errName': 'Le nom est requis',
|
||
'conn.errUrl': 'L\'adresse doit être une URL http:// ou https:// valide',
|
||
'conn.errHeaderName': 'L\'en-tête personnalisé exige un nom',
|
||
'conn.testOk': '✓ Test réussi · {ms} ms · ComfyUI {v}',
|
||
'conn.testFail': '✕ {reason}',
|
||
'conn.needTest': 'Réussissez le test avant d\'enregistrer',
|
||
'conn.testBtn': 'Tester',
|
||
'conn.save': 'Enregistrer',
|
||
'conn.noticeStrong': 'C\'est le serveur qui décide de la connectivité : ',
|
||
'conn.noticeBody': 'Une adresse qui s\'ouvre dans le navigateur ne garantit pas que la génération fonctionne ; tests et requêtes sont faits par le serveur. Les jetons restent côté serveur.',
|
||
'conn.wfTitle': 'Bibliothèque de workflows',
|
||
'conn.wfHint': 'Importez le JSON au format API ComfyUI, classez-le image/vidéo, liez-le à une connexion',
|
||
'conn.wfEmpty': 'Aucun workflow importé. Activez le mode développeur dans ComfyUI, exportez en « format API » puis collez-le ici.',
|
||
'conn.wfCount': '{n} workflows · {m} image · {k} vidéo',
|
||
'conn.wfKindImage': 'Image',
|
||
'conn.wfKindVideo': 'Vidéo',
|
||
'conn.wfConnection': 'Connexion liée',
|
||
'conn.wfConnectionActive': 'Suit la connexion par défaut',
|
||
'conn.wfParams': '{n} paramètres remplissables',
|
||
'conn.wfImport': 'Importer le workflow',
|
||
'conn.wfImporting': 'Import…',
|
||
'conn.wfNodes': '{n} nœuds',
|
||
'conn.wfImportedN': 'Workflow importé : {n} paramètres détectés',
|
||
'conn.wfImportedNoParams': 'Workflow importé, mais aucun paramètre détecté : il sera exécuté avec ses réglages intégrés',
|
||
'conn.wfImportFailed': 'Échec de l\'import : {detail}',
|
||
'conn.wfImportTitle': 'Importer un workflow ComfyUI (JSON format API)',
|
||
'conn.wfImportHint': 'Collez ou choisissez un fichier ; le nom est requis, le type décide de la fenêtre image ou vidéo.',
|
||
'conn.wfJsonInvalid': 'JSON invalide au format API (attendu : objet id de nœud → {{…class_type…}})',
|
||
'conn.wfJsonPh': 'Collez ici le JSON format API ComfyUI ou choisissez un fichier',
|
||
'conn.wfDeleted': 'Workflow supprimé',
|
||
'conn.wfImportedBroken': 'Imported, but the workflow file is incomplete and must be re-exported before generating: {detail}',
|
||
'conn.wfBrokenBadge': 'Incomplete file — cannot generate',
|
||
// --- Five usages & import confirmation (HEL-636) ---
|
||
'usage.text2image': 'Text → Image',
|
||
'usage.image2image': 'Image → Image',
|
||
'usage.text2video': 'Text → Video',
|
||
'usage.image2video': 'Image → Video',
|
||
'usage.ref2video': 'Reference → Video',
|
||
'usage.pending': 'Usage pending',
|
||
'wfRole.image': 'Input image',
|
||
'wfRole.first_frame': 'First frame',
|
||
'wfRole.last_frame': 'Last frame',
|
||
'wfRole.reference_image': 'Reference',
|
||
'wfRole.mask': 'Mask',
|
||
'conn.wfImportAction': 'Import workflow',
|
||
'conn.wfConfirmTitle': 'Confirm detection',
|
||
'conn.wfStepAnalyze': 'Paste & analyze',
|
||
'conn.wfStepConfirm': 'Confirm & save',
|
||
'conn.wfChooseFile': 'Choose file',
|
||
'conn.wfAnalyze': 'Analyze',
|
||
'conn.wfAnalyzing': 'Analyzing…',
|
||
'conn.wfConfirmHint': 'Review the evidence, output nodes and image slots; correct the usage or slot roles before saving.',
|
||
'conn.wfUsageLabel': 'Usage',
|
||
'conn.wfUsageAuto': 'Auto-detected: {usage}',
|
||
'conn.wfUsageNeedPick': 'Pick manually',
|
||
'conn.wfPickUsage': 'Choose a usage first',
|
||
'conn.wfSlotsLabel': 'Image slots',
|
||
'conn.wfSlotsHint': 'Roles are inferred from wiring; override them (input image / first / last frame / reference / mask) and the manual choice sticks.',
|
||
'conn.wfBack': 'Back',
|
||
'conn.wfConfirmSave': 'Confirm & save',
|
||
'conn.wfImportedWithUsage': 'Saved as “{usage}” with {n} fillable parameters',
|
||
'conn.wfPendingCount': '{n} pending',
|
||
'conn.wfConfirmed': 'Usage confirmed: {usage} — the workflow can generate now',
|
||
'conn.wfSourceUser': 'Usage set manually; re-analysis will not overwrite it',
|
||
'conn.wfSourceAuto': 'Usage auto-detected',
|
||
'conn.wfDisabledBadge': 'Disabled',
|
||
'conn.wfConfirmAria': 'Confirm workflow usage',
|
||
'conn.wfOutputLabel': 'Nœuds de sortie',
|
||
'conn.wfOutputNeedPick': 'Nœuds de sortie personnalisés non reconnus — à désigner',
|
||
'conn.wfOutputHint': 'Cochez les nœuds qui produisent réellement les résultats et choisissez leur type de média ; la génération ne collecte les images/vidéos que sur ces nœuds.',
|
||
'conn.wfOutputPick': 'Cochez au moins un nœud de sortie',
|
||
'conn.wfOutputKindAria': 'Type de média du nœud de sortie',
|
||
'conn.wfOutputPendingBadge': 'Sortie à définir',
|
||
'conn.wfOutputNeedMap': 'Ce workflow contient des nœuds de sortie non reconnus ; désignez-les avec leur type de média pour l’activer',
|
||
'conn.wfOutputApply': 'Enregistrer le mapping de sortie',
|
||
'conn.wfMapCancel': 'Annuler',
|
||
'conn.wfOutputApplied': 'Mapping de sortie enregistré : nœud {nodes}',
|
||
'conn.wfOutputCleared': 'Mapping de sortie effacé — le workflow est de nouveau en attente',
|
||
'conn.missingMaterial': 'Un JSON de workflow Qwen Image 2.1 dédié manque encore au dépôt : exportez-le depuis ComfyUI et importez-le ici — le chemin d\'import générique est prêt.',
|
||
|
||
// --- Génération indépendante image / vidéo (a3/a4, HEL-612) ---
|
||
'studio.image.title': 'Image',
|
||
'studio.image.subtitle': 'Générez des images avec les workflows importés · connexions et file partagées avec Connexions ComfyUI',
|
||
'studio.video.title': 'Vidéo',
|
||
'studio.video.subtitle': 'Générez des vidéos avec les workflows importés · connexions et file partagées avec Connexions ComfyUI',
|
||
'studio.genParams': 'Paramètres',
|
||
'studio.modeTextToImage': 'Texte vers image',
|
||
'studio.modeTextToVideo': 'Texte vers vidéo',
|
||
'studio.video.resultsTitle': 'Aperçu',
|
||
'studio.image.historyTitle': 'Historique images',
|
||
'studio.video.historyTitle': 'Historique vidéos',
|
||
'studio.historyCount': '{n} au total',
|
||
'studio.doneAt': 'Terminé à {time}',
|
||
'studio.kindImageText': 'image',
|
||
'studio.kindVideoText': 'vidéo',
|
||
'studio.loading': 'Chargement…',
|
||
'studio.connLabel': 'Connexion',
|
||
'studio.connQueue': 'File {n}',
|
||
'studio.connUntested': 'Vérification…',
|
||
'studio.connOk': 'Connecté · {ms} ms',
|
||
'studio.connFail': 'Injoignable',
|
||
'studio.connManage': 'Gérer les connexions',
|
||
'studio.wfLabel': 'Workflow',
|
||
'studio.wfParams': '{n} paramètres remplissables',
|
||
'studio.wfBindTo': 'Lié à {name}',
|
||
'studio.wfFollowActive': 'Suit la connexion par défaut',
|
||
'studio.promptLabel': 'Prompt positif',
|
||
'studio.promptPh': 'Décrivez l’image : sujet, décor, lumière, style…',
|
||
'studio.negLabel': 'Prompt négatif',
|
||
'studio.seedLabel': 'Graine',
|
||
'studio.sizeLabel': 'Dimensions',
|
||
'studio.batchLabel': 'Lot',
|
||
'studio.durationLabel': 'Durée (s)',
|
||
'studio.fpsLabel': 'Images/s',
|
||
'studio.stepsLabel': 'Étapes',
|
||
'studio.cfgLabel': 'CFG',
|
||
'studio.paramsTitle': 'Paramètres du workflow',
|
||
'studio.chars': '{n} car.',
|
||
'studio.insertStyle': 'Insérer des mots de style',
|
||
'studio.styleSoon': 'La bibliothèque de Skills arrivera avec la fonction Agents',
|
||
'studio.generateN': 'Générer · {n} images',
|
||
'studio.generate': 'Générer',
|
||
'studio.submitting': 'Envoi…',
|
||
'studio.etaHint': 'Le temps réel dépend de la connexion et du workflow',
|
||
'studio.errNoConn': 'Sélectionnez d’abord une connexion de génération',
|
||
'studio.errConnDown': 'Cette connexion est indisponible (dernier test échoué à {time}) ; changez de connexion ou corrigez-la dans Connexions ComfyUI',
|
||
'studio.errPrompt': 'Remplissez le prompt',
|
||
'studio.errPromptLong': 'Le prompt dépasse 2000 caractères ; raccourcissez-le',
|
||
'studio.errRefImage': 'Image-vers-image nécessite une image de référence',
|
||
'studio.errFirstLast': 'La vidéo premier/dernier cadre exige les deux cadres',
|
||
'studio.errUpload': 'Téléversez {label}',
|
||
'studio.errFill': 'Remplissez {label}',
|
||
'studio.slotRef': 'Image de référence',
|
||
'studio.slotRefN': 'Référence {n}',
|
||
'studio.slotMask': 'Masque',
|
||
'studio.slotFirst': 'Premier cadre',
|
||
'studio.slotLast': 'Dernier cadre',
|
||
'studio.slotOptional': 'Facultatif',
|
||
'studio.slotRefVideo': 'Vidéo de référence',
|
||
'studio.slotAudio': 'Audio de référence',
|
||
'studio.slotPick': 'Cliquez ou déposez',
|
||
'studio.slotFromResults': 'Choisir parmi les résultats d’image',
|
||
'studio.taskCurrent': 'Tâche en cours',
|
||
'studio.taskQueued': 'En file',
|
||
'studio.taskRunning': 'Génération',
|
||
'studio.taskCancel': 'Annuler la tâche',
|
||
'studio.queuedBehind': '{n} tâche(s) devant',
|
||
'studio.stepsShort': 'Étapes {v}',
|
||
'studio.usedShort': 'Écoulé {v}',
|
||
'studio.etaShort': 'Restant {v}',
|
||
'studio.targetShort': 'Cible {name}',
|
||
'studio.renderFrames': 'Frame {done}/{total}',
|
||
'studio.noActiveTask': 'Aucune tâche active · réglez les paramètres puis lancez Générer',
|
||
'studio.resultsTitle': 'Résultats récents',
|
||
'studio.selectHint': 'Choisie',
|
||
'studio.sendToImg2Img': 'Envoyer vers img2img',
|
||
'studio.zoom': 'Agrandir',
|
||
'studio.download': 'Télécharger',
|
||
'studio.downloadMp4': 'Télécharger MP4',
|
||
'studio.copyPrompt': 'Copier le prompt',
|
||
'studio.copiedToast': 'Copié ; collez-le dans la génération image/vidéo',
|
||
'studio.sentToImg2ImgToast': 'Ajouté comme référence ; vérifiez les paramètres et lancez',
|
||
'studio.noImg2ImgWf': 'Aucun workflow image ne déclare d’entrée de référence ; importez d’abord un workflow img2img dans Connexions ComfyUI',
|
||
'studio.videoRefStrip': 'Référence premier / dernier cadre',
|
||
'studio.historyEmptyImage': 'Aucune génération d’image ; réglez les paramètres puis lancez Générer',
|
||
'studio.historyEmptyVideo': 'Aucune génération de vidéo ; réglez les paramètres puis lancez Générer',
|
||
'studio.jobName': 'Tâche #{id}',
|
||
'studio.retryLink': 'Réessayer',
|
||
'studio.retryQueuedToast': 'Tâche remise en file',
|
||
'studio.retryFailedToast': 'Échec de la remise en file : {detail}',
|
||
'studio.errNoWorkflow': 'Choisissez d\'abord un workflow',
|
||
'studio.errBlocked': 'Envoi impossible : {reason}',
|
||
'studio.queuedToast': 'Envoyé à « {name} », en file',
|
||
'studio.submitFailedToast': 'Échec de l\'envoi : {detail}',
|
||
'studio.jobFailedToast': 'Échec de la génération : {detail}',
|
||
'studio.wfNoParamsNote': 'Ce workflow n\'a aucun paramètre à remplir et sera exécuté avec son prompt et ses réglages intégrés. Pour les remplir ici, ajoutez (Input:prompt) etc. aux titres de nœuds dans ComfyUI puis réimportez.',
|
||
'studio.wfAutoParamsNote': 'Aucune balise (Input:…) : {n} paramètres détectés par type de nœud ; les champs vides gardent les valeurs du workflow.',
|
||
'studio.promptNotDeclared': 'Ce workflow n\'a pas de nœud de prompt',
|
||
'studio.modeImageEdit': 'Image edit',
|
||
'studio.modeImageToVideo': 'Image to video',
|
||
'studio.modeRefToVideo': 'Reference to video',
|
||
'studio.slotInput': 'Input image',
|
||
'studio.slotHintOne': 'Required · 1 image',
|
||
'studio.slotEmptyInput': 'Click or drop the input image',
|
||
'studio.slotEmptyFirst': 'Click or drop the first frame',
|
||
'studio.slotEmptySub': 'PNG / JPG / WebP · ≤ 20MB each',
|
||
'studio.slotFromResultsShort': 'From results',
|
||
'studio.errImageFormat': '"{name}" is not supported — use PNG / JPG / WebP; this file will not be used',
|
||
'studio.errImageSize': '"{name}" is larger than 20MB — compress it and upload again',
|
||
'studio.errNeedInputImage': 'Image edit needs an input image',
|
||
'studio.errNeedFirstFrame': 'Image to video needs a first frame',
|
||
'studio.errNeedRef': 'Reference to video needs at least 1 reference image',
|
||
'studio.errRefMax': 'At most {max} reference images: {n} selected, these {k} were not added',
|
||
'studio.refHint': 'Required · 1–{max} · {n} selected',
|
||
'studio.refAdd': 'Add reference image',
|
||
'studio.refAddSub': '{n} more · max {max}',
|
||
'studio.refReplace': 'Replace',
|
||
'studio.refRemove': 'Remove reference {n}',
|
||
'studio.refRejectedShort': 'Not added',
|
||
'studio.refFull': 'Limit of {max} reached — remove one to add another',
|
||
'studio.refStrip': 'Reference images ({n} used)',
|
||
'studio.resolutionLabel': 'Output resolution',
|
||
'studio.resolutionHint': 'About {v}×{v} px, keeps the input aspect; 0 = original size',
|
||
'studio.wfBrokenTitle': 'This workflow file is incomplete — ComfyUI cannot run it, generation is blocked',
|
||
'studio.wfBrokenHint': 'Re-export the API-format JSON from a ComfyUI that has the custom nodes installed, then import it again under ComfyUI connections.',
|
||
'studio.errWfBroken': 'Workflow file is incomplete — re-export it before generating',
|
||
'studio.cancelToast': 'Annulation demandée',
|
||
'studio.deleteBtn': 'Supprimer',
|
||
'studio.delTitle': 'Supprimer la tâche',
|
||
'studio.delConfirm': 'La suppression retire aussi les fichiers de résultats de cette tâche ; l’historique est irrécupérable. Supprimer ?',
|
||
'studio.delTitleJob': 'Supprimer la tâche « {name} »',
|
||
'studio.delConfirmMulti': 'Cette tâche a produit {n} résultats. La suppression retire la tâche entière et ses {n} fichiers de résultats ; action irréversible. Supprimer ?',
|
||
'studio.deleteFailedToast': 'Échec de la suppression : {detail}',
|
||
'studio.deletedTakeNoFilesToast': '« {name} » supprimé',
|
||
'studio.deletedTakeToast': '« {name} » et ses fichiers de résultat ont été supprimés',
|
||
'studio.deletedToast': 'Tâche supprimée avec ses fichiers de résultats',
|
||
'studio.wfDeletedTag': 'Workflow supprimé',
|
||
'studio.wfEmptyTitle': 'Pas encore de workflows {kind}',
|
||
'studio.wfEmptyBody': 'Activez le mode développeur de ComfyUI, exportez le workflow en JSON API, puis importez-le dans Connexions ComfyUI comme {kind}.',
|
||
'studio.wfEmptyGo': 'Importer dans Connexions ComfyUI',
|
||
'studio.missingQwen': 'Les JSON dédiés Qwen Image 2.1 (t2i / img2img / masque) manquent encore ; la voie d’import générique est prête — exportez-les depuis ComfyUI.',
|
||
'studio.missingFirstLast': 'Le JSON dédié MiniMax H3 premier/dernier cadre manque encore ; les exemples t2v / r2v fournis peuvent être importés en attendant.',
|
||
'studio.pickerTitle': 'Choisir un résultat d’image',
|
||
'studio.pickerEmpty': 'Aucun résultat d’image disponible',
|
||
'studio.pickerPick': 'Utiliser',
|
||
'studio.uploadFailedToast': 'Échec du téléversement : {detail}',
|
||
'studio.playAria': 'Lecture',
|
||
'studio.pauseAria': 'Pause',
|
||
'studio.fullscreenAria': 'Plein écran',
|
||
|
||
// --- Page des tâches de génération (HEL-612) ---
|
||
'tasks.title': 'Tâches de génération',
|
||
'tasks.subtitle': 'Toutes les tâches image / vidéo : fenêtres indépendantes et flux de création',
|
||
'tasks.filterAll': 'Toutes',
|
||
'tasks.filterImage': 'Images',
|
||
'tasks.filterFailed': 'Échecs',
|
||
'tasks.filterActive': 'En cours',
|
||
'tasks.filterVideo': 'Vidéos',
|
||
'tasks.count': '{n} tâches · {m} actives',
|
||
'tasks.empty': 'Aucune tâche. Lancez la première dans Image ou Vidéo.',
|
||
'tasks.emptyFiltered': 'Aucune tâche ne correspond au filtre actuel.',
|
||
'tasks.goGenerate': 'Ouvrir Image',
|
||
'tasks.sourceStudioImage': 'Image indépendante',
|
||
'tasks.sourceStudioVideo': 'Vidéo indépendante',
|
||
'tasks.sourcePlayground': 'Playground',
|
||
'tasks.sourceFlow': 'Flux de création',
|
||
'tasks.sourceOther': 'Génération',
|
||
'tasks.queued': 'En file',
|
||
'tasks.running': 'En cours',
|
||
'tasks.done': 'Terminé',
|
||
'tasks.failed': 'Échec',
|
||
'tasks.retry': 'Réessayer',
|
||
'tasks.cancel': 'Annuler',
|
||
'tasks.delete': 'Supprimer',
|
||
'tasks.download': 'Télécharger',
|
||
'tasks.delTitle': 'Supprimer la tâche',
|
||
'tasks.delConfirm': 'Les fichiers de résultats seront supprimés avec la tâche. Supprimer ?',
|
||
'tasks.searchPh': 'Rechercher des tâches…',
|
||
'tasks.outputs': '{n} résultats',
|
||
|
||
'agentsPage.title': 'Agents',
|
||
'agentsPage.subtitle': 'Discutez séparément avec les cinq agents de création ; définissez et attribuez des Skills',
|
||
'agentsPage.statusChip': '{n} Skills · {m} activés',
|
||
'agentsPage.agentsTitle': 'Cinq agents',
|
||
'agentsPage.skillLib': 'Bibliothèque de Skills',
|
||
'agentsPage.skillLibCount': '{n}',
|
||
'agentsPage.installedTitle': '{name} · Skills installés',
|
||
'agentsPage.installedCount': '{n} · {m} actifs',
|
||
'agentsPage.newSkill': 'Nouveau Skill',
|
||
'agentsPage.skillLibEmpty': 'Aucun Skill pour l’instant — créez-en un avec « Nouveau Skill ».',
|
||
'agentsPage.skillsCount': '{n} Skills',
|
||
'agentsPage.replying': 'Réponse…',
|
||
'agentsPage.idle': 'Inactif',
|
||
'agentsPage.assigned': 'attribué {n}',
|
||
'agentsPage.edit': 'Modifier',
|
||
'agentsPage.toggleSkill': 'Activer ou désactiver le Skill',
|
||
'agentsPage.independentNote': 'Chat indépendant · hors du flux de création',
|
||
'agentsPage.model': 'Modèle',
|
||
'agentsPage.modelDefault': 'Défaut de l’agent',
|
||
'agentsPage.newSessionLabel': 'Nouvelle discussion',
|
||
'agentsPage.newSession': 'Nouvelle discussion',
|
||
'agentsPage.clear': 'Vider',
|
||
'agentsPage.export': 'Exporter',
|
||
'agentsPage.skillManage': 'Gestion des Skills',
|
||
'agentsPage.composerPlaceholder': 'Continuez la discussion ou collez un fragment de scénario… (Entrée pour envoyer, Maj+Entrée pour un saut de ligne)',
|
||
'agentsPage.send': 'Envoyer',
|
||
'agentsPage.clearTitle': 'Vider la discussion',
|
||
'agentsPage.clearConfirm': 'L’historique sera perdu définitivement. Vider la discussion avec l’agent {name} ?',
|
||
'agentsPage.skillErrName': 'Donnez un nom au Skill',
|
||
'agentsPage.skillErrAssign': 'Attribuez-le à au moins un Agent, sinon il ne prendra jamais effet',
|
||
'agentsPage.skillLoadFailed': 'Échec de lecture du contenu du Skill',
|
||
'agentsPage.skillSaved': 'Skill enregistré',
|
||
'agentsPage.skillSaveFailed': 'Échec de l’enregistrement : {detail}',
|
||
'agentsPage.skillEnabled': 'Skill activé',
|
||
'agentsPage.skillDisabled': 'Skill désactivé — les nouvelles réponses ne l’utiliseront plus',
|
||
'agentsPage.skillDeleted': 'Skill supprimé',
|
||
'agentsPage.skillRestored': 'Version précédente restaurée',
|
||
'agentsPage.skillTypeTemplate': 'Modèle de prompt',
|
||
'agentsPage.skillTypeKnowledge': 'Connaissance de référence',
|
||
'agentsPage.skillTypeRules': 'Règles de processus',
|
||
'agentsPage.versions': 'Historique des versions',
|
||
'agentsPage.versionsEmpty': 'Aucune version — chaque enregistrement archive la précédente.',
|
||
'agentsPage.restore': 'Restaurer',
|
||
'agentsPage.close': 'Fermer',
|
||
'agentsPage.editSkill': 'Modifier le Skill',
|
||
'agentsPage.skillName': 'Nom',
|
||
'agentsPage.skillNamePh': 'ex. cyberpunk-style-kit',
|
||
'agentsPage.skillType': 'Type',
|
||
'agentsPage.skillDesc': 'Description',
|
||
'agentsPage.skillDescPh': 'Quand l’agent doit l’utiliser (affiché dans sa liste de Skills)',
|
||
'agentsPage.skillContent': 'Contenu',
|
||
'agentsPage.skillContentPh': 'Markdown pris en charge : modèles, références ou règles…',
|
||
'agentsPage.skillContentHint': 'Markdown pris en charge ; l’enregistrement incrémente la version et archive l’ancienne.',
|
||
'agentsPage.assignTo': 'Attribuer à',
|
||
'agentsPage.saveNext': 'Enregistrer v{v}+1',
|
||
'agentsPage.save': 'Enregistrer',
|
||
'agentsPage.disable': 'Désactiver',
|
||
'agentsPage.enable': 'Activer',
|
||
'agentsPage.delete': 'Supprimer',
|
||
'agentsPage.delSkillTitle': 'Supprimer le Skill',
|
||
'agentsPage.delSkillConfirm': 'Irréversible ; les {n} agents assignés le perdront aussi. Supprimer ?',
|
||
'agentsPage.skillIdleHint': 'Choisissez « Modifier » dans la bibliothèque ou cliquez « Nouveau Skill »',
|
||
'agentsPage.sugScript1': 'Transformer une idée en plan trois actes',
|
||
'agentsPage.sugScript1P': 'Idée : un vendeur de supérette remarque le même client à la même minute chaque nuit. Écrivez un plan en trois actes.',
|
||
'agentsPage.sugScript2': 'Peaufiner un scénario existant',
|
||
'agentsPage.sugScript2P': 'Je collerai un scénario ; lisez-le puis proposez trois améliorations de dialogue et de rythme.',
|
||
'agentsPage.sugStyle1': 'Proposer des directions visuelles',
|
||
'agentsPage.sugStyle1P': 'Court-métrage romantique urbain sous la pluie néon : trois directions visuelles distinctes avec mots-clés anglais.',
|
||
'agentsPage.sugStyle2': 'Mots-clés cinéma réaliste',
|
||
'agentsPage.sugStyle2P': 'Compilez des prompts de style cinéma réaliste (positif + négatif), anglais annoté en chinois.',
|
||
'agentsPage.sugBoard1': 'Découper le scénario en storyboard',
|
||
'agentsPage.sugBoard1P': 'Découpez ce scénario plan par plan : numéro, échelle, mouvement, contenu, réplique, durée.',
|
||
'agentsPage.sugBoard2': 'Storyboard du climax',
|
||
'agentsPage.sugBoard2P': 'Climax de poursuite de 30 secondes : une version au rythme marqué.',
|
||
'agentsPage.sugAssets1': 'Prompts de fiche personnage',
|
||
'agentsPage.sugAssets1P': 'L’héroïne est une détective de 17 ans : des prompts cohérents (face / profil / plein pied).',
|
||
'agentsPage.sugAssets2': 'Liste d’assets',
|
||
'agentsPage.sugAssets2P': 'À partir de la supérette sous la pluie, listez des prompts de décors et accessoires.',
|
||
'agentsPage.sugShot1': 'Un prompt vidéo',
|
||
'agentsPage.sugShot1P': 'Travelling avant de l’enseigne néon vers la porte vitrée : un prompt vidéo prêt à l’emploi.',
|
||
'agentsPage.sugShot2': 'Plans premier/dernier cadre',
|
||
'agentsPage.sugShot2P': 'Montrez comment écrire un prompt premier/dernier cadre : description, mouvement et durée.',
|
||
|
||
|
||
|
||
'workbench.title': 'Atelier de création',
|
||
'workbench.subtitle': 'Scénario → style → storyboard → assets → plan de tournage, cinq agents en relais',
|
||
'workbench.pickerSubtitle': 'Choisissez un projet pour reprendre son flux en cinq étapes',
|
||
'workbench.pickerEmpty': 'Aucun projet pour l\'instant',
|
||
'workbench.pickerEmptyBody': 'Retournez à la vue d\'ensemble : partez d\'une idée ou importez un scénario.',
|
||
'workbench.pickerGoHome': 'Vue d\'ensemble',
|
||
'workbench.pickerFootHint': 'Vous pouvez aussi entrer dans l\'atelier depuis la vue d\'ensemble (idée / import de scénario).',
|
||
'workbench.stageProgress': 'Progression en cinq étapes',
|
||
'workbench.activeJobs': '{n} tâches en cours',
|
||
'workbench.stage.script': 'Scénario',
|
||
'workbench.stage.style': 'Style visuel',
|
||
'workbench.stage.storyboard': 'Storyboard',
|
||
'workbench.stage.assets': 'Assets',
|
||
'workbench.stage.shot': 'Plan de tournage',
|
||
'workbench.lockedStep': 'Se déverrouille après confirmation de « {stage} »',
|
||
'workbench.state.todo': 'Non commencé',
|
||
'workbench.state.running': 'Génération',
|
||
'workbench.state.draft': 'À confirmer',
|
||
'workbench.state.confirmed': 'Confirmé',
|
||
'workbench.state.edited': 'Modifié',
|
||
'workbench.copied': 'Copié — à coller dans la génération image/vidéo',
|
||
'workbench.copyFailed': 'Échec de la copie, copiez manuellement',
|
||
'workbench.copy': 'Copier',
|
||
'workbench.charCount': '{n} caractères',
|
||
'workbench.runStage': 'Générer avec {agent}',
|
||
'workbench.runDone': '{agent} a terminé le brouillon — à valider',
|
||
'workbench.runFailed': 'Échec de génération, réessayez',
|
||
'workbench.runningHint': '{agent} rédige cette étape…',
|
||
'workbench.confirmNext': 'Confirmer et continuer',
|
||
'workbench.confirmLast': 'Confirmer l\'étape',
|
||
'workbench.confirmed': 'Étape « {agent} » confirmée',
|
||
'workbench.confirmFailed': 'Échec de confirmation, réessayez',
|
||
'workbench.restore': 'Restaurer la version confirmée',
|
||
'workbench.restored': 'Version confirmée restaurée',
|
||
'workbench.restoreFailed': 'Échec de restauration, réessayez',
|
||
'workbench.draftNotice': 'Brouillon non confirmé : l\'agent suivant ne le verra qu\'après confirmation.',
|
||
'workbench.draftSaved': 'Brouillon enregistré — confirmation requise',
|
||
'workbench.saveFailed': 'Échec de l\'enregistrement, réessayez',
|
||
'workbench.saveDraft': 'Enregistrer le brouillon',
|
||
'workbench.cancelEdit': 'Annuler',
|
||
'workbench.editDraft': 'Modifier',
|
||
'workbench.regenerate': 'Régénérer',
|
||
'workbench.regenerateHint': 'Regénérer cette étape (la version confirmée est conservée et restaurable)',
|
||
'workbench.instructionPh': 'Consignes supplémentaires (facultatif) : plus cinématographique, dialogues plus naturels…',
|
||
'workbench.jobSubmitted': 'Tâche de génération envoyée — les résultats reviennent au projet',
|
||
'workbench.jobSubmitFailed': 'Échec de l\'envoi de la tâche',
|
||
'workbench.jobRequeued': 'Tâche remise en file',
|
||
'workbench.retryJob': 'Réessayer',
|
||
'workbench.cancelJob': 'Annuler la tâche',
|
||
'workbench.openOutput': 'Voir le résultat',
|
||
'workbench.jobRunningPct': '{n} %',
|
||
'workbench.jobRunning': 'En cours',
|
||
'workbench.jobQueued': 'En file',
|
||
'workbench.jobDone': 'Terminé',
|
||
'workbench.jobFailed': 'Échec',
|
||
'workbench.generating': 'Génération…',
|
||
'workbench.progressChip': 'Étape {n}/5',
|
||
'workbench.backHome': 'Vue d\'ensemble',
|
||
'workbench.loadFailed': 'Échec du chargement de l\'atelier.',
|
||
'workbench.retryLoad': 'Réessayer',
|
||
'workbench.agentSkills': '{n} skills',
|
||
'workbench.chatWithAgent': 'Discuter en solo',
|
||
'workbench.tasksTitle': 'Tâches de l\'étape',
|
||
'workbench.tasksAll': 'Toutes les tâches',
|
||
'workbench.tasksEmpty': 'Aucune tâche. Envoyez des prompts depuis l\'étape assets ou plans.',
|
||
'workbench.flowTitle': 'Progression en cinq étapes',
|
||
'workbench.script.todoTitle': 'Commencez par le scénario : confiez votre idée à l\'agent Scénario',
|
||
'workbench.script.todoIdea': 'Votre idée :',
|
||
'workbench.script.generate': 'Rédiger le brouillon',
|
||
'workbench.script.importBtn': 'Importer un scénario',
|
||
'workbench.script.writeManually': 'Écrire manuellement',
|
||
'workbench.script.importPlaceholder': 'Collez ici un scénario existant… L\'import saute la rédaction et reprend au style visuel.',
|
||
'workbench.script.importHint': 'Le scénario importé devient la base confirmée de cette étape.',
|
||
'workbench.script.importConfirm': 'Importer et passer',
|
||
'workbench.script.importDone': 'Scénario importé — continuez au style visuel',
|
||
'workbench.script.importFailed': 'Échec de l\'import, vérifiez le texte et réessayez',
|
||
'workbench.script.editorHint': 'Modifiez le texte directement ; la confirmation reste nécessaire.',
|
||
'workbench.script.copyLabel': 'Scénario complet',
|
||
'workbench.style.todoTitle': 'Définir le style visuel du scénario',
|
||
'workbench.style.todoBody': 'L\'agent Style propose plusieurs directions, chacune avec des prompts image prêts à copier.',
|
||
'workbench.style.generate': 'Proposer des directions',
|
||
'workbench.style.namePh': 'Nom de la direction, ex. Néon Cyber',
|
||
'workbench.style.descPh': 'Description (palette / lumière / matière)',
|
||
'workbench.style.promptPh': 'Mots-clés image en anglais, séparés par des virgules',
|
||
'workbench.style.negativePh': 'Prompt négatif (facultatif, anglais)',
|
||
'workbench.style.negativeLabel': 'Prompt négatif',
|
||
'workbench.style.remove': 'Supprimer la direction',
|
||
'workbench.style.add': 'Ajouter une direction',
|
||
'workbench.style.chosen': 'Sélectionné',
|
||
'workbench.style.chooseHint': 'En confirmant, le style choisi est transmis aux étapes suivantes.',
|
||
'workbench.style.promptLabel': 'Prompt de style',
|
||
'workbench.board.scene': 'Scène',
|
||
'workbench.board.size': 'Échelle',
|
||
'workbench.board.camera': 'Caméra',
|
||
'workbench.board.duration': 'Sec',
|
||
'workbench.board.desc': 'Description',
|
||
'workbench.board.dialog': 'Dialogue/SFX',
|
||
'workbench.board.descPh': 'Ce que montre ce plan',
|
||
'workbench.board.dialogPh': 'Dialogue ou effet sonore (facultatif)',
|
||
'workbench.board.remove': 'Supprimer le plan',
|
||
'workbench.board.add': 'Ajouter un plan',
|
||
'workbench.board.todoTitle': 'Découper le scénario plan par plan',
|
||
'workbench.board.todoBody': 'L\'agent Storyboard produit numéros, échelles, mouvements et durées.',
|
||
'workbench.board.generate': 'Rédiger le storyboard',
|
||
'workbench.board.summary': '{n} plans · ~{sec} s',
|
||
'workbench.asset.kindCharacter': 'Personnage',
|
||
'workbench.asset.kindLocation': 'Lieu',
|
||
'workbench.asset.kindProp': 'Accessoire',
|
||
'workbench.asset.namePh': 'Nom de l\'asset',
|
||
'workbench.asset.descPh': 'Description (apparence, usage)',
|
||
'workbench.asset.promptPh': 'Prompt image complet en anglais',
|
||
'workbench.asset.promptLabel': 'Prompt image',
|
||
'workbench.asset.remove': 'Supprimer l\'asset',
|
||
'workbench.asset.add': 'Ajouter un asset',
|
||
'workbench.asset.todoTitle': 'Construire la liste d\'assets avec prompts',
|
||
'workbench.asset.todoBody': 'L\'agent Assets combine scénario, style et storyboard en prompts prêts à copier.',
|
||
'workbench.asset.generate': 'Rédiger la liste',
|
||
'workbench.asset.generateImage': 'Générer l\'image',
|
||
'workbench.asset.generateHint': 'Génère via le workflow ComfyUI connecté ; les résultats reviennent au projet',
|
||
'workbench.asset.summary': '{n} assets',
|
||
'workbench.vshot.noPh': 'N° de plan, ex. S1',
|
||
'workbench.vshot.descPh': 'Description du plan',
|
||
'workbench.vshot.promptPh': 'Prompt vidéo complet (anglais)',
|
||
'workbench.vshot.promptLabel': 'Prompt vidéo',
|
||
'workbench.vshot.remove': 'Supprimer le plan',
|
||
'workbench.vshot.add': 'Ajouter un plan',
|
||
'workbench.vshot.todoTitle': 'Produire le script vidéo plan par plan',
|
||
'workbench.vshot.todoBody': 'L\'agent Plans transforme le storyboard en prompts prêts pour les modèles vidéo.',
|
||
'workbench.vshot.generate': 'Rédiger les plans',
|
||
'workbench.vshot.generateVideo': 'Générer la vidéo du plan',
|
||
'workbench.vshot.generateHint': 'Génère via le workflow vidéo ComfyUI connecté ; résultats dans le projet',
|
||
'workbench.vshot.summary': '{n} plans',
|
||
'home.errScriptShort': 'Scénario trop court — vérifiez le collage (30 caractères min.)',
|
||
'home.stageProgress': 'Progression en cinq étapes',
|
||
'tasks.sourceWorkbench': 'Flux de création',
|
||
'jobst.idSuffix': ' · ID de prompt ComfyUI {id}',
|
||
'jobst.done': 'Fixé',
|
||
'jobst.doneDetail': 'ComfyUI a terminé, résultats enregistrés',
|
||
'jobst.dryRun': 'Substitut',
|
||
'jobst.dryRunDetail': 'Substitut uniquement : Dry-run actif, ComfyUI n\'a pas été appelé',
|
||
'jobst.noOutput': 'Aucune sortie',
|
||
'jobst.noOutputDetail': 'La tâche s\'est terminée sans fichier de résultat : pas une génération',
|
||
'jobst.missing': 'Fichiers manquants',
|
||
'jobst.missingDetail': 'La tâche a réussi, mais ses fichiers ne sont plus sur le serveur',
|
||
'jobst.queued': 'En attente',
|
||
'jobst.queuedDetail': 'En attente dans la file de l\'atelier avant envoi à ComfyUI',
|
||
'jobst.connecting': 'Connexion',
|
||
'jobst.connectingDetail': 'Connexion à ComfyUI et envoi des entrées',
|
||
'jobst.comfyQueued': 'Acceptée',
|
||
'jobst.comfyQueuedDetail': 'ComfyUI a accepté la tâche et l\'a mise en file',
|
||
'jobst.comfyQueuedAhead': 'ComfyUI a accepté la tâche — {n} devant dans sa file',
|
||
'jobst.comfyRunning': 'En cours',
|
||
'jobst.comfyRunningDetail': 'ComfyUI exécute la tâche',
|
||
'jobst.saving': 'Enregistrement',
|
||
'jobst.savingDetail': 'ComfyUI a renvoyé des résultats, téléchargement',
|
||
'jobst.failed': 'Échec',
|
||
'jobst.cancelled': 'Annulée',
|
||
'studio.ratioLabel': 'Format d\'image',
|
||
'studio.megapixelsLabel': 'Mégapixels',
|
||
'studio.outputSize': 'Sortie {w} × {h}',
|
||
'studio.denoiseLabel': 'Débruitage',
|
||
'studio.errNumber': '« {label} » doit être un nombre',
|
||
'studio.errInteger': '« {label} » doit être un entier',
|
||
'studio.errMin': '« {label} » doit valoir au moins {v}',
|
||
'studio.errMax': '« {label} » doit valoir au plus {v}',
|
||
'studio.errOption': '« {label} » n\'est pas une option du workflow',
|
||
'studio.reuseParams': 'Réutiliser les réglages',
|
||
'studio.reusedToast': 'Réglages de cette tâche repris : ajustez puis relancez',
|
||
'studio.reuseMissingWf': 'Le workflow de cette tâche n\'existe plus',
|
||
'studio.doneToast': 'Terminé : {n} fichier(s) (ID de prompt ComfyUI {id})',
|
||
'studio.dryRunToast': 'Substitut uniquement : Dry-run actif, ComfyUI n\'a pas été appelé',
|
||
'studio.dryRunNote': 'Dry-run actif : Générer n\'écrit que des substituts et n\'appelle jamais ComfyUI. Désactivez-le dans Réglages.',
|
||
// --- HEL-643 : vérification d'import / test réel / groupes de médias ---
|
||
'studio.errVideoFormat': "« {name} » n'est pas un format vidéo pris en charge — utilisez MP4 / WebM / MOV",
|
||
'studio.errAudioFormat': "« {name} » n'est pas un format audio pris en charge — utilisez MP3 / WAV / M4A",
|
||
'studio.errMediaSize': "« {name} » dépasse la limite de taille — compressez-le d'abord",
|
||
'studio.errNeedRefMedia': '« {label} » exige au moins {n} clips',
|
||
'studio.refHintMedia': 'Requis · 1–{max} clips · {n} sélectionnés',
|
||
'studio.refAddMedia': 'Ajouter {kind}',
|
||
'studio.refAddSubMedia': '{n} de plus · max {max}',
|
||
'studio.refRemoveMedia': 'Retirer {kind} {n}',
|
||
'studio.refFullMedia': 'Limite de {max} clips atteinte — retirez-en un pour en ajouter un autre',
|
||
'wfMedia.h3Limits': "Limites officielles MiniMax H3 Ref2VA : jusqu'à 9 images, 3 vidéos et 3 audios de référence ; chaque clip de 2–15 s, totaux ≤15 s par type ; l'audio ne peut être la seule référence ; 12 fichiers de référence au maximum.",
|
||
'wfMedia.h3TotalOver': '{n} fichiers de référence — au-delà du plafond officiel de 12 ; la génération peut échouer',
|
||
'wfMedia.h3AudioAlone': "L'audio ne peut pas être la seule référence — ajoutez au moins une image ou une vidéo",
|
||
'conn.wfCheckTitle': 'Vérification de compatibilité de la connexion',
|
||
'conn.wfCheckEndpoint': 'Cible : {name}',
|
||
'conn.wfCheckBtn': 'Revérifier',
|
||
'conn.wfChecking': 'Vérification…',
|
||
'conn.wfCheckOk': 'Cette connexion possède les nœuds et modèles requis par ce flux',
|
||
'conn.wfCheckProblems': '{n} nœud(s)/modèle(s) manquant(s) détecté(s)',
|
||
'conn.wfCheckUnreachable': "Vérification impossible (ComfyUI injoignable) — l'enregistrement reste possible ; revérifiez après avoir réparé la connexion",
|
||
'conn.wfCheckSaveHint': 'Vous pouvez enregistrer le brouillon (il ne sera pas marqué générable) ; installez le manquant puis revérifiez.',
|
||
'conn.wfTestBtn': 'Tester',
|
||
'conn.wfLastTest': 'Dernier test',
|
||
'conn.wfTestPassed': '{time} réussi ({n} fichiers)',
|
||
'conn.wfTestRunning': '{time} en cours',
|
||
'conn.wfTestFailed': '{time} échoué',
|
||
'wft.title': 'Tester le flux',
|
||
'wft.connection': 'Connexion cible',
|
||
'wft.costNote': 'Un test envoie une tâche réelle au ComfyUI choisi et mobilise son VRAM et sa file.',
|
||
'wft.submit': 'Lancer le test',
|
||
'wft.confirmTitle': 'Confirmer une exécution réelle',
|
||
'wft.confirmBody': 'Une tâche réelle sera envoyée à « {endpoint} » ({n} tâches en file). Le test ne réussit que si au moins un fichier téléchargeable du bon type revient.',
|
||
'wft.running': 'Test en cours…',
|
||
'wft.cancel': 'Annuler le test',
|
||
'wft.passed': 'Test réussi : {n} fichier(s) produit(s)',
|
||
'wft.passedShort': 'Réussi ({n} fichiers)',
|
||
'wft.failed': 'Test échoué',
|
||
'wft.failedShort': 'Échoué',
|
||
'wft.cancelledShort': 'Annulé',
|
||
'wft.reusedToast': 'Un test est déjà en cours pour ce flux — rattaché à celui-ci',
|
||
'wft.history': 'Historique des tests ({n})',
|
||
'wft.clear': "Effacer l'historique des tests",
|
||
'wft.cleared': 'Historique des tests effacé',
|
||
'wft.never': 'Jamais testé',
|
||
'wft.download': 'Télécharger',
|
||
'wft.errRequired': 'Veuillez renseigner « {label} »',
|
||
'wft.errListMin': '« {label} » exige au moins {n} {unit}',
|
||
'tasks.testBadge': 'Test',
|
||
'tasks.sourceWorkflowTest': 'Test de flux',
|
||
// --- 生成台 (HEL-653) ---
|
||
'cdf.orig': 'Original {v}',
|
||
'desk.title': 'Générer',
|
||
'desk.advanced': 'Avancé · {n} · inchangés, les valeurs du workflow s’appliquent',
|
||
'desk.chipResolution': 'Résolution {v}',
|
||
'desk.chipSeconds': '{v} s',
|
||
'desk.chipSeed': 'Graine {v}',
|
||
'desk.closeInspector': 'Fermer l’inspecteur',
|
||
'desk.countActive': '{n} en cours',
|
||
'desk.countTakes': '{n} prises',
|
||
'desk.ctxAsset': '{kind} « {name} »',
|
||
'desk.ctxShot': 'Plan {no}',
|
||
'desk.ctxBack': 'Retour à {stage}',
|
||
'desk.ctxDismiss': 'Fermer la note d’origine',
|
||
'desk.ctxFrom': 'Depuis « {project} »',
|
||
'desk.ctxNoBackfill': 'Les résultats restent dans le fil et ne sont pas renvoyés vers {stage}',
|
||
'desk.dayDate': '{d}/{m}',
|
||
'desk.download': 'Télécharger',
|
||
'desk.dropNoSlot': '{n} fichier(s) sans emplacement : ce workflow n’a pas cette entrée',
|
||
'desk.dryRun': 'Simulation',
|
||
'desk.durMin': '{m} min {s} s',
|
||
'desk.durSec': '{s} s',
|
||
'desk.elapsed': 'Durée',
|
||
'desk.emptyFailed': 'Aucune prise échouée',
|
||
'desk.emptyFeed': 'Aucune prise. Écrivez un prompt ci-dessous et cliquez sur Générer.',
|
||
'desk.filterAria': 'Filtrer les prises',
|
||
'desk.filterAll': 'Tout',
|
||
'desk.filterImage': 'Images',
|
||
'desk.filterVideo': 'Vidéos',
|
||
'desk.filterFailed': 'Échecs',
|
||
'desk.generate': 'Générer',
|
||
'desk.genHint': 'Générer (Ctrl/⌘ + Entrée)',
|
||
'desk.inputs': 'Entrées',
|
||
'desk.inspector': 'Inspecteur',
|
||
'desk.keyClose': 'Fermer',
|
||
'desk.keyInspector': 'Afficher / masquer',
|
||
'desk.keySelect': 'Choisir',
|
||
'desk.keyUse': 'Utiliser',
|
||
'desk.kvCreated': 'Soumis',
|
||
'desk.kvName': 'Nom',
|
||
'desk.kvPromptId': 'ID ComfyUI',
|
||
'desk.kvUsage': 'Usage',
|
||
'desk.loadEarlier': 'Afficher {n} prises plus anciennes',
|
||
'desk.missingSub': 'Refaire avec les mêmes paramètres, ou retirer cette prise',
|
||
'desk.missingTitle': 'Les fichiers de résultat ne sont plus sur le serveur',
|
||
'desk.needWorkflow': 'Manque : workflow',
|
||
'desk.noConn': 'Non connecté',
|
||
'desk.noPromptInput': 'Ce workflow n’a pas de prompt ; il s’exécute avec ses propres valeurs.',
|
||
'desk.notGenerated': 'Non généré',
|
||
'desk.noWorkflows': 'Aucun workflow image ou vidéo prêt',
|
||
'desk.openInDesk': 'Régler dans le générateur',
|
||
'desk.openInDeskHint': 'Ouvre le générateur avec ce prompt ; choisissez workflow et paramètres, les résultats restent dans le fil',
|
||
'desk.openInspector': 'Inspecteur',
|
||
'desk.origValue': 'Valeur du workflow',
|
||
'desk.outputN': 'Résultat {n}',
|
||
'desk.outputs': 'Tous les résultats',
|
||
'desk.paramError': 'Paramètre invalide : {msg}',
|
||
'desk.paramsAll': 'Tous les paramètres',
|
||
'desk.paramsChanged': 'Paramètres · {n} modifiés',
|
||
'desk.paramsCommon': 'Paramètres courants',
|
||
'desk.pickTake': 'Choisissez une prise pour voir son résultat',
|
||
'desk.pickWorkflow': 'Choisir un workflow',
|
||
'desk.promptOnly': 'Prompt seul',
|
||
'desk.promptPh': 'Décrivez l’image… (Ctrl/⌘ + Entrée pour générer, / pour cibler)',
|
||
'desk.restoreAll': 'Rétablir toutes les valeurs du workflow',
|
||
'desk.redo': 'Refaire avec les mêmes paramètres',
|
||
'desk.removeRecord': 'Retirer la ligne',
|
||
'desk.restoreOrig': 'Rétablir l’original',
|
||
'desk.reuse': 'Réutiliser',
|
||
'desk.reuseToComposer': 'Réutiliser dans l’éditeur',
|
||
'desk.seedRandom': 'Aléatoire',
|
||
'desk.sendToSlot': 'Envoyer vers l’emplacement image',
|
||
'desk.sent': 'Soumis',
|
||
'desk.sentToSlotToast': 'Envoyé vers l’emplacement image du workflow actuel',
|
||
'desk.slotOne': '{label} ×1',
|
||
'desk.slotRange': '{label} {min}–{max}',
|
||
'desk.specSize': 'Taille',
|
||
'desk.stillNeed': 'Manque : {what}',
|
||
'desk.tabParams': 'Paramètres',
|
||
'desk.tabResult': 'Résultat',
|
||
'desk.today': 'Aujourd’hui',
|
||
'desk.took': 'Durée {d}',
|
||
'desk.wfBroken': 'Indisponible',
|
||
'desk.wfCurrent': 'actuel',
|
||
'desk.wfDefaultConn': 'Connexion par défaut',
|
||
'desk.wfImport': 'Importer / gérer les workflows',
|
||
'desk.wfLastFailed': 'Dernier essai échoué',
|
||
'desk.wfNoMatch': 'Aucun workflow correspondant',
|
||
'desk.wfOk': 'Prêt',
|
||
'desk.wfSearchPh': 'Chercher un workflow ou un usage : image vers vidéo, référence…',
|
||
'desk.wfTesting': 'Test en cours',
|
||
'desk.wfUntested': 'Non testé',
|
||
'desk.workflow': 'Workflow',
|
||
'desk.yesterday': 'Hier',
|
||
'wfd.stepParse': 'Analyser le JSON',
|
||
'wfd.stepNodes': 'Identifier les nœuds',
|
||
'wfd.stepModels': 'Vérifier les modèles',
|
||
'wfd.stepSlots': 'Créer les slots d’entrée',
|
||
'wfd.noOutput': "Le flux n'a aucun nœud de sortie — import impossible",
|
||
'wfd.nodesAutoOk': 'Usage détecté automatiquement : {usage}',
|
||
'wfd.nodesUserOk': 'Usage confirmé : {usage}',
|
||
'wfd.modelsOk': '« {name} » possède tous les nœuds et modèles requis',
|
||
'wfd.slotsOk': "{n} slot(s) d'entrée créés ({m} média)",
|
||
'wfd.checksAria': "Résultats de la vérification d'import",
|
||
'wfd.showDetails': "Afficher les détails de l'erreur",
|
||
'wfd.hideDetails': "Masquer les détails de l'erreur",
|
||
'wfd.unreachableSuggest': "L'impossibilité de vérifier n'empêche pas l'enregistrement ; revérifiez après avoir réparé la connexion.",
|
||
'wfd.nodesPickSuggest': "Choisissez l'usage et terminez le mappage des sorties ci-dessous avant d'enregistrer.",
|
||
'wfd.showRaw': 'Voir le JSON brut',
|
||
'wfd.hideRaw': 'Masquer le JSON brut',
|
||
|
||
// --- Workflow library · batch import & management (HEL-682) ---
|
||
'wl.hint': 'Importez par lots des flux au format UI ; cherchez, filtrez, annotez — le JSON complet ne se charge qu’à l’action',
|
||
'wl.batchImport': 'Import par lot',
|
||
'wl.dedupe': 'Dédupliquer',
|
||
'wl.dedupeTitle': 'Supprimer les flux dupliqués',
|
||
'wl.dedupeConfirm': 'Les entrées au nom ET contenu identiques seront supprimées (le premier import est conservé). Même nom mais contenu différent = votre variante, intact. Continuer ?',
|
||
'wl.dedupeDone': '{n} flux dupliqués supprimés',
|
||
'wl.dedupeNone': 'Aucun flux dupliqué trouvé',
|
||
'wl.favCount': '{n} favoris',
|
||
'wl.searchPh': 'Rechercher nom, description, tags, modèle… (touche /)',
|
||
'wl.filterLabel': 'Filtres',
|
||
'wl.filterAll': 'Tous',
|
||
'wl.filterFav': 'Favoris',
|
||
'wl.filterPending': 'À confirmer',
|
||
'wl.filterDisabled': 'Désactivés',
|
||
'wl.favAria': 'Mettre en favori',
|
||
'wl.unfavAria': 'Retirer des favoris',
|
||
'wl.categoryLabel': 'Catégorie',
|
||
'wl.categoryAll': 'Toutes les catégories',
|
||
'wl.familyLabel': 'Famille de modèle',
|
||
'wl.familyAll': 'Toutes les familles',
|
||
'wl.mediaLabel': 'Média',
|
||
'wl.mediaAll': 'Tous les médias',
|
||
'wl.mediaImage': 'Image',
|
||
'wl.mediaVideo': 'Vidéo',
|
||
'wl.mediaAudio': 'Audio',
|
||
'wl.mediaIn': 'Entrée',
|
||
'wl.mediaOut': 'Sortie',
|
||
'wl.sortLabel': 'Tri',
|
||
'wl.sortRecent': 'Favoris / récents',
|
||
'wl.sortName': 'Nom',
|
||
'wl.resetFilters': 'Effacer les filtres',
|
||
'wl.noMatch': 'Aucun flux ne correspond aux filtres',
|
||
'wl.resultCount': '{n} sur {m}',
|
||
'wl.selected': '{n} sélectionnés',
|
||
'wl.batchLabel': 'Actions groupées',
|
||
'wl.batchAnnotate': 'Annoter',
|
||
'wl.batchEnable': 'Activer',
|
||
'wl.batchDisable': 'Désactiver',
|
||
'wl.clearSel': 'Effacer la sélection',
|
||
'wl.batchDone': '{n} flux mis à jour',
|
||
'wl.batchPartial': '{n} réussis, {m} échoués (usage et sortie à confirmer d’abord)',
|
||
'wl.selectAll': 'Sélectionner tous les flux listés',
|
||
'wl.rowCheckAria': 'Sélectionner {name}',
|
||
'wl.headMeta': 'Métadonnées',
|
||
'wl.headActions': 'Actions',
|
||
'wl.enableAria': 'Activer ou désactiver {name}',
|
||
'wl.enableBlocked': 'Confirmez l’usage et les nœuds de sortie avant activation',
|
||
'wl.editMeta': 'Modifier les métadonnées',
|
||
'wl.lastUsed': 'Dernière utilisation',
|
||
'wl.moreCount': 'Afficher {n} de plus ({m} au total)',
|
||
'wfCat.basic': 'Traitement de base',
|
||
'wfCat.audioTts': 'Génération de voix',
|
||
'wfCat.music': 'Génération de musique',
|
||
'wfCat.image': 'Génération d’images',
|
||
'wfCat.video': 'Génération de vidéo',
|
||
'wfCat.digitalHuman': 'Humain numérique',
|
||
'wfCat.motionTransfer': 'Transfert de mouvement',
|
||
'md.title': 'Métadonnées du flux',
|
||
'md.batchTitle': 'Annotation groupée ({n})',
|
||
'md.batchHint': 'Seuls les champs remplis sont appliqués ; renommage par rechercher→remplacer, tags ajoutés.',
|
||
'md.name': 'Nom affiché',
|
||
'md.nameFind': 'Rechercher',
|
||
'md.nameFindPh': 'Texte à remplacer…',
|
||
'md.nameReplace': 'Remplacer par',
|
||
'md.nameReplacePh': 'Texte de remplacement…',
|
||
'md.nameHint': 'Laissez « Rechercher » vide pour ne pas renommer.',
|
||
'md.description': 'Description',
|
||
'md.descriptionPh': 'Une ligne sur ce que fait ce flux…',
|
||
'md.tags': 'Tags',
|
||
'md.tagsPh': 'ex. rapide, haute qualité',
|
||
'md.tagsHint': 'Séparés par des virgules ; ajoutés en mode groupé.',
|
||
'md.category': 'Catégorie',
|
||
'md.modelFamily': 'Famille de modèle',
|
||
'md.apply': 'Appliquer',
|
||
'md.applied': '{n} flux mis à jour',
|
||
'md.appliedOne': 'Mis à jour',
|
||
'md.partial': '{n} réussis, {m} échoués',
|
||
'wiz.title': 'Import de flux par lot',
|
||
'wiz.stepSource': 'Source',
|
||
'wiz.stepReport': 'Rapport de test',
|
||
'wiz.stepResult': 'Résultat',
|
||
'wiz.sourceLabel': 'Source d’import',
|
||
'wiz.modeScan': 'Scanner un dossier serveur',
|
||
'wiz.modeFiles': 'Choisir des fichiers locaux',
|
||
'wiz.rootLabel': 'Dossier serveur',
|
||
'wiz.rootHint': 'Chemin d’un dossier sur le serveur (ex. example_ComfyUI_workflows du dépôt) ; les JSON au format UI sont scannés récursivement, le format API et les autres sont ignorés.',
|
||
'wiz.preflight': 'Pré-vérification sur un ComfyUI réel (facultatif)',
|
||
'wiz.preflightNone': 'Passer (conversion hors ligne)',
|
||
'wiz.preflightHint': 'Avec une connexion choisie, les graphes convertis sont vérifiés nœud par nœud.',
|
||
'wiz.pickFiles': 'Fichiers locaux',
|
||
'wiz.pickFilesBtn': 'Choisir des fichiers JSON (plusieurs)',
|
||
'wiz.pickFilesHint': 'Choisissez des flux ComfyUI au format UI ; sélection multiple possible.',
|
||
'wiz.parsed': '{n} fichiers lus',
|
||
'wiz.notUi': '{n} fichiers ne sont pas au format UI (pas de tableau nodes), ignorés',
|
||
'wiz.noFiles': 'Choisissez d’abord des fichiers à importer',
|
||
'wiz.runDry': 'Lancer le test (rien n’est enregistré)',
|
||
'wiz.running': 'Vérification…',
|
||
'wiz.total': '{n} fichiers',
|
||
'wiz.ok': 'OK {n}',
|
||
'wiz.warn': 'Avertissements {n}',
|
||
'wiz.fail': 'Échecs {n}',
|
||
'wiz.confirmCount': 'À vérifier {n}',
|
||
'wiz.importable': 'Importables {n}',
|
||
'wiz.reportHint': 'Le test n’écrit rien. Les avertissements s’importent activés dès qu’un usage est fourni ; les fichiers à vérifier ou en échec ne sont jamais importés.',
|
||
'wiz.filterLabel': 'Filtres du rapport',
|
||
'wiz.filterWarn': 'Avertissements seuls',
|
||
'wiz.filterBlocked': 'Non importables',
|
||
'wiz.searchPh': 'Rechercher un nom de fichier…',
|
||
'wiz.includeAria': 'Importer {name}',
|
||
'wiz.skipReason': 'Non importable : {reason}',
|
||
'wiz.issues': '{n} notes de conversion',
|
||
'wiz.usagePick': 'Usage :',
|
||
'wiz.usageNone': 'Passer pour l’instant (à confirmer après import)',
|
||
'wiz.selectedN': '{n} fichiers seront importés',
|
||
'wiz.excludedM': '{m} non importables',
|
||
'wiz.import': 'Importer',
|
||
'wiz.importing': 'Import…',
|
||
'wiz.back': 'Retour',
|
||
'wiz.imported': '{n} importés',
|
||
'wiz.skipped': '{n} ignorés',
|
||
'wiz.conflict': 'Existe déjà (doublon ignoré)',
|
||
'wiz.usageApplied': 'Usage fourni pour {n} nouveaux imports',
|
||
'wiz.done': 'Terminé',
|
||
'wiz.again': 'Importer un autre lot',
|
||
'wiz.resultNote': 'Les fichiers au contenu identique sont ignorés automatiquement — relancer ne crée jamais de doublons.',
|
||
'wiz.importedToast': '{n} flux importés',
|
||
'wiz.warnTag': 'Avertissement',
|
||
'wiz.confirmTag': 'À vérifier',
|
||
'wiz.preflightTag': 'Pré-vérification échouée',
|
||
'wiz.importedTag': 'Importé #{id}',
|
||
};
|