const cache = {} function nf(lang, opts) { const key = lang + JSON.stringify(opts) // 'always' groups 4-digit amounts too (pt-PT would otherwise print 9888,00 but 19 888,00) if (!cache[key]) cache[key] = new Intl.NumberFormat(lang === 'en' ? 'en-IE' : 'pt-PT', { useGrouping: 'always', ...opts }) return cache[key] } export const eur = (v, lang, digits = 2) => v == null ? '—' : nf(lang, { style: 'currency', currency: 'EUR', minimumFractionDigits: digits, maximumFractionDigits: digits }).format(v) export const num = (v, lang, digits = 2) => v == null ? '—' : nf(lang, { minimumFractionDigits: digits, maximumFractionDigits: digits }).format(v) export const pct = (v, lang) => v == null ? '—' : (v > 0 ? '+' : '') + nf(lang, { minimumFractionDigits: 2, maximumFractionDigits: 2 }).format(v) + '%' export const signedEur = (v, lang) => (v == null ? '—' : (v > 0 ? '+' : '') + eur(v, lang)) export const dateTime = (iso, lang) => iso ? new Date(iso).toLocaleString(lang === 'en' ? 'en-GB' : 'pt-PT', { dateStyle: 'short', timeStyle: 'short' }) : '' // Shows a stored expression in the user's decimal style: "839.67*12" -> "839,67*12" in Portuguese. export const exprForDisplay = (expr, lang) => (lang === 'pt' ? String(expr ?? '').replace(/\./g, ',') : String(expr ?? ''))