/* Indonesian number formatting shared by the calculator and admin pages. */ (function (root) { 'use strict'; var nf0 = new Intl.NumberFormat('id-ID', { maximumFractionDigits: 0 }); var nf2 = new Intl.NumberFormat('id-ID', { minimumFractionDigits: 2, maximumFractionDigits: 2 }); var nfp = new Intl.NumberFormat('id-ID', { minimumFractionDigits: 0, maximumFractionDigits: 4 }); var F = { /** 1234567.8 -> "Rp1.234.568" */ rp: function (x) { var v = Math.round(Number(x) || 0); return (v < 0 ? '−Rp' : 'Rp') + nf0.format(Math.abs(v)); }, /** 0.027 -> "2,70%" */ pct: function (x) { return nf2.format((Number(x) || 0) * 100) + '%'; }, /** 0.0075 -> "0,75" (for inputs) */ pctInput: function (x) { return nfp.format((Number(x) || 0) * 100); }, num: function (x) { return nf0.format(Math.round(Number(x) || 0)); }, /** "55.000.000" -> 55000000 */ parseIdr: function (s) { var d = String(s == null ? '' : s).replace(/[^0-9]/g, ''); return d === '' ? null : Number(d); }, /** "0,75" / "0.75" -> 0.0075; "" -> null; invalid -> NaN */ parsePct: function (s) { var t = String(s == null ? '' : s).replace(/[\s%]/g, '').replace(',', '.'); if (t === '') return null; if (!/^-?\d+(\.\d+)?$/.test(t)) return NaN; return Math.round(parseFloat(t) * 1e6) / 1e8; }, /** 50000000 -> "50 jt", 2e9 -> "2 M" */ short: function (x) { var v = Number(x) || 0; if (v >= 1e12) return nfp.format(v / 1e12) + ' T'; if (v >= 1e9) return nfp.format(v / 1e9) + ' M'; if (v >= 1e6) return nfp.format(v / 1e6) + ' jt'; return nf0.format(v); }, /** Keeps the caret position stable while re-formatting a thousands-separated input. */ liveFormatIdr: function (input) { var before = input.value; var caret = input.selectionStart == null ? before.length : input.selectionStart; var digitsBefore = before.slice(0, caret).replace(/[^0-9]/g, '').length; var n = F.parseIdr(before); var after = n === null ? '' : nf0.format(n); input.value = after; var pos = 0, seen = 0; while (pos < after.length && seen < digitsBefore) { if (/[0-9]/.test(after[pos])) seen++; pos++; } try { input.setSelectionRange(pos, pos); } catch (e) { /* not focusable */ } return n; } }; root.SerubiFormat = F; })(window);