gestion_table_tournante_libre/src/application/libelles/generation.js

115 lines
5.2 KiB
JavaScript
Raw Normal View History

// © 2026 TechnoLibre (http://www.technolibre.ca)
// License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl)
// Les textes des commandes de la génération et des propositions (§ 5.7,
2026-10-07 06:09:45 -04:00
// § 14.6) : refus et libellés figés, puis les refus du contrôleur de
// génération et de la saisie de ses réglages (§ 5.9, § 5.10, § 15.4). Cette
// table ne porte que des codes. Un nombre et une durée se mettent en forme
// par creerFormat, sur la composition que la traduction passe à l'entrée.
import { creerFormat } from '../format.js';
import { cite, compte, phraseDeRaison } from './aides.js';
// Le nom de chaque réglage de génération, celui que la saisie affiche.
const NOMS_DES_REGLAGES = new Map([
['graine', 'Graine'],
['nombre', 'Propositions par génération'],
['arret', 'Mouvements par proposition'],
['historique', "Historique d'acceptation"],
]);
// Les cœurs d'un calcul, dits quand il en emploie plus d'un : « , sur
// 4 cœurs » ; rien pour un seul, ou quand le nombre n'est pas donné.
function surCoeurs(coeurs, texte) {
return typeof coeurs === 'number' && coeurs > 1 ? `, sur ${creerFormat(texte).nombre(coeurs)} cœurs` : '';
}
// L'estimation d'une génération longue, en mots : l'ordre de grandeur et les
// cœurs qu'elle emploierait, puis la mesure dont il vient ; ou le seuil d'une
// génération sans mesure.
2026-10-07 06:09:45 -04:00
function phraseEstimation(estimation, texte) {
if (estimation.inconnue === true) {
return (
"Aucune durée n'est encore mesurée sur ce poste dans cette séance, et ce réglage demande plus de " +
'dix fois le réglage par défaut'
);
}
const format = creerFormat(texte);
const { mesure } = estimation;
const plafond = estimation.auDelaDuPlafond ? ", au-delà du plafond d'usage de trente minutes" : '';
return (
`Ce réglage prendrait ${format.ordreDeGrandeur(estimation.secondes)}${surCoeurs(estimation.coeurs, texte)}` +
`${plafond}, d'après le dernier calcul, ` +
2026-10-07 06:09:45 -04:00
`${format.duree(mesure.dureeMs)} pour ${format.nombre(mesure.mouvements)} mouvements ` +
`sur ${compte(mesure.participants, 'participant', 'participants')}${surCoeurs(mesure.coeurs, texte)}`
2026-10-07 06:09:45 -04:00
);
}
export const TABLE = new Map([
// --- Les refus des propositions (§ 5.7) ------------------------------------
['PROPOSITION_INCONNUE', ({ id }) => `La proposition n° ${id} n'est pas dans cet événement.`],
// --- Les libellés figés du journal (§ 8.2, § 8.3) --------------------------
[
'ENTREE_ENREGISTRER_GENERATION',
({ n, premier, dernier }) =>
`Généré ${compte(n, 'proposition', 'propositions')} ` +
`(n° ${premier === dernier ? premier : `${premier} à ${dernier}`})`,
],
['ENTREE_RETENIR_PROPOSITION', ({ id }) => `Retenu la proposition n° ${id}`],
[
'ENTREE_EFFACER_PROPOSITIONS',
({ n, gardee }) =>
`Effacé ${compte(n, 'proposition', 'propositions')}` +
`${gardee === null || gardee === undefined ? '' : `, gardé la retenue (n° ${gardee})`}`,
],
2026-10-07 06:09:45 -04:00
// --- Le contrôleur de génération (§ 5.9, § 5.10, § 15.4) -------------------
['GENERATION_EN_COURS', () => "Une génération est déjà en cours : l'annuler, ou attendre qu'elle s'achève."],
[
'AUCUN_PARTICIPANT',
() => "Aucune personne à placer : la liste des participants est vide, ou chacun en est exclu.",
],
['AUCUNE_TABLE', () => "Aucune table : la génération place les personnes autour des tables de l'événement."],
// Le travailleur de génération n'a pas démarré, ou s'est arrêté sans
// résultat : rien n'est enregistré, et aucun geste de la page ne le relance.
[
'TRAVAILLEUR_EN_ECHEC',
() =>
"Le calcul hors de la page n'a pas pu se faire : le navigateur n'a pas démarré le travailleur de génération, " +
"ou l'a arrêté sans résultat. Rien n'est enregistré ; relancer le logiciel le recharge.",
],
2026-10-07 06:09:45 -04:00
[
'CONFIRMATION_REQUISE',
({ estimation }, texte) =>
`${phraseEstimation(estimation, texte)}. Confirmer « Générer » lance quand même la génération.`,
],
[
'REGLAGE_HORS_DOMAINE',
({ reglage }) =>
`Le réglage ${cite(NOMS_DES_REGLAGES.get(reglage) ?? String(reglage))} sort de son domaine : ` +
"la génération n'a pas eu lieu.",
],
// rang : la place du placement dans la suite des graines du lancement,
// jamais un numéro de proposition, puisque rien n'est enregistré ; chaque
// violation se dit par le texte de son code (libelles/moteur.js).
[
'GENERATION_INVARIANT_VIOLE',
({ rang, violations }, texte) =>
`Le placement que la génération a rendu au rang ${rang} de ce lancement enfreint ` +
`${compte(violations.length, 'règle', 'règles')} ; rien n'est enregistré. ` +
violations.map((violation) => phraseDeRaison(violation.code, violation, texte)).join(' '),
],
// --- La saisie des réglages (§ 5.7) -----------------------------------------
// max null : le domaine n'a pas de borne supérieure.
[
'HORS_DOMAINE',
({ min, max }, texte) => {
const { nombre } = creerFormat(texte);
return max === null || max === undefined
? `La valeur doit être d'au moins ${nombre(min)}.`
: `La valeur doit être comprise entre ${nombre(min)} et ${nombre(max)}.`;
},
],
]);