// Text helpers shared by the views: money, durations, effects and rewards. import { t } from '../services/i18n.js'; /** Money in the theme's currency, e.g. "12.50 GAL". */ export const moneyFormatter = (fmt) => (n) => t('theme.fmt.funds', { value: fmt.money(n) }); export function formatDuration(seconds) { const total = Math.max(0, Math.round(seconds)); const minutes = Math.floor(total / 60); if (minutes < 1) return t('time.seconds', { value: total }); if (minutes < 60) return t('time.minutes', { value: minutes }); return t('time.hoursMinutes', { hours: Math.floor(minutes / 60), minutes: minutes % 60 }); } /** "×1.5 production", "-20% generator cost"... from an effect object. */ export function effectText(effect, fmt) { const params = { value: fmt.number(effect.value) }; if (effect.target) params.target = t(`theme.gen.${effect.target}.name`); if (effect.type === 'batch_discount' || effect.type === 'generator_cost_mult') { params.percent = fmt.number(Math.round((1 - effect.value) * 100)); } if (effect.type === 'reliability_add' || effect.type === 'offline_add') { params.percent = fmt.number(Math.round(effect.value * 100)); } if (effect.type === 'start_funds') params.funds = moneyFormatter(fmt)(effect.value); return t(`effect.${effect.type}`, params); } /** What a contract pays, e.g. "Reward: 1.2M GAL". */ export function rewardText(reward, fmt, seconds = 0) { const money = moneyFormatter(fmt); switch (reward.type) { case 'funds': return t('contracts.reward.funds', { amount: money(reward.amount) }); case 'boost': return t('contracts.reward.boost', { value: fmt.number(reward.amount), duration: formatDuration(seconds) }); default: // research, chips return t(`contracts.reward.${reward.type}`, { amount: fmt.number(reward.amount) }); } } export function setText(node, text) { if (node.textContent !== text) node.textContent = text; } /** "+3.2%" / "-1.0%" */ export function signedPercent(fraction, fmt) { const sign = fraction > 0 ? '+' : ''; return `${sign}${fmt.number(Math.round(fraction * 1000) / 10)}%`; }