SPB Git

spb/qc26

Public
3.6 KB · 61 lines typescript
1/** Registre des partis côté web — miroir du registre du moteur (engine/qc26/parties.py).2 * Toute couleur ou logo de parti passe par ici : aucun code hex dans les composants. */3import type { PartyId, PartyKey } from "./api";45export interface PartyDef {6  id: PartyId;7  abbreviation: string;8  officialName: string;9  shortName: string;10  color: string;11  secondaryColor: string;12  website: string;13  logo: string;14  logoWhite?: string;15  /** Le logo officiel est blanc : afficher sur une pastille de cette couleur. */16  logoBackdrop?: string;17  logoRatio: number; // largeur / hauteur18  order: number;19}2021export const PARTIES: PartyDef[] = [22  { id: "caq", abbreviation: "CAQ", officialName: "Coalition avenir Québec", shortName: "CAQ", color: "#20A8E0", secondaryColor: "#0B6FA6", website: "https://coalitionavenirquebec.org", logo: "/parties/caq/logo.png", logoWhite: "/parties/caq/logo-white.png", logoRatio: 2560 / 1134, order: 1 },23  { id: "plq", abbreviation: "PLQ", officialName: "Parti libéral du Québec", shortName: "PLQ", color: "#ED1B2D", secondaryColor: "#007AC2", website: "https://plq.org", logo: "/parties/plq/logo.svg", logoWhite: "/parties/plq/logo-white.svg", logoRatio: 516.1 / 278.3, order: 2 },24  { id: "pq", abbreviation: "PQ", officialName: "Parti québécois", shortName: "PQ", color: "#1E295C", secondaryColor: "#4C5B9E", website: "https://pq.org", logo: "/parties/pq/logo.svg", logoWhite: "/parties/pq/wordmark-white.png", logoRatio: 180 / 45, order: 3 },25  { id: "qs", abbreviation: "QS", officialName: "Québec solidaire", shortName: "QS", color: "#FF5505", secondaryColor: "#FFF0A8", website: "https://quebecsolidaire.net", logo: "/parties/qs/logo.svg", logoRatio: 720 / 300, order: 4 },26  { id: "pcq", abbreviation: "PCQ", officialName: "Parti conservateur du Québec", shortName: "PCQ", color: "#6E4C9F", secondaryColor: "#102850", website: "https://conservateur.quebec", logo: "/parties/pcq/logo.svg", logoBackdrop: "#102850", logoRatio: 324 / 79, order: 5 },27];2829export const OTHERS = { id: "aut" as const, abbreviation: "Autres", officialName: "Autres candidatures", color: "#9AA0A6" };30export const PARTY_IDS: PartyId[] = PARTIES.map((p) => p.id);31export const PARTY_BY_ID: Record<string, PartyDef> = Object.fromEntries(PARTIES.map((p) => [p.id, p]));3233export function party(id: string | null | undefined): PartyDef | null {34  return id ? PARTY_BY_ID[id] ?? null : null;35}36export function partyColor(id: string | null | undefined): string {37  if (!id) return "#C4C8CE";38  return PARTY_BY_ID[id]?.color ?? OTHERS.color;39}40export function partyLabel(id: string | null | undefined): string {41  if (!id) return "—";42  return PARTY_BY_ID[id]?.abbreviation ?? OTHERS.abbreviation;43}44export function partyName(id: string | null | undefined): string {45  if (!id) return "—";46  return PARTY_BY_ID[id]?.officialName ?? OTHERS.officialName;47}48/** Ordonne des identifiants de partis par une valeur décroissante. */49export function sortParties<T>(rec: Record<string, T>, key: (v: T) => number, includeOthers = false): [PartyKey, T][] {50  return (Object.entries(rec) as [PartyKey, T][])51    .filter(([id]) => includeOthers || id !== "aut")52    .sort((a, b) => key(b[1]) - key(a[1]));53}54/** Couleur atténuée par une probabilité (incertitude → moins d'opacité). */55export function withAlpha(hex: string, alpha: number): string {56  const h = hex.replace("#", "");57  const n = parseInt(h.length === 3 ? h.split("").map((c) => c + c).join("") : h, 16);58  const r = (n >> 16) & 255, g = (n >> 8) & 255, b = n & 255;59  return `rgba(${r}, ${g}, ${b}, ${Math.max(0, Math.min(1, alpha)).toFixed(3)})`;60}61
Files · f3bb07025804f73080c3fe80ab3c20f6aeea6682
Menu

Theme