import { i18n, t, type Key } from './i18n/index.svelte'; import type { Inertia, Proposal, Unit } from './types'; /** « 3 / 5 · moyenne ». */ export function inertiaLevel(k: Inertia): string { return t('inertia.level', { k, name: t(`inertia.name.${k}`) }); } /** « inertie 3 / 5 · moyenne ». */ export function inertiaBadge(k: Inertia): string { return t('inertia.badge', { level: inertiaLevel(k) }); } const SECTIONS = ['introduction', 'fondamental', 'technique', 'conclusion', 'annexe', 'formule', 'inertie', 'ordonnancement']; /** The name of a section of the seed, or null. */ export function sectionLabel(s: string | null | undefined): string | null { return s && SECTIONS.includes(s) ? t(`section.${s}` as Key) : null; } /** * The sections whose articles carry the title already (Yvv, 2026-11-03: « Enlève les titres * Introduction et Engagements fondamentaux, les titres sont déjà dans les contenus à voter. Ça * embrouille. »): not named again where the text is read. They keep their name elsewhere — the * order of the section, the basket, the open proposals. */ const TITLED_BY_THEIR_ARTICLES = ['introduction', 'fondamental']; /** The name of a section where the text is read, or null. */ export function readerSectionLabel(s: string | null | undefined): string | null { return s && TITLED_BY_THEIR_ARTICLES.includes(s) ? null : sectionLabel(s); } /** The name of a module (ADR 0009): « Titre du document », « Ordre des articles · Conclusion ». */ export function moduleName(unit: Unit): string { if (unit.kind === 'title') return t('module.title.name'); const section = sectionLabel(unit.section) ?? unit.section; return section ? t('module.order.named', { section }) : t('module.order.name'); } /** What a proposal is, in words, whatever its kind. */ export function titleOf(p: Proposal, unit: Unit | undefined): string { if (p.kind === 'inertia' && p.inertiaTarget) { return t('deep.inertia', { level: inertiaLevel(p.inertiaTarget) }); } if (p.kind === 'remove') return t('deep.removal', { title: unit?.inForce?.title ?? p.title }); if (p.kind === 'order') return unit ? moduleName(unit) : t('module.order.name'); return p.title; } /** Its relation to the text in force. */ export function relationOf(p: Proposal, unit: Unit | undefined): string { if (p.kind !== 'text' && p.kind !== 'title') return ''; if (unit?.inForce && unit.inForce.id !== p.id) return t('deep.rival', { title: unit.inForce.title }); return ''; } /** What an order version says of itself: completed at the end, or the order in force already. */ export function orderNote(p: Proposal): string[] { const o = p.order; if (!o || p.status === 'in_force') return []; const notes: string[] = []; if (o.added.length) notes.push(i18n.plural('module.order.added', o.added.length)); if (o.dropped.length) notes.push(i18n.plural('module.order.dropped', o.dropped.length)); if (o.same) notes.push(t('module.order.same')); return notes; } /** * How many « oui » pass a version, how many « non » block it (Yvv, 2026-11-02: « combien il * faut de oui pour passer et combien de non pour maintenir l'opposition »), from what the * server says (ADR 0013): `yesNeeded`, the total of *for* that passes with the *against* cast * now; `noNeeded`, the total of *against* that holds the *for* cast now in check — 0 when * the quorum holds them alone. Before any vote: « 9 oui sur 12 votants ». The quorum goes * to the tooltip (`title`), never to the title of a line. */ export function needOf(p: Proposal): { long: string; short: string; title: string } | null { const e = p.evaluation; if (!e || e.yesNeeded === undefined || e.noNeeded === undefined || e.quorum === undefined) return null; const yes = e.yesNeeded; const no = e.noNeeded; const quorum = e.quorum; const title = i18n.plural('vote.need.title', quorum); if (e.cast === 0) { return { long: i18n.plural('vote.need.first', quorum, { yes, quorum }), short: t('vote.need.short.first', { yes, quorum }), title }; } if (no === 0) return { long: t('vote.need.quorum', { yes }), short: t('vote.need.short.quorum', { yes }), title }; return { long: t('vote.need', { yes, no }), short: t('vote.need.short', { yes, no }), title }; }