- Surface API `solver.run(editionId)` (HTTP + mock) et hooks `useRunSolver` (mutation, alimente le cache) / `useSolverSuggestions` (lecture seule du cache, ne déclenche jamais de calcul). - Grille des besoins : bouton « Suggestions (solveur) », affiche le nombre de suggestions calculées. - Panneau d'affectation d'un créneau : les bénévoles suggérés par le solveur passent en tête de la liste des candidats (avant le tri par disponibilité / charge), avec un badge « Suggéré ». Ne pré-affecte jamais personne — la coordination choisit et confirme comme avant. - Mock : portage glouton (par créneau, du plus urgent au moins urgent) du scoring du moteur back-end, pour une démonstration cohérente sans CP-SAT côté navigateur. typecheck / lint / build / smoke au vert. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017uUsRg7XzopkCPWimwg9ZM
302 lines
18 KiB
JSON
302 lines
18 KiB
JSON
{
|
||
"filter.all": "TOUS",
|
||
"legend.title": "LÉGENDE",
|
||
"action.close": "Fermer",
|
||
"action.remove": "Retirer",
|
||
"action.add": "Ajouter",
|
||
"app.loading": "Chargement…",
|
||
"app.error.generic": "Une erreur est survenue",
|
||
"error.generic": "Erreur inattendue",
|
||
"error.not_found": "Ressource introuvable",
|
||
"error.forbidden": "Accès refusé",
|
||
"error.unauthorized": "Authentification requise",
|
||
"error.validation_failed": "La validation a échoué (règle bloquante)",
|
||
"assignment.duplicate": "Ce bénévole est déjà affecté à ce créneau",
|
||
"assignment.wrong_edition": "Bénévole ou créneau hors de cette édition",
|
||
"volunteer.duplicate_email": "Un bénévole avec cet email existe déjà",
|
||
"shift.ends_not_after_starts": "La fin doit être après le début",
|
||
"shift.position_wrong_edition": "Le poste n'appartient pas à cette édition",
|
||
"auth.invalid_credentials": "Email ou mot de passe incorrect",
|
||
"auth.invalid_token": "Ce lien de connexion est invalide ou expiré",
|
||
"role.coordinator": "Coordination",
|
||
"role.lead": "Référent",
|
||
"role.volunteer": "Bénévole",
|
||
"auth.logout": "Déconnexion",
|
||
"auth.email": "Email",
|
||
"auth.password": "Mot de passe",
|
||
"auth.signIn": "Se connecter",
|
||
"auth.signingIn": "Connexion…",
|
||
"auth.admin.title": "Espace coordination",
|
||
"auth.demoCredentials": "Démo : {email} · mot de passe « {password} »",
|
||
"auth.notAdmin": "Bénévole ou référent ?",
|
||
"auth.magicLinkLink": "Recevoir un lien de connexion",
|
||
"auth.isAdmin": "Vous êtes de la coordination ?",
|
||
"auth.adminLink": "Connexion par mot de passe",
|
||
"auth.magic.title": "Connexion bénévole / référent",
|
||
"auth.magic.lead": "Entrez votre email : vous recevrez un lien de connexion, sans mot de passe.",
|
||
"auth.magic.send": "Envoyer le lien",
|
||
"auth.magic.sending": "Envoi…",
|
||
"auth.magic.sent": "Si un compte correspond à cet email, un lien de connexion vient d'être envoyé.",
|
||
"auth.magic.devHint": "Démo (email stubé) — cliquez ce lien :",
|
||
"auth.magic.another": "Utiliser un autre email",
|
||
"auth.magic.verifyTitle": "Connexion en cours",
|
||
"auth.magic.verifying": "Vérification du lien…",
|
||
"auth.magic.retry": "Demander un nouveau lien",
|
||
"header.title": "GESTION DES BÉNÉVOLES",
|
||
"header.meta": "BÉNÉVOLAT · {count} INSCRITS",
|
||
"header.mockMode": "DONNÉES DE DÉMO",
|
||
"tab.grille": "Grille des besoins",
|
||
"tab.volunteers": "Vue par bénévole",
|
||
"tab.mobileVolunteer": "Bénévole · mobile",
|
||
"tab.mobileLead": "Référent · mobile",
|
||
"tab.config": "Configuration",
|
||
"position.category.bar": "Bar",
|
||
"position.category.ticketing": "Billetterie",
|
||
"position.category.welcome": "Accueil",
|
||
"position.category.parking": "Parking",
|
||
"position.category.cleaning": "Propreté",
|
||
"position.category.catering": "Catering",
|
||
"position.category.setup": "Montage",
|
||
"position.category.stage": "Régie",
|
||
"position.category.other": "Autre",
|
||
"validation.SHIFT_OVERLAP": "Se chevauche avec un autre créneau",
|
||
"validation.SHIFT_OVERLAP.at": "Déjà affecté sur {position} au même moment",
|
||
"validation.SHIFT_OVERLAP.rule": "Deux créneaux d'un même bénévole se chevauchent.",
|
||
"validation.OUTSIDE_AVAILABILITY": "Hors des disponibilités déclarées ({gap} non couvertes).",
|
||
"validation.OUTSIDE_AVAILABILITY.rule": "Le créneau n'est pas entièrement couvert par les disponibilités déclarées.",
|
||
"validation.DAILY_HOURS_EXCEEDED": "Plus de 8 h sur la journée ({hours})",
|
||
"validation.DAILY_HOURS_EXCEEDED.rule": "Plus de 8 h 00 d'affectations cumulées sur une même journée.",
|
||
"validation.INSUFFICIENT_REST": "Moins de 8 h de repos entre deux créneaux ({rest})",
|
||
"validation.INSUFFICIENT_REST.rule": "Moins de 8 h 00 entre la fin d'un créneau et le début du suivant.",
|
||
"grille.filter.day": "JOUR",
|
||
"grille.filter.position": "POSTE",
|
||
"grille.legend.critical": "SOUS-EFFECTIF CRITIQUE",
|
||
"grille.legend.incomplete": "INCOMPLET",
|
||
"grille.legend.complete": "COMPLET",
|
||
"grille.legend.overstaffed": "SUREFFECTIF",
|
||
"grille.legend.undefined": "À DÉFINIR",
|
||
"grille.positionsCount": "{count} POSTES",
|
||
"grille.assignedRequired": "AFFECTÉS / IDÉAL",
|
||
"grille.footnote": "Chaque cellule est un créneau. Nombre = bénévoles affectés, / = effectif idéal. Cliquer ouvre le panneau d'affectation à droite.",
|
||
"grille.empty": "Aucun créneau pour le moment. Créez des postes dans Configuration → « Postes & créneaux » — un créneau est généré par jour et par créneau type.",
|
||
"grille.panel.empty.title": "Cliquez une cellule de la grille pour affecter des bénévoles.",
|
||
"grille.panel.empty.body": "Le panneau s'ouvre ici, sans quitter la grille : candidats triés par charge, alertes bloquantes et avertissements du moteur de validation.",
|
||
"grille.panel.slotDuration": "CRÉNEAU DE {hours} H",
|
||
"grille.panel.assigned": "AFFECTÉS",
|
||
"grille.panel.min": "MINIMUM {count}",
|
||
"grille.panel.ideal": "IDÉAL {count}",
|
||
"grille.panel.assignmentsTitle": "AFFECTATIONS ({count})",
|
||
"grille.panel.noneAssigned": "Personne n'est encore affecté sur ce créneau.",
|
||
"grille.panel.hoursTotal": "{hours} H AU TOTAL",
|
||
"grille.panel.candidates": "CANDIDATS",
|
||
"grille.panel.candidatesHint": "LES MOINS CHARGÉS D'ABORD",
|
||
"grille.panel.hoursAssigned": "{hours} H · {slots} CRÉNEAUX",
|
||
"grille.panel.assign": "AFFECTER",
|
||
"grille.panel.blocked": "BLOQUÉ",
|
||
"grille.panel.blockingPrefix": "BLOQUANT — {reason}",
|
||
"grille.panel.warningsTitle": "⚠ AVERTISSEMENTS — AFFECTATION POSSIBLE",
|
||
"volunteers.filter.show": "AFFICHER",
|
||
"volunteers.filter.all": "TOUS",
|
||
"volunteers.filter.overloaded": "SURCHARGÉS",
|
||
"volunteers.filter.unassigned": "SANS AFFECTATION",
|
||
"volunteers.legend.assigned": "AFFECTATION",
|
||
"volunteers.count": "{count} BÉNÉVOLES",
|
||
"volunteers.totalHours": "TOTAL H",
|
||
"volunteers.name": "NOM",
|
||
"volunteers.cumulative": "CUMUL",
|
||
"volunteers.badge.overloaded": "▲ SURCHARGE",
|
||
"volunteers.badge.unassigned": "○ OUBLIÉ",
|
||
"volunteers.empty": "Aucun bénévole ne correspond à ce filtre — bonne nouvelle. Repassez sur « TOUS » pour revoir l'ensemble de l'équipe.",
|
||
"volunteers.noData": "Aucun bénévole pour le moment. Ajoutez-les dans Configuration → « Bénévoles & import ».",
|
||
"volunteers.footnote": "Surcharge = plus de 8 h sur une même journée ou moins de 8 h entre deux créneaux. Oublié = aucune affectation.",
|
||
"design.noteTitle": "CHOIX DE CONCEPTION",
|
||
"mobileVol.statusTime": "9:41",
|
||
"mobileVol.kicker": "MON PLANNING BÉNÉVOLE",
|
||
"mobileVol.greeting": "SALUT {name}",
|
||
"mobileVol.slots": "{count} CRÉNEAUX",
|
||
"mobileVol.hours": "{count} HEURES",
|
||
"mobileVol.location": "📍 {location}",
|
||
"mobileVol.slotAssigned": "✓ TU ES ATTENDU SUR CE CRÉNEAU",
|
||
"mobileVol.noSlots": "Aucun créneau pour l'instant. La coordination t'affectera bientôt.",
|
||
"mobileVol.noAccount": "Ce compte n'est rattaché à aucun bénévole. Contactez la coordination.",
|
||
"mobileVol.detailsUnavailable": "Le détail des créneaux (poste, horaires) n'est pas encore exposé aux bénévoles par l'API.",
|
||
"mobileVol.designNote": "Lisibilité plein soleil : fonds opaques, texte noir sur jaune ou blanc, aucun gris clair. Cibles tactiles à 52–62 px de haut. Une seule action par créneau. Les données proviennent des affectations réelles de l'API.",
|
||
"mobileLead.statusTime": "18:07",
|
||
"mobileLead.kicker": "RÉFÉRENT DE POSTE",
|
||
"mobileLead.inProgress": "CRÉNEAU · {hours}",
|
||
"mobileLead.present": "{present}/{total} POINTÉS PRÉSENTS",
|
||
"mobileLead.absenceAlert": "⚠ {count} ABSENCE(S) SUR LE CRÉNEAU",
|
||
"mobileLead.requestBackup": "DEMANDER UN RENFORT À LA COORDINATION",
|
||
"mobileLead.teamTitle": "POINTAGE DE L'ÉQUIPE",
|
||
"mobileLead.badgePresent": "✓ PRÉSENT",
|
||
"mobileLead.badgeAbsent": "✕ ABSENT",
|
||
"mobileLead.markPresent": "PRÉSENT",
|
||
"mobileLead.markAbsent": "ABSENT",
|
||
"mobileLead.emptyTeam": "Aucun bénévole affecté à ce créneau.",
|
||
"mobileLead.designNote": "Le référent ne voit que son poste et un créneau. Le pointage est un geste unique par personne. Il est local à cette maquette : le pointage sur site est hors périmètre (CLAUDE.md §4).",
|
||
"config.admin": "ADMINISTRATION",
|
||
"config.reserved": "RÉSERVÉ À LA COORDINATION",
|
||
"config.tab.grid": "POSTES & CRÉNEAUX",
|
||
"config.tab.volunteers": "BÉNÉVOLES & IMPORT",
|
||
"config.tab.mail": "MESSAGES",
|
||
"config.tab.rules": "RÈGLES & ÉDITION",
|
||
"config.grid.positionsHeader": "POSTES · {count} CRÉNEAUX",
|
||
"config.grid.slotsCount": "{count} créneaux",
|
||
"config.grid.addPosition": "+ AJOUTER UN POSTE",
|
||
"config.grid.newPositionName": "Nouveau poste",
|
||
"config.grid.minTotal": "BESOIN MINIMUM · TOTAL",
|
||
"config.grid.idealTotal": "BESOIN IDÉAL · TOTAL",
|
||
"config.grid.min": "MIN",
|
||
"config.grid.ideal": "IDÉAL",
|
||
"config.grid.emptyDay": "Aucun créneau ce jour.",
|
||
"config.grid.deletePosition": "SUPPRIMER LE POSTE",
|
||
"config.grid.deletePositionConfirm": "Supprimer ce poste et tous ses créneaux ?",
|
||
"config.grid.generateShifts": "GÉNÉRER LES CRÉNEAUX",
|
||
"config.grid.generated": "{count} créneau(x) ajouté(s).",
|
||
"config.grid.note": "Effectifs, créneaux, nom et catégorie du poste sont enregistrés immédiatement via l'API. Pour ajouter ou retirer des jours, modifiez les dates de l'édition dans l'onglet « Règles & édition ».",
|
||
"config.vol.importTitle": "IMPORTER DES BÉNÉVOLES",
|
||
"config.vol.importHint": "Trois façons d'ajouter des bénévoles : saisie manuelle, import d'un fichier CSV / Excel, ou (à venir) le formulaire d'inscription en ligne.",
|
||
"config.vol.profiles": "PROFILS ENREGISTRÉS",
|
||
"config.vol.colName": "NOM",
|
||
"config.vol.colPhone": "TÉLÉPHONE",
|
||
"config.vol.colEmail": "EMAIL",
|
||
"config.vol.ficheKicker": "FICHE BÉNÉVOLE",
|
||
"config.vol.firstName": "PRÉNOM",
|
||
"config.vol.lastName": "NOM",
|
||
"config.vol.phone": "TÉLÉPHONE",
|
||
"config.vol.email": "EMAIL (LIEN MAGIQUE)",
|
||
"config.vol.delete": "SUPPRIMER (RGPD — EFFACEMENT COMPLET)",
|
||
"config.vol.deleteConfirm": "Supprimer définitivement ce bénévole et toutes ses données (disponibilités, affectations) ?",
|
||
"config.vol.note": "Modifications enregistrées immédiatement via l'API. La suppression est un effacement complet en cascade (RGPD).",
|
||
"config.mail.smtpBanner": "Envoie un récapitulatif de planning à chaque bénévole. L'email part si le serveur SMTP est configuré (EMAIL_ENABLED) ; sinon il est seulement journalisé.",
|
||
"config.mail.templateTitle": "MODÈLE DE MESSAGE",
|
||
"config.mail.senderNote": "Expéditeur défini côté serveur (SMTP_FROM).",
|
||
"config.mail.subject": "OBJET",
|
||
"config.mail.body": "CORPS DU MESSAGE",
|
||
"config.mail.variables": "VARIABLES DISPONIBLES",
|
||
"config.mail.variablesHint": "Cliquer une variable l'ajoute au corps. {lien_connexion} insère un lien de connexion personnel.",
|
||
"config.mail.send": "ENVOYER LE RÉCAPITULATIF",
|
||
"config.mail.sendWithLink": "ENVOYER AVEC LIEN DE CONNEXION",
|
||
"config.mail.sending": "ENVOI EN COURS…",
|
||
"config.mail.sent": "Envoi lancé : {queued} email(s), {skipped} bénévole(s) sans adresse.",
|
||
"config.mail.loginLinkLine": "Accède à ton planning : {lien_connexion}",
|
||
"config.mail.previewTitle": "APERÇU",
|
||
"config.mail.previewSender": "DE : expéditeur configuré côté serveur",
|
||
"config.rules.editionTitle": "ÉDITION",
|
||
"config.rules.editionName": "Nom",
|
||
"config.rules.editionStart": "Premier jour",
|
||
"config.rules.editionEnd": "Dernier jour",
|
||
"config.rules.editionDays": "{count} jour(s)",
|
||
"config.rules.editionSave": "ENREGISTRER L'ÉDITION",
|
||
"config.rules.editionSaved": "Édition enregistrée.",
|
||
"config.rules.apiMode": "Mode API",
|
||
"config.rules.volunteersCount": "Bénévoles",
|
||
"config.rules.positionsCount": "Postes",
|
||
"config.rules.shiftsCount": "Créneaux",
|
||
"edition.dates_inconsistent": "La date de fin doit être postérieure ou égale à la date de début.",
|
||
"day_part.code_required": "Le libellé du créneau type est requis.",
|
||
"day_part.duplicate_code": "Un créneau type porte déjà ce libellé.",
|
||
"config.rules.slotsTitle": "CRÉNEAUX TYPES",
|
||
"config.rules.slotLabel": "Libellé",
|
||
"config.rules.slotAdd": "AJOUTER",
|
||
"config.rules.slotsNote": "Ces créneaux sont ajoutés à besoin 0/0 sur chaque jour à la création d'un poste. Après un ajout ici (ou une extension des dates), utilisez « Générer les créneaux » sur le poste.",
|
||
"config.rules.thresholdsTitle": "MOTEUR DE VALIDATION",
|
||
"config.rules.maxDaily": "Maximum d'heures par journée",
|
||
"config.rules.minRest": "Repos minimum entre deux créneaux",
|
||
"config.rules.thresholdsNote": "Seuils figés côté back-end (CLAUDE.md §3) : non paramétrables. Le double emploi au même créneau est toujours bloquant.",
|
||
"config.rules.rulesTitle": "RÈGLES APPLIQUÉES",
|
||
"config.rules.rolesTitle2": "RÔLES ET ACCÈS",
|
||
"config.rules.roleCoordinator": "Coordination",
|
||
"config.rules.roleCoordinatorDesc": "Accès complet, construit et publie les plannings",
|
||
"config.rules.roleLead": "Référent de poste",
|
||
"config.rules.roleLeadDesc": "Lecture sur l'édition, écriture sur ses postes",
|
||
"config.rules.roleVolunteer": "Bénévole",
|
||
"config.rules.roleVolunteerDesc": "Ses seules données, lien magique par email",
|
||
"config.vol.addButton": "AJOUTER MANUELLEMENT",
|
||
"config.vol.importButton2": "IMPORTER UN FICHIER",
|
||
"config.vol.search": "Rechercher un nom, un email…",
|
||
"config.vol.emptyList": "Aucun bénévole pour l'instant. Ajoutez-en un ou importez un fichier.",
|
||
"config.vol.noMatch": "Aucun bénévole ne correspond à la recherche.",
|
||
"config.vol.count": "{count} bénévole(s)",
|
||
"config.vol.cancel": "ANNULER",
|
||
"config.vol.field.firstName": "Prénom",
|
||
"config.vol.field.lastName": "Nom",
|
||
"config.vol.field.email": "Email (lien magique)",
|
||
"config.vol.field.phone": "Téléphone",
|
||
"config.vol.field.comment": "Commentaire",
|
||
"config.vol.addTitle": "NOUVEAU BÉNÉVOLE",
|
||
"config.vol.addHint": "Le bénévole reçoit un accès par lien magique uniquement si un email est renseigné.",
|
||
"config.vol.create": "CRÉER LE BÉNÉVOLE",
|
||
"config.vol.requiredNames": "Le prénom et le nom sont obligatoires.",
|
||
"config.vol.wiz.title": "IMPORTER UN FICHIER",
|
||
"config.vol.wiz.step1": "1 · FICHIER",
|
||
"config.vol.wiz.step2": "2 · COLONNES",
|
||
"config.vol.wiz.step3": "3 · APERÇU & IMPORT",
|
||
"config.vol.wiz.pickFile": "CHOISIR UN FICHIER CSV OU EXCEL",
|
||
"config.vol.wiz.fileHint": "Une ligne par bénévole. La première ligne contient les intitulés de colonnes. En mode démonstration, seuls les fichiers CSV sont pris en charge.",
|
||
"config.vol.wiz.analyzing": "Analyse du fichier…",
|
||
"config.vol.wiz.detected": "{rows} ligne(s) · {cols} colonne(s) détectée(s)",
|
||
"config.vol.wiz.preview": "APERÇU DES PREMIÈRES LIGNES",
|
||
"config.vol.wiz.mapTitle": "ASSOCIER LES COLONNES",
|
||
"config.vol.wiz.mapHint": "« Prénom » et « Nom » sont obligatoires. Laissez « — » pour ignorer une colonne.",
|
||
"config.vol.wiz.ignore": "—",
|
||
"config.vol.wiz.mapMissing": "Associez au moins les colonnes « Prénom » et « Nom ».",
|
||
"config.vol.wiz.simulate": "SIMULER",
|
||
"config.vol.wiz.runImport": "IMPORTER POUR DE VRAI",
|
||
"config.vol.wiz.back": "RETOUR",
|
||
"config.vol.wiz.next": "SUIVANT",
|
||
"config.vol.wiz.dryRunTitle": "SIMULATION — RIEN N'A ÉTÉ ENREGISTRÉ",
|
||
"config.vol.wiz.doneTitle": "IMPORT TERMINÉ",
|
||
"config.vol.wiz.created": "{count} créé(s)",
|
||
"config.vol.wiz.updated": "{count} mis à jour",
|
||
"config.vol.wiz.skipped": "{count} ignoré(s)",
|
||
"config.vol.wiz.rowsWithIssues": "LIGNES AVEC REMARQUES",
|
||
"config.vol.wiz.line": "Ligne {line}",
|
||
"config.vol.wiz.noIssues": "Aucune remarque : tout est prêt à être importé.",
|
||
"config.vol.wiz.close": "FERMER",
|
||
"import.error.empty_file": "Le fichier est vide.",
|
||
"import.error.encoding": "L'encodage du fichier n'est pas reconnu.",
|
||
"import.error.unreadable_file": "Fichier illisible ou format non pris en charge.",
|
||
"import.error.file_too_large": "Le fichier est trop volumineux (5 Mo maximum).",
|
||
"import.error.xlsx_demo_only": "En mode démonstration, l'import Excel n'est pas disponible : exportez votre fichier en CSV.",
|
||
"import.mapping.invalid": "Le paramétrage des colonnes est invalide.",
|
||
"import.mapping.required_field_missing": "Le champ « {field} » doit être associé à une colonne.",
|
||
"import.mapping.column_not_found": "La colonne « {column} » est absente du fichier.",
|
||
"import.row.missing_required_field": "Champ obligatoire manquant : {field}.",
|
||
"import.row.invalid_email": "Adresse email invalide : {value}.",
|
||
"import.row.duplicate_email_in_file": "Email déjà présent à la ligne {first_line} du fichier.",
|
||
"import.row.duplicate_name_in_file": "Nom et prénom déjà présents à la ligne {first_line} du fichier.",
|
||
"import.row.updated_existing": "Bénévole existant mis à jour.",
|
||
"import.row.possible_duplicate_name": "Un bénévole portant le même nom existe déjà dans l’édition.",
|
||
"config.tab.artists": "PROGRAMMATION",
|
||
"config.artists.title": "PROGRAMMATION",
|
||
"config.artists.hint": "La liste des artistes de l'édition, jour par jour. Les bénévoles y choisissent ceux qu'ils veulent voir depuis leur fiche.",
|
||
"config.artists.count": "ARTISTES",
|
||
"config.artists.empty": "Aucun artiste ce jour.",
|
||
"config.artists.outside": "hors dates",
|
||
"config.artists.namePlaceholder": "Nom de l'artiste",
|
||
"config.vol.field.artists": "Artistes à voir",
|
||
"config.vol.field.positions": "Postes souhaités",
|
||
"config.vol.noArtists": "Aucun artiste choisi",
|
||
"config.vol.noPositions": "Aucun poste choisi",
|
||
"config.vol.pickArtist": "Ajouter un artiste…",
|
||
"config.vol.pickPosition": "Ajouter un poste…",
|
||
"config.vol.colWishes": "VŒUX",
|
||
"config.vol.wishesCount": "{count} vœu(x)",
|
||
"config.vol.addAvailabilityHint": "Les disponibilités se renseignent sur la fiche du bénévole, une fois celui-ci créé.",
|
||
"config.vol.avail.title": "Disponibilités",
|
||
"config.vol.avail.hint": "Plages horaires où le bénévole peut venir. Une heure de fin ≤ début signifie que la plage se termine le lendemain.",
|
||
"config.vol.avail.none": "Aucune disponibilité déclarée",
|
||
"config.vol.avail.add": "Ajouter une plage",
|
||
"config.vol.avail.save": "Enregistrer les disponibilités",
|
||
"grille.panel.coverage.full": "Disponible",
|
||
"grille.panel.coverage.partial": "Partiellement dispo",
|
||
"grille.panel.coverage.none": "Dispo non déclarée",
|
||
"availability.date_outside_edition": "Cette date est hors des dates de l'édition.",
|
||
"availability.empty_window": "Une plage doit avoir un début et une fin différents.",
|
||
"grille.solver.run": "SUGGESTIONS (SOLVEUR)",
|
||
"grille.solver.running": "CALCUL EN COURS…",
|
||
"grille.solver.result": "{count} suggestion(s)",
|
||
"grille.panel.suggested": "Suggéré"
|
||
}
|