TypeScript 50.6%
JavaScript 46.1%
SQL 2.1%
Shell 0.6%
CSS 0.5%
1// Formats fr-CA : prix CAD, pi²/m², dates, pourcentages.2const cad0 = new Intl.NumberFormat("fr-CA", { style: "currency", currency: "CAD", maximumFractionDigits: 0 });3const int = new Intl.NumberFormat("fr-CA", { maximumFractionDigits: 0 });4const dec1 = new Intl.NumberFormat("fr-CA", { maximumFractionDigits: 1, minimumFractionDigits: 0 });56export function fmtPrice(v: number | null | undefined, opts?: { rent?: boolean; compact?: boolean }): string {7 if (v == null || !Number.isFinite(v)) return "—";8 if (opts?.compact) {9 if (v >= 1_000_000) return `${dec1.format(v / 1_000_000).replace(",0", "")} M$`;10 if (v >= 1_000) return `${int.format(Math.round(v / 1000))} k$`;11 }12 const s = cad0.format(v);13 return opts?.rent ? `${s}/mois` : s;14}15export function fmtInt(v: number | null | undefined): string { return v == null || !Number.isFinite(v) ? "—" : int.format(v); }16export function fmtPct(v: number | null | undefined, digits = 1, signed = true): string {17 if (v == null || !Number.isFinite(v)) return "—";18 const s = new Intl.NumberFormat("fr-CA", { maximumFractionDigits: digits, minimumFractionDigits: 0 }).format(Math.abs(v) * 100);19 return `${signed ? (v > 0 ? "+" : v < 0 ? "−" : "") : ""}${s} %`;20}21export function fmtArea(sqft: number | null | undefined, unit: "sqft" | "m2" = "sqft"): string {22 if (sqft == null || !Number.isFinite(sqft) || sqft <= 0) return "—";23 return unit === "m2" ? `${int.format(Math.round(sqft * 0.09290304))} m²` : `${int.format(Math.round(sqft))} pi²`;24}25export function fmtDate(iso: string | null | undefined, style: "short" | "long" = "short"): string {26 if (!iso) return "—";27 const d = new Date(iso);28 if (Number.isNaN(d.getTime())) return "—";29 return d.toLocaleDateString("fr-CA", style === "long" ? { day: "numeric", month: "long", year: "numeric" } : { day: "numeric", month: "short", year: "numeric" });30}31export function daysSince(iso: string | null | undefined): number | null {32 if (!iso) return null; const t = Date.parse(iso); return Number.isNaN(t) ? null : Math.max(0, Math.floor((Date.now() - t) / 86400000));33}34export function fmtRooms(bed: number | null | undefined, bath: number | null | undefined): string {35 const p: string[] = [];36 if (bed != null) p.push(`${dec1.format(bed)} ch.`);37 if (bath != null) p.push(`${dec1.format(bath)} sdb`);38 return p.join(" · ");39}40export function slugify(s: string): string {41 return s.normalize("NFD").replace(/[̀-ͯ]/g, "").toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-|-$/g, "");42}43export function pluralize(n: number, one: string, many: string): string { return `${fmtInt(n)} ${n > 1 ? many : one}`; }44