/* Margin Money Debt Payoff Calculator v2: page shell + calculator */
(function () {
var script = document.currentScript;
var part = (script && script.getAttribute('data-part')) || 'bottom';
var holder = document.createElement('div');
if (script && script.parentNode) script.parentNode.insertBefore(holder, script); else document.body.appendChild(holder);
if (!window.__mmDpcShell) {
window.__mmDpcShell = fetch('/resources', { credentials: 'same-origin' }).then(function (r) { return r.text(); }).then(function (html) {
var d = new DOMParser().parseFromString(html, 'text/html');
var cc = d.querySelector('.custom-code-container') || d;
var styles = Array.prototype.map.call(cc.querySelectorAll('link[rel=stylesheet],link[rel=preconnect],style'), function (e) { return e.outerHTML; }).join('');
var header = cc.querySelector('.mm-header');
if (header) header.querySelectorAll('[aria-current]').forEach(function (a) { a.removeAttribute('aria-current'); });
var skip = cc.querySelector('.mm-skip');
var footer = cc.querySelector('footer.mm-f');
return { styles: styles, header: header ? header.outerHTML : '', skip: skip ? skip.outerHTML : '', footer: footer ? footer.outerHTML : '' };
}).catch(function () { return { styles: '', header: '', skip: '', footer: '' }; });
}
var hero = '
' +
'
Free debt payoff calculator
' +
'
See the month your last debt is paid off.
' +
'
Do you ever wonder when the payments will finally stop? List your debts, choose the snowball or avalanche method, and see your payoff order, the month each debt is gone, and how much money you get back as each one clears. When you are done, you can print your plan or save it as a PDF.
';
return;
}
/* hide the email form and hero button once unlocked */
function hideGate() {
var anchor = document.getElementById('get-calculator');
if (anchor) anchor.style.display = 'none';
document.querySelectorAll('.c-form').forEach(function (f) { f.style.display = 'none'; });
document.querySelectorAll('a[href="#get-calculator"]').forEach(function (a) { a.setAttribute('href', '#calculator'); a.textContent = 'Go to the calculator'; });
}
hideGate(); setTimeout(hideGate, 800); setTimeout(hideGate, 2500);
/* ---------- render ---------- */
mount.innerHTML =
'
' +
'
Margin Money Debt Payoff Plan
' +
'
' +
'
Debt Payoff Calculator
' +
'
List each debt with its balance, interest rate, and minimum payment. Your numbers stay on this device and are not sent to us.
' +
'' +
'' +
'
' +
'
$
Money on top of your minimum payments.
' +
'' +
'
' +
'
Payoff method
' +
'' +
'
' +
'
' +
'' +
'
';
var debtsEl = document.getElementById('dpc-debts');
var extraEl = document.getElementById('dpc-extra');
var startEl = document.getElementById('dpc-start');
var outEl = document.getElementById('dpc-out');
extraEl.value = state.extra; startEl.value = state.start;
function renderDebts() {
debtsEl.innerHTML = state.debts.map(function (d, i) {
var n = i + 1;
return '
' +
'' +
'
$
' +
'
%
' +
'
$
' +
'' +
'
';
}).join('');
}
function setMethodButtons() {
document.querySelectorAll('.dpc-toggle button').forEach(function (b) { b.setAttribute('aria-pressed', b.getAttribute('data-m') === state.method ? 'true' : 'false'); });
}
var lastResult = null;
function compute() {
var debts = [], issues = [];
state.debts.forEach(function (d, i) {
var b = num(d.balance), r = num(d.rate), m = num(d.min), name = (d.name || '').trim() || ('Debt ' + (i + 1));
if (!b && !m && !(d.name || '').trim()) return;
if (b <= 0) { issues.push(name + ' needs a balance.'); return; }
if (m <= 0) { issues.push(name + ' needs a minimum payment.'); return; }
if (r < 0 || r > 100) { issues.push(name + ' needs an interest rate between 0 and 100.'); return; }
debts.push({ name: name, balance: b, rate: r, min: m });
});
var extra = Math.max(0, num(state.extra));
var sm = (state.start || '').split('-'), sy = parseInt(sm[0], 10), smo = parseInt(sm[1], 10) - 1;
if (!(sy > 1900) || !(smo >= 0)) { sy = now.getFullYear(); smo = now.getMonth(); }
if (!debts.length) {
outEl.innerHTML = '
Add at least one debt with a balance and a minimum payment to see your plan.
' + (issues.length ? '
' + issues.map(esc).join(' ') + '
' : '') + '
';
lastResult = null; return;
}
var snow = simulate(debts, extra, 'snowball');
var aval = simulate(debts, extra, 'avalanche');
var res = state.method === 'avalanche' ? aval : snow;
lastResult = { res: res, debts: debts, sy: sy, smo: smo, extra: extra };
function endLabel(r) { var e = addMonths(sy, smo, r.months - 1); return monthLabel(e[0], e[1]); }
function planCard(r, key, title, desc) {
var on = state.method === key;
return '
The minimum on ' + esc(d.name) + ' does not cover its monthly interest of ' + money2(d.balance * d.rate / 1200) + ', so it only shrinks once extra money reaches it.
';
});
if (issues.length) warn += '
Skipped: ' + issues.map(esc).join(' ') + '
';
var diff = Math.round(snow.totalInterest - aval.totalInterest);
var cmp = diff > 0 ? 'Avalanche saves about ' + money(diff) + ' in interest. Snowball pays off your first debt sooner, which keeps many people motivated.' :
(diff < 0 ? 'Snowball costs about ' + money(-diff) + ' less in interest with these numbers.' : 'Both methods cost about the same in interest with these numbers.');
var running = 0;
var orderHtml = res.payoff.map(function (d) {
running += d.min;
var e = addMonths(sy, smo, d.paidMonth - 1);
return '
';
}).join('');
var firstFree = res.payoff.length ? res.payoff[0] : null;
var ff = firstFree ? addMonths(sy, smo, firstFree.paidMonth - 1) : null;
var stl = monthLabel(sy, smo);
var printDebts = '
Your debts
Debt
Balance
Interest rate
Minimum payment
' +
debts.map(function (d) { return '
' + esc(d.name) + '
' + money2(d.balance) + '
' + d.rate + '%
' + money2(d.min) + '
'; }).join('') +
'
Extra each month: ' + money2(extra) + '. First payment month: ' + stl + '.
';
outEl.innerHTML = printDebts +
'
Your two options
' + warn +
'
' +
planCard(snow, 'snowball', 'Snowball', 'Smallest balance first. Quick wins you can see.') +
planCard(aval, 'avalanche', 'Avalanche', 'Highest interest rate first. Usually the least interest.') +
'
' + cmp + '
' +
'
Your payoff order (' + (state.method === 'avalanche' ? 'avalanche' : 'snowball') + ')
' +
'
You put ' + money(res.budget) + ' toward debt every month: your minimums plus ' + money(extra) + ' extra. When a debt is paid off, its payment rolls into the next one, so your monthly amount stays the same while the debts disappear faster.
' +
(firstFree ? '
Your first debt is gone in ' + monthLabel(ff[0], ff[1]) + '. When the last one clears, ' + money(res.budget) + ' a month is margin you get back.
' : '') +
'' + orderHtml + '' +
(res.stuck ? '
With these numbers some debt is still left after 50 years. Try adding a little extra each month.
' : '') +
'
' +
'
Month by month
' +
'
' +
'' +
'
Monthly payments and balances for each debt
' +
heads.map(function (h, i) { return '
' + esc(h) + '
'; }).join('') + '
' + body + '
' +
'
This calculator is for education and planning. It assumes fixed interest rates charged monthly, no new charges, and payments made every month, so your real numbers will vary a little. It is not financial advice.