calcsuite-react 1.1.2 → 1.1.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +9 -0
- package/dist/calcsuite.js +617 -617
- package/dist/ui/icons.d.ts +1 -0
- package/package.json +1 -1
- package/src/theme.css +11 -10
package/dist/calcsuite.js
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
var
|
|
2
|
-
var
|
|
3
|
-
var ge = (e, t, n) =>
|
|
1
|
+
var fa = Object.defineProperty;
|
|
2
|
+
var ya = (e, t, n) => t in e ? fa(e, t, { enumerable: !0, configurable: !0, writable: !0, value: n }) : e[t] = n;
|
|
3
|
+
var ge = (e, t, n) => ya(e, typeof t != "symbol" ? t + "" : t, n);
|
|
4
4
|
import { jsx as o, jsxs as b, Fragment as re } from "react/jsx-runtime";
|
|
5
|
-
import { useState as M, useCallback as ke, useMemo as X, useContext as
|
|
5
|
+
import { useState as M, useCallback as ke, useMemo as X, useContext as ba, createContext as ga, useRef as de, useEffect as Q, Fragment as xn, useSyncExternalStore as va } from "react";
|
|
6
6
|
import mt from "decimal.js";
|
|
7
|
-
const
|
|
7
|
+
const ka = {
|
|
8
8
|
money: 2,
|
|
9
9
|
rate: 6,
|
|
10
10
|
period: 4,
|
|
@@ -13,7 +13,7 @@ const ga = {
|
|
|
13
13
|
instalment: "none",
|
|
14
14
|
residualAbsorption: "last"
|
|
15
15
|
}, qt = {
|
|
16
|
-
rounding:
|
|
16
|
+
rounding: ka,
|
|
17
17
|
ui: {
|
|
18
18
|
theme: "system",
|
|
19
19
|
accent: "#078DEE",
|
|
@@ -68,13 +68,13 @@ function xt(e) {
|
|
|
68
68
|
defaults: { tenureUnit: "both", rateType: "floating", maxRatePercent: 50, sipReturnPercent: "12", inflationPercent: "6" }
|
|
69
69
|
};
|
|
70
70
|
}
|
|
71
|
-
const
|
|
71
|
+
const Qe = xt("IN"), H = mt.clone({
|
|
72
72
|
precision: 40,
|
|
73
73
|
rounding: mt.ROUND_HALF_UP,
|
|
74
74
|
toExpPos: 60,
|
|
75
75
|
toExpNeg: -60,
|
|
76
76
|
modulo: mt.ROUND_DOWN
|
|
77
|
-
}), g = (e) => new H(e),
|
|
77
|
+
}), g = (e) => new H(e), ms = (e, t) => g(e).eq(t), ps = (e, t) => g(e).gt(t), hs = (e, t) => g(e).lt(t), ce = (e, t = "1e-9") => e.abs().lt(t), wa = {
|
|
78
78
|
HALF_UP: H.ROUND_HALF_UP,
|
|
79
79
|
HALF_EVEN: H.ROUND_HALF_EVEN,
|
|
80
80
|
HALF_DOWN: H.ROUND_HALF_DOWN,
|
|
@@ -83,7 +83,7 @@ const Xe = xt("IN"), H = mt.clone({
|
|
|
83
83
|
CEIL: H.ROUND_CEIL,
|
|
84
84
|
FLOOR: H.ROUND_FLOOR
|
|
85
85
|
};
|
|
86
|
-
function
|
|
86
|
+
function Na(e) {
|
|
87
87
|
switch (e.numberFormat.grouping) {
|
|
88
88
|
case "indian":
|
|
89
89
|
return "en-IN";
|
|
@@ -98,7 +98,7 @@ function ka(e) {
|
|
|
98
98
|
}
|
|
99
99
|
}
|
|
100
100
|
function Sn(e) {
|
|
101
|
-
const t =
|
|
101
|
+
const t = wa[e.rounding.mode], n = (l, p = e.numberFormat.decimalPlaces) => g(l).toDecimalPlaces(p, t), a = (l, p) => e.numberFormat.grouping === "plain" ? l.toFixed(p) : new Intl.NumberFormat(Na(e), {
|
|
102
102
|
minimumFractionDigits: e.numberFormat.trimTrailingZeros ? 0 : p,
|
|
103
103
|
maximumFractionDigits: p
|
|
104
104
|
}).format(l), r = (l, p) => l ? e.numberFormat.negativeFormat === "parentheses" ? `(${p})` : `-${p}` : p, s = (l) => {
|
|
@@ -126,54 +126,54 @@ function pt(e) {
|
|
|
126
126
|
const t = Math.floor(e / 12), n = e % 12, a = [];
|
|
127
127
|
return t && a.push(`${t} yr`), n && a.push(`${n} mo`), a.join(" ") || "0 mo";
|
|
128
128
|
}
|
|
129
|
-
const
|
|
129
|
+
const Cn = [
|
|
130
130
|
{ id: "default", label: "Green", main: "#00A76F", light: "#2CCF8E", dark: "#087055", ink: "#06251A" },
|
|
131
131
|
{ id: "cyan", label: "Cyan", main: "#078DEE", light: "#68CDF9", dark: "#0351AB", ink: "#FFFFFF" },
|
|
132
132
|
{ id: "purple", label: "Purple", main: "#7635DC", light: "#B985F4", dark: "#431A9E", ink: "#FFFFFF" },
|
|
133
133
|
{ id: "blue", label: "Blue", main: "#2065D1", light: "#76B0F1", dark: "#103996", ink: "#FFFFFF" },
|
|
134
134
|
{ id: "orange", label: "Orange", main: "#FDA92D", light: "#FED680", dark: "#B66816", ink: "#212B36" },
|
|
135
135
|
{ id: "gray", label: "Gray", main: "#A4AAB3", light: "#CED1D7", dark: "#63686C", ink: "#FFFFFF" }
|
|
136
|
-
],
|
|
137
|
-
{ id: "Inter Tight", label: "Inter Tight", stack: `'Inter Tight', ${
|
|
138
|
-
{ id: "Public Sans", label: "Public Sans", stack: `'Public Sans', ${
|
|
139
|
-
{ id: "system-ui", label: "System UI", stack: `system-ui, ${
|
|
136
|
+
], xa = (e) => Cn.find((t) => t.main.toLowerCase() === e.toLowerCase()), Je = "-apple-system, 'Segoe UI', system-ui, sans-serif", Pn = [
|
|
137
|
+
{ id: "Inter Tight", label: "Inter Tight", stack: `'Inter Tight', ${Je}` },
|
|
138
|
+
{ id: "Public Sans", label: "Public Sans", stack: `'Public Sans', ${Je}` },
|
|
139
|
+
{ id: "system-ui", label: "System UI", stack: `system-ui, ${Je}` },
|
|
140
140
|
{ id: "Georgia", label: "Georgia (serif)", stack: "Georgia, 'Times New Roman', serif" }
|
|
141
|
-
],
|
|
141
|
+
], Sa = (e) => {
|
|
142
142
|
var t;
|
|
143
|
-
return ((t =
|
|
144
|
-
},
|
|
145
|
-
function
|
|
143
|
+
return ((t = Pn.find((n) => n.id === e)) == null ? void 0 : t.stack) ?? `'${e}', ${Je}`;
|
|
144
|
+
}, Tn = ga(null), Fn = "calcsuite:settings";
|
|
145
|
+
function et(e, t) {
|
|
146
146
|
if (t == null) return e;
|
|
147
147
|
const n = Array.isArray(e) ? [...e] : { ...e };
|
|
148
148
|
for (const a of Object.keys(t)) {
|
|
149
149
|
const r = t[a], s = e[a];
|
|
150
|
-
n[a] = r && typeof r == "object" && !Array.isArray(r) && s && typeof s == "object" ?
|
|
150
|
+
n[a] = r && typeof r == "object" && !Array.isArray(r) && s && typeof s == "object" ? et(s, r) : r;
|
|
151
151
|
}
|
|
152
152
|
return n;
|
|
153
153
|
}
|
|
154
|
-
function
|
|
155
|
-
const t = e ? Qe
|
|
154
|
+
function Ca(e) {
|
|
155
|
+
const t = e ? et(Qe, e) : Qe;
|
|
156
156
|
try {
|
|
157
|
-
const n = localStorage.getItem(
|
|
158
|
-
if (n) return
|
|
157
|
+
const n = localStorage.getItem(Fn);
|
|
158
|
+
if (n) return et(t, JSON.parse(n));
|
|
159
159
|
} catch {
|
|
160
160
|
}
|
|
161
161
|
return t;
|
|
162
162
|
}
|
|
163
163
|
function ht(e) {
|
|
164
164
|
try {
|
|
165
|
-
e.persistence.driver === "localStorage" && localStorage.setItem(
|
|
165
|
+
e.persistence.driver === "localStorage" && localStorage.setItem(Fn, JSON.stringify(e));
|
|
166
166
|
} catch {
|
|
167
167
|
}
|
|
168
168
|
}
|
|
169
|
-
function
|
|
169
|
+
function fs({
|
|
170
170
|
children: e,
|
|
171
171
|
settings: t
|
|
172
172
|
}) {
|
|
173
|
-
const [n, a] = M(() =>
|
|
173
|
+
const [n, a] = M(() => Ca(t)), r = ke((h) => {
|
|
174
174
|
a(h), ht(h);
|
|
175
175
|
}, []), s = ke((h) => a((f) => {
|
|
176
|
-
const y =
|
|
176
|
+
const y = et(f, h);
|
|
177
177
|
return ht(y), y;
|
|
178
178
|
}), []), u = ke((h) => {
|
|
179
179
|
a((f) => {
|
|
@@ -188,10 +188,20 @@ function ps({
|
|
|
188
188
|
() => ({ settings: n, fmt: i, update: s, setRegion: u, reset: m, replace: d, resolvedTheme: c }),
|
|
189
189
|
[n, i, s, u, m, d, c]
|
|
190
190
|
), p = X(
|
|
191
|
-
() =>
|
|
191
|
+
() => {
|
|
192
|
+
var h;
|
|
193
|
+
return {
|
|
194
|
+
display: "contents",
|
|
195
|
+
"--fc-accent": n.ui.accent,
|
|
196
|
+
// Each preset ships its own readable text colour for on-accent surfaces (buttons, active nav,
|
|
197
|
+
// FAB). Without this, on-accent text falls back to white and low-contrasts on light accents.
|
|
198
|
+
"--fc-accent-ink": ((h = xa(n.ui.accent)) == null ? void 0 : h.ink) ?? "#ffffff",
|
|
199
|
+
"--fc-font-ui": Sa(n.ui.fontFamily)
|
|
200
|
+
};
|
|
201
|
+
},
|
|
192
202
|
[n.ui.accent, n.ui.fontFamily]
|
|
193
203
|
);
|
|
194
|
-
return /* @__PURE__ */ o(
|
|
204
|
+
return /* @__PURE__ */ o(Tn.Provider, { value: l, children: /* @__PURE__ */ o(
|
|
195
205
|
"div",
|
|
196
206
|
{
|
|
197
207
|
"data-fincalc-root": "",
|
|
@@ -203,17 +213,17 @@ function ps({
|
|
|
203
213
|
) });
|
|
204
214
|
}
|
|
205
215
|
function ue() {
|
|
206
|
-
const e =
|
|
216
|
+
const e = ba(Tn);
|
|
207
217
|
if (!e) throw new Error("useSettings must be used within SettingsProvider");
|
|
208
218
|
return e;
|
|
209
219
|
}
|
|
210
|
-
let
|
|
211
|
-
const
|
|
212
|
-
|
|
213
|
-
},
|
|
214
|
-
|
|
215
|
-
},
|
|
216
|
-
function
|
|
220
|
+
let tt = 0;
|
|
221
|
+
const Pa = () => {
|
|
222
|
+
tt += 1;
|
|
223
|
+
}, Ta = () => {
|
|
224
|
+
tt = Math.max(0, tt - 1);
|
|
225
|
+
}, Fa = () => tt > 0, Ia = 'a[href],button:not([disabled]),textarea:not([disabled]),input:not([disabled]),select:not([disabled]),[tabindex]:not([tabindex="-1"])';
|
|
226
|
+
function Ra({
|
|
217
227
|
open: e,
|
|
218
228
|
onClose: t,
|
|
219
229
|
children: n,
|
|
@@ -222,7 +232,7 @@ function Fa({
|
|
|
222
232
|
}) {
|
|
223
233
|
const s = de(null), u = de(null), m = ke(() => {
|
|
224
234
|
const h = s.current;
|
|
225
|
-
return h ? Array.from(h.querySelectorAll(
|
|
235
|
+
return h ? Array.from(h.querySelectorAll(Ia)).filter(
|
|
226
236
|
(f) => !f.hasAttribute("disabled") && f.getAttribute("aria-hidden") !== "true"
|
|
227
237
|
) : [];
|
|
228
238
|
}, []), [d, i] = M(e), [c, l] = M(!1);
|
|
@@ -246,7 +256,7 @@ function Fa({
|
|
|
246
256
|
document.body.style.overflow = "hidden";
|
|
247
257
|
const w = (k) => {
|
|
248
258
|
if (k.key === "Escape") {
|
|
249
|
-
if (
|
|
259
|
+
if (Fa()) return;
|
|
250
260
|
k.preventDefault(), k.stopImmediatePropagation(), t();
|
|
251
261
|
return;
|
|
252
262
|
}
|
|
@@ -292,17 +302,17 @@ function be(e, t, n, a = !1) {
|
|
|
292
302
|
let m = s.times(u.minus(1)).div(r);
|
|
293
303
|
return a && (m = m.times(r.plus(1))), m;
|
|
294
304
|
}
|
|
295
|
-
function
|
|
305
|
+
function nt(e, t, n) {
|
|
296
306
|
return g(e).times(g(t).plus(1).pow(n));
|
|
297
307
|
}
|
|
298
|
-
function
|
|
308
|
+
function In(e, t, n, a = !1) {
|
|
299
309
|
const r = g(t), s = g(e);
|
|
300
310
|
if (ce(r)) return s.times(n);
|
|
301
311
|
const u = r.plus(1).pow(n);
|
|
302
312
|
let m = s.times(g(1).minus(u.pow(-1))).div(r);
|
|
303
313
|
return a && (m = m.times(r.plus(1))), m;
|
|
304
314
|
}
|
|
305
|
-
function
|
|
315
|
+
function Ea(e, t, n) {
|
|
306
316
|
return g(e).div(g(t).plus(1).pow(n));
|
|
307
317
|
}
|
|
308
318
|
function we(e, t, n, a = 0, r = !1) {
|
|
@@ -312,11 +322,11 @@ function we(e, t, n, a = 0, r = !1) {
|
|
|
312
322
|
let m = g(e).times(u).plus(a).times(s).div(u.minus(1));
|
|
313
323
|
return r && (m = m.div(s.plus(1))), m;
|
|
314
324
|
}
|
|
315
|
-
function
|
|
325
|
+
function Ma(e, t, n) {
|
|
316
326
|
const a = g(n), r = g(e), s = g(t);
|
|
317
327
|
return ce(a) ? r.div(s) : H.ln(s.div(s.minus(r.times(a)))).div(H.ln(a.plus(1)));
|
|
318
328
|
}
|
|
319
|
-
function
|
|
329
|
+
function it(e, t = -0.9999, n = 100, a = 200) {
|
|
320
330
|
let r = g(t), s = g(n), u = e(r), m = e(s);
|
|
321
331
|
if (u.times(m).gt(0)) return null;
|
|
322
332
|
for (let d = 0; d < a; d++) {
|
|
@@ -333,42 +343,42 @@ function At(e, t) {
|
|
|
333
343
|
a = a.plus(g(t[r]).div(n.plus(1).pow(r)));
|
|
334
344
|
return a;
|
|
335
345
|
}
|
|
336
|
-
function
|
|
337
|
-
return
|
|
346
|
+
function Rn(e) {
|
|
347
|
+
return it((t) => At(t, e));
|
|
338
348
|
}
|
|
339
|
-
const
|
|
340
|
-
function
|
|
349
|
+
const $a = (e, t) => (Date.parse(t) - Date.parse(e)) / 864e5;
|
|
350
|
+
function En(e, t) {
|
|
341
351
|
const n = g(e), a = t[0].date;
|
|
342
352
|
let r = g(0);
|
|
343
353
|
for (const s of t) {
|
|
344
|
-
const u = g(
|
|
354
|
+
const u = g($a(a, s.date)).div(365);
|
|
345
355
|
r = r.plus(g(s.amount).div(n.plus(1).pow(u)));
|
|
346
356
|
}
|
|
347
357
|
return r;
|
|
348
358
|
}
|
|
349
|
-
function
|
|
359
|
+
function Mn(e) {
|
|
350
360
|
if (e.length < 2) return null;
|
|
351
361
|
const t = [...e].sort((n, a) => Date.parse(n.date) - Date.parse(a.date));
|
|
352
|
-
return
|
|
362
|
+
return it((n) => En(n, t), -0.9999, 100);
|
|
353
363
|
}
|
|
354
|
-
function
|
|
364
|
+
function st(e, t, n) {
|
|
355
365
|
return g(t).div(e).pow(g(1).div(n)).minus(1);
|
|
356
366
|
}
|
|
357
|
-
const
|
|
367
|
+
const ys = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
|
|
358
368
|
__proto__: null,
|
|
359
|
-
bisectRate:
|
|
360
|
-
cagr:
|
|
369
|
+
bisectRate: it,
|
|
370
|
+
cagr: st,
|
|
361
371
|
fvAnnuity: be,
|
|
362
|
-
fvLump:
|
|
363
|
-
irr:
|
|
364
|
-
nper:
|
|
372
|
+
fvLump: nt,
|
|
373
|
+
irr: Rn,
|
|
374
|
+
nper: Ma,
|
|
365
375
|
npv: At,
|
|
366
376
|
periodic: J,
|
|
367
377
|
pmt: we,
|
|
368
|
-
pvAnnuity:
|
|
369
|
-
pvLump:
|
|
370
|
-
xirr:
|
|
371
|
-
xnpv:
|
|
378
|
+
pvAnnuity: In,
|
|
379
|
+
pvLump: Ea,
|
|
380
|
+
xirr: Mn,
|
|
381
|
+
xnpv: En
|
|
372
382
|
}, Symbol.toStringTag, { value: "Module" })), me = {
|
|
373
383
|
IN: {
|
|
374
384
|
region: "IN",
|
|
@@ -405,18 +415,18 @@ class se extends Error {
|
|
|
405
415
|
this.name = "FinCalcError", this.code = n, this.field = r;
|
|
406
416
|
}
|
|
407
417
|
}
|
|
408
|
-
const
|
|
418
|
+
const Aa = 2, te = (e) => e.toDecimalPlaces(Aa, H.ROUND_HALF_UP), St = (e) => e.div(100).div(12);
|
|
409
419
|
function Ct(e, t, n) {
|
|
410
420
|
if (ce(t)) return e.div(n);
|
|
411
421
|
const a = t.plus(1).pow(n);
|
|
412
422
|
return e.times(t).times(a).div(a.minus(1));
|
|
413
423
|
}
|
|
414
|
-
function
|
|
424
|
+
function Da(e, t, n) {
|
|
415
425
|
if (ce(t)) return e.times(n);
|
|
416
426
|
const a = t.plus(1).pow(n);
|
|
417
427
|
return e.times(a.minus(1)).div(t.times(a));
|
|
418
428
|
}
|
|
419
|
-
function
|
|
429
|
+
function La(e, t, n) {
|
|
420
430
|
if (ce(t)) return Math.ceil(e.div(n).toNumber());
|
|
421
431
|
const a = e.times(t);
|
|
422
432
|
if (n.lte(a))
|
|
@@ -442,7 +452,7 @@ function Gt(e, t, n, a) {
|
|
|
442
452
|
throw new se("SOLVER_DID_NOT_CONVERGE", "Could not find a rate within the allowed range.", "rate");
|
|
443
453
|
return u;
|
|
444
454
|
}
|
|
445
|
-
function
|
|
455
|
+
function Ua(e, t, n, a) {
|
|
446
456
|
const r = [];
|
|
447
457
|
let s = e, u = g(0);
|
|
448
458
|
for (let m = 1; m <= n; m++) {
|
|
@@ -460,7 +470,7 @@ function Da(e, t, n, a) {
|
|
|
460
470
|
}
|
|
461
471
|
return r;
|
|
462
472
|
}
|
|
463
|
-
function
|
|
473
|
+
function Oa(e) {
|
|
464
474
|
const t = [];
|
|
465
475
|
for (const n of e) {
|
|
466
476
|
const a = Math.ceil(n.month / 12);
|
|
@@ -503,17 +513,17 @@ function Ie(e) {
|
|
|
503
513
|
i = te(Ct(u, k(), d)), l = "PMT = P·r·(1+r)^n / ((1+r)^n − 1)";
|
|
504
514
|
break;
|
|
505
515
|
case "principal":
|
|
506
|
-
u =
|
|
516
|
+
u = Da(i, k(), d), l = "P = PMT·((1+r)^n − 1) / (r·(1+r)^n)";
|
|
507
517
|
break;
|
|
508
518
|
case "tenure":
|
|
509
|
-
d =
|
|
519
|
+
d = La(u, k(), i), l = "n = ln(PMT / (PMT − P·r)) / ln(1 + r)";
|
|
510
520
|
break;
|
|
511
521
|
case "rate":
|
|
512
522
|
m = Gt(u, d, i, t.maxRatePct), l = "solve r: PMT = P·r·(1+r)^n / ((1+r)^n − 1)";
|
|
513
523
|
break;
|
|
514
524
|
}
|
|
515
525
|
}
|
|
516
|
-
const p = St(m), h = n === "flat" ? i : te(Ct(u, p, d)), f =
|
|
526
|
+
const p = St(m), h = n === "flat" ? i : te(Ct(u, p, d)), f = Ua(u, p, d, h);
|
|
517
527
|
d = f.length;
|
|
518
528
|
const y = f.reduce((k, S) => k.plus(S.interest), g(0)), w = f.reduce((k, S) => k.plus(S.payment), g(0));
|
|
519
529
|
return {
|
|
@@ -527,7 +537,7 @@ function Ie(e) {
|
|
|
527
537
|
totalInterest: te(y),
|
|
528
538
|
totalPayment: te(w),
|
|
529
539
|
schedule: f,
|
|
530
|
-
byYear:
|
|
540
|
+
byYear: Oa(f),
|
|
531
541
|
chart: {
|
|
532
542
|
balance: f.map((k) => k.closingBalance),
|
|
533
543
|
cumulativeInterest: f.map((k) => k.cumulativeInterest)
|
|
@@ -549,7 +559,7 @@ const C = (e, t = 0) => {
|
|
|
549
559
|
tone: n,
|
|
550
560
|
sub: a
|
|
551
561
|
}), U = (e) => e.toDecimalPlaces(2, H.ROUND_HALF_UP);
|
|
552
|
-
function
|
|
562
|
+
function $n(e, t) {
|
|
553
563
|
const n = /* @__PURE__ */ new Map();
|
|
554
564
|
for (const r of e) {
|
|
555
565
|
const s = Math.ceil(r.month / 12), u = n.get(s);
|
|
@@ -567,7 +577,7 @@ function Mn(e, t) {
|
|
|
567
577
|
}
|
|
568
578
|
return a;
|
|
569
579
|
}
|
|
570
|
-
const
|
|
580
|
+
const An = [
|
|
571
581
|
{
|
|
572
582
|
key: "count",
|
|
573
583
|
label: "How many loans",
|
|
@@ -578,19 +588,19 @@ const $n = [
|
|
|
578
588
|
];
|
|
579
589
|
for (let e = 1; e <= 5; e++) {
|
|
580
590
|
const t = e <= 2, n = t ? void 0 : (a) => C(a.count, 2) >= e;
|
|
581
|
-
|
|
591
|
+
An.push(
|
|
582
592
|
{ key: `p${e}`, label: `Loan ${e} amount`, kind: "money", prefix: "currency", default: e <= 2 ? "2500000" : "", optional: !t, showIf: n },
|
|
583
593
|
{ key: `r${e}`, label: `Loan ${e} rate`, kind: "percent", suffix: "%", default: e === 1 ? 9 : e === 2 ? 8.65 : "", optional: !t, showIf: n, labelByRegion: {} },
|
|
584
594
|
{ key: `t${e}`, label: `Loan ${e} tenure`, kind: "tenure", default: 240, optional: !t, showIf: n, labelByRegion: { US: `Loan ${e} term` } }
|
|
585
595
|
);
|
|
586
596
|
}
|
|
587
|
-
const
|
|
597
|
+
const Ba = {
|
|
588
598
|
id: "loan.compare",
|
|
589
599
|
group: "loans",
|
|
590
600
|
title: "Compare loans",
|
|
591
601
|
blurb: "Line up 2–5 loans and see which costs least over its full life.",
|
|
592
602
|
keywords: ["compare", "loan", "cheapest", "emi", "best offer"],
|
|
593
|
-
inputs:
|
|
603
|
+
inputs: An,
|
|
594
604
|
compute(e, t) {
|
|
595
605
|
const n = me[t.region], a = Math.max(2, Math.min(5, C(e.count, 2))), r = [];
|
|
596
606
|
for (let l = 1; l <= a; l++) {
|
|
@@ -628,7 +638,7 @@ const Ua = {
|
|
|
628
638
|
raw: i
|
|
629
639
|
};
|
|
630
640
|
}
|
|
631
|
-
},
|
|
641
|
+
}, _a = {
|
|
632
642
|
id: "loan.prepay",
|
|
633
643
|
group: "loans",
|
|
634
644
|
title: "Prepayment impact",
|
|
@@ -697,7 +707,7 @@ const Ua = {
|
|
|
697
707
|
schedule: {
|
|
698
708
|
title: "New amortisation",
|
|
699
709
|
columns: ["Month", "Principal", "Interest", "Prepay", "Balance"],
|
|
700
|
-
groups:
|
|
710
|
+
groups: $n(w, t),
|
|
701
711
|
toneCols: { 1: "principal", 2: "interest" }
|
|
702
712
|
},
|
|
703
713
|
notes: B,
|
|
@@ -712,7 +722,7 @@ const Ua = {
|
|
|
712
722
|
}
|
|
713
723
|
};
|
|
714
724
|
}
|
|
715
|
-
},
|
|
725
|
+
}, Ha = {
|
|
716
726
|
id: "loan.transfer",
|
|
717
727
|
group: "loans",
|
|
718
728
|
title: "Balance transfer",
|
|
@@ -756,7 +766,7 @@ const Ua = {
|
|
|
756
766
|
}
|
|
757
767
|
};
|
|
758
768
|
}
|
|
759
|
-
},
|
|
769
|
+
}, qa = {
|
|
760
770
|
id: "loan.eligibility",
|
|
761
771
|
group: "loans",
|
|
762
772
|
title: "Loan eligibility",
|
|
@@ -797,7 +807,7 @@ const Ua = {
|
|
|
797
807
|
}
|
|
798
808
|
const d = [];
|
|
799
809
|
let i = g(0);
|
|
800
|
-
return u.gt(0) ? i = U(
|
|
810
|
+
return u.gt(0) ? i = U(In(u, s, r)) : d.push("Existing obligations already use up the allowed share of income — no additional loan capacity."), {
|
|
801
811
|
primary: v("Eligible loan amount", t.fmt.money(i), "positive"),
|
|
802
812
|
secondary: m,
|
|
803
813
|
formula: t.region === "US" ? "EMI = min(income·frontDTI, income·backDTI − debts); P = PV of that annuity" : "EMI = income·FOIR − existingEMI; P = PV of that annuity",
|
|
@@ -808,7 +818,7 @@ const Ua = {
|
|
|
808
818
|
}
|
|
809
819
|
};
|
|
810
820
|
}
|
|
811
|
-
},
|
|
821
|
+
}, Ga = {
|
|
812
822
|
id: "loan.stepEmi",
|
|
813
823
|
group: "loans",
|
|
814
824
|
title: "Step-up / step-down EMI",
|
|
@@ -825,7 +835,7 @@ const Ua = {
|
|
|
825
835
|
let S = a;
|
|
826
836
|
for (let F = 1; F <= s; F++) S = S.plus(S.times(m)).minus(k.times(d(F)));
|
|
827
837
|
return S;
|
|
828
|
-
}, c = U(
|
|
838
|
+
}, c = U(it((k) => i(k), 0, a.toNumber(), 200) ?? we(a, m, s)), l = [];
|
|
829
839
|
let p = a, h = g(0), f = c;
|
|
830
840
|
for (let k = 1; k <= s && p.gt("0.005"); k++) {
|
|
831
841
|
const S = U(p.times(m));
|
|
@@ -845,7 +855,7 @@ const Ua = {
|
|
|
845
855
|
schedule: {
|
|
846
856
|
title: "Amortisation",
|
|
847
857
|
columns: ["Month", "Principal", "Interest", n.paymentLabel, "Balance"],
|
|
848
|
-
groups:
|
|
858
|
+
groups: $n(l, t),
|
|
849
859
|
toneCols: { 1: "principal", 2: "interest" }
|
|
850
860
|
},
|
|
851
861
|
notes: [`EMI changes by ${t.fmt.pct(g(C(e.annualStepPct)))} every 12 months. A step-up starts lower and pays a little more interest than a flat EMI; a step-down does the reverse.`],
|
|
@@ -859,7 +869,7 @@ const Ua = {
|
|
|
859
869
|
}
|
|
860
870
|
};
|
|
861
871
|
}
|
|
862
|
-
},
|
|
872
|
+
}, ja = {
|
|
863
873
|
id: "loan.moratorium",
|
|
864
874
|
group: "loans",
|
|
865
875
|
title: "Moratorium / EMI holiday",
|
|
@@ -914,7 +924,7 @@ const Ua = {
|
|
|
914
924
|
}
|
|
915
925
|
};
|
|
916
926
|
}
|
|
917
|
-
},
|
|
927
|
+
}, Va = {
|
|
918
928
|
id: "loan.overdraft",
|
|
919
929
|
group: "loans",
|
|
920
930
|
title: "Overdraft / flexi loan",
|
|
@@ -944,7 +954,7 @@ const Ua = {
|
|
|
944
954
|
}
|
|
945
955
|
};
|
|
946
956
|
}
|
|
947
|
-
},
|
|
957
|
+
}, Ya = {
|
|
948
958
|
id: "loan.refinance",
|
|
949
959
|
group: "loans",
|
|
950
960
|
title: "Refinance",
|
|
@@ -991,16 +1001,16 @@ const Ua = {
|
|
|
991
1001
|
}
|
|
992
1002
|
};
|
|
993
1003
|
}
|
|
994
|
-
},
|
|
995
|
-
Ua,
|
|
996
|
-
Oa,
|
|
1004
|
+
}, Ka = [
|
|
997
1005
|
Ba,
|
|
998
1006
|
_a,
|
|
999
1007
|
Ha,
|
|
1000
1008
|
qa,
|
|
1001
1009
|
Ga,
|
|
1002
|
-
ja
|
|
1003
|
-
|
|
1010
|
+
ja,
|
|
1011
|
+
Va,
|
|
1012
|
+
Ya
|
|
1013
|
+
], lt = Qe.defaults.sipReturnPercent, Wa = Qe.defaults.inflationPercent, ct = (e, t) => ({
|
|
1004
1014
|
labels: e,
|
|
1005
1015
|
series: [{ name: "Value", tone: "accent", points: t, area: !0 }]
|
|
1006
1016
|
}), Dt = (e) => ({
|
|
@@ -1010,7 +1020,7 @@ const Ua = {
|
|
|
1010
1020
|
}), Lt = (e, t) => [
|
|
1011
1021
|
{ label: "Invested", value: Number(e), tone: "principal" },
|
|
1012
1022
|
{ label: "Gains", value: Number(t), tone: "interest" }
|
|
1013
|
-
],
|
|
1023
|
+
], za = {
|
|
1014
1024
|
id: "invest.sip",
|
|
1015
1025
|
group: "invest",
|
|
1016
1026
|
title: "SIP Calculator",
|
|
@@ -1018,7 +1028,7 @@ const Ua = {
|
|
|
1018
1028
|
keywords: ["sip", "systematic investment plan", "mutual fund", "monthly investment", "future value"],
|
|
1019
1029
|
inputs: [
|
|
1020
1030
|
{ key: "monthlyAmount", label: "Monthly investment", kind: "money", prefix: "currency", default: "10000" },
|
|
1021
|
-
{ key: "expectedReturnPct", label: "Expected return", kind: "percent", suffix: "% p.a.", default:
|
|
1031
|
+
{ key: "expectedReturnPct", label: "Expected return", kind: "percent", suffix: "% p.a.", default: lt },
|
|
1022
1032
|
{ key: "tenure", label: "Investment period", kind: "tenure", default: 120 }
|
|
1023
1033
|
],
|
|
1024
1034
|
compute(e, t) {
|
|
@@ -1036,7 +1046,7 @@ const Ua = {
|
|
|
1036
1046
|
],
|
|
1037
1047
|
split: Lt(i.toFixed(2), c.toFixed(2)),
|
|
1038
1048
|
schedule: Dt(p),
|
|
1039
|
-
chart:
|
|
1049
|
+
chart: ct(p.map((f) => f.label), h),
|
|
1040
1050
|
formula: "FV = P·[((1+i)^n − 1) / i]·(1+i), i = r/12 (invested at the start of each month)",
|
|
1041
1051
|
notes: ["Returns are assumed constant; actual market returns vary year to year."],
|
|
1042
1052
|
raw: {
|
|
@@ -1047,7 +1057,7 @@ const Ua = {
|
|
|
1047
1057
|
}
|
|
1048
1058
|
};
|
|
1049
1059
|
}
|
|
1050
|
-
},
|
|
1060
|
+
}, Ja = {
|
|
1051
1061
|
id: "invest.stepupSip",
|
|
1052
1062
|
group: "invest",
|
|
1053
1063
|
title: "Step-up SIP Calculator",
|
|
@@ -1056,7 +1066,7 @@ const Ua = {
|
|
|
1056
1066
|
inputs: [
|
|
1057
1067
|
{ key: "monthlyAmount", label: "Initial monthly investment", kind: "money", prefix: "currency", default: "10000" },
|
|
1058
1068
|
{ key: "annualStepPct", label: "Annual step-up", kind: "percent", suffix: "%", default: "10" },
|
|
1059
|
-
{ key: "returnPct", label: "Expected return", kind: "percent", suffix: "% p.a.", default:
|
|
1069
|
+
{ key: "returnPct", label: "Expected return", kind: "percent", suffix: "% p.a.", default: lt },
|
|
1060
1070
|
{ key: "tenure", label: "Investment period", kind: "tenure", default: 120 }
|
|
1061
1071
|
],
|
|
1062
1072
|
compute(e, t) {
|
|
@@ -1075,13 +1085,13 @@ const Ua = {
|
|
|
1075
1085
|
],
|
|
1076
1086
|
split: Lt(c.toFixed(2), f.toFixed(2)),
|
|
1077
1087
|
schedule: Dt(p),
|
|
1078
|
-
chart:
|
|
1088
|
+
chart: ct(p.map((y) => y.label), h),
|
|
1079
1089
|
formula: "Monthly simulation; the SIP amount is increased by the step-up % every 12 months",
|
|
1080
1090
|
notes: ["The monthly amount steps up on each yearly anniversary; returns are assumed constant."],
|
|
1081
1091
|
raw: { maturity: i.toFixed(2), invested: c.toFixed(2), gains: f.toFixed(2), finalMonthly: l.toFixed(2) }
|
|
1082
1092
|
};
|
|
1083
1093
|
}
|
|
1084
|
-
},
|
|
1094
|
+
}, Za = { annual: 1, semiannual: 2, quarterly: 4, monthly: 12 }, Xa = {
|
|
1085
1095
|
id: "invest.lumpsum",
|
|
1086
1096
|
group: "invest",
|
|
1087
1097
|
title: "Lump Sum Calculator",
|
|
@@ -1089,7 +1099,7 @@ const Ua = {
|
|
|
1089
1099
|
keywords: ["lump sum", "lumpsum", "one time investment", "compound interest", "maturity"],
|
|
1090
1100
|
inputs: [
|
|
1091
1101
|
{ key: "principal", label: "Investment amount", kind: "money", prefix: "currency", default: "100000" },
|
|
1092
|
-
{ key: "ratePct", label: "Expected return", kind: "percent", suffix: "% p.a.", default:
|
|
1102
|
+
{ key: "ratePct", label: "Expected return", kind: "percent", suffix: "% p.a.", default: lt },
|
|
1093
1103
|
{ key: "years", label: "Investment period", kind: "years", suffix: "years", default: 10 },
|
|
1094
1104
|
{
|
|
1095
1105
|
key: "compounding",
|
|
@@ -1105,7 +1115,7 @@ const Ua = {
|
|
|
1105
1115
|
}
|
|
1106
1116
|
],
|
|
1107
1117
|
compute(e, t) {
|
|
1108
|
-
const { D: n, fmt: a } = t, r = D(e.principal, "100000"), s = n(C(e.ratePct, Number(t.settings.defaults.sipReturnPercent))), u = Math.max(1, Math.round(C(e.years, 10))), m =
|
|
1118
|
+
const { D: n, fmt: a } = t, r = D(e.principal, "100000"), s = n(C(e.ratePct, Number(t.settings.defaults.sipReturnPercent))), u = Math.max(1, Math.round(C(e.years, 10))), m = Za[_(e.compounding, "annual")] ?? 1, d = s.div(100).div(m), i = r.times(d.plus(1).pow(m * u)), c = i.minus(r), l = r.isZero() ? n(0) : st(r, i, u), p = [], h = [];
|
|
1109
1119
|
for (let f = 1; f <= u; f++) {
|
|
1110
1120
|
const y = r.times(d.plus(1).pow(m * f));
|
|
1111
1121
|
p.push({ label: String(f), cells: [a.money(r), a.money(y.minus(r)), a.money(y)] }), h.push(Number(y.toFixed(2)));
|
|
@@ -1119,13 +1129,13 @@ const Ua = {
|
|
|
1119
1129
|
],
|
|
1120
1130
|
split: Lt(r.toFixed(2), c.toFixed(2)),
|
|
1121
1131
|
schedule: Dt(p),
|
|
1122
|
-
chart:
|
|
1132
|
+
chart: ct(p.map((f) => f.label), h),
|
|
1123
1133
|
formula: "A = P·(1 + r/f)^(f·t)",
|
|
1124
1134
|
notes: ["Returns are assumed constant across the whole period."],
|
|
1125
1135
|
raw: { maturity: i.toFixed(2), invested: r.toFixed(2), gains: c.toFixed(2), cagr: l.times(100).toFixed(4) }
|
|
1126
1136
|
};
|
|
1127
1137
|
}
|
|
1128
|
-
},
|
|
1138
|
+
}, Qa = 1200, er = {
|
|
1129
1139
|
id: "invest.swp",
|
|
1130
1140
|
group: "invest",
|
|
1131
1141
|
title: "SWP Calculator",
|
|
@@ -1138,7 +1148,7 @@ const Ua = {
|
|
|
1138
1148
|
{ key: "tenureMonths", label: "Withdrawal period", kind: "tenure", default: 120, optional: !0 }
|
|
1139
1149
|
],
|
|
1140
1150
|
compute(e, t) {
|
|
1141
|
-
const { D: n, fmt: a } = t, r = D(e.corpus, "5000000"), s = D(e.withdrawalPerMonth, "30000"), u = C(e.expectedReturnPct, 8), m = J(u, 12), d = C(e.tenureMonths, 0), i = d > 0 ? Math.round(d) :
|
|
1151
|
+
const { D: n, fmt: a } = t, r = D(e.corpus, "5000000"), s = D(e.withdrawalPerMonth, "30000"), u = C(e.expectedReturnPct, 8), m = J(u, 12), d = C(e.tenureMonths, 0), i = d > 0 ? Math.round(d) : Qa;
|
|
1142
1152
|
let c = r, l = n(0), p = 0;
|
|
1143
1153
|
const h = [], f = [];
|
|
1144
1154
|
let y = r, w = n(0);
|
|
@@ -1164,7 +1174,7 @@ const Ua = {
|
|
|
1164
1174
|
rows: h,
|
|
1165
1175
|
toneCols: { 2: "interest", 3: "principal" }
|
|
1166
1176
|
},
|
|
1167
|
-
chart:
|
|
1177
|
+
chart: ct(h.map((N) => N.label), f),
|
|
1168
1178
|
formula: "Each month: balance = balance·(1 + r/12) − withdrawal",
|
|
1169
1179
|
notes: [
|
|
1170
1180
|
S ? `The corpus is exhausted in month ${p}; the final withdrawal may be partial.` : "The corpus survives the whole withdrawal period; the remaining balance is shown.",
|
|
@@ -1177,7 +1187,7 @@ const Ua = {
|
|
|
1177
1187
|
}
|
|
1178
1188
|
};
|
|
1179
1189
|
}
|
|
1180
|
-
},
|
|
1190
|
+
}, tr = {
|
|
1181
1191
|
id: "invest.goal",
|
|
1182
1192
|
group: "invest",
|
|
1183
1193
|
title: "Goal SIP Planner",
|
|
@@ -1186,12 +1196,12 @@ const Ua = {
|
|
|
1186
1196
|
inputs: [
|
|
1187
1197
|
{ key: "targetCorpus", label: "Today's cost of goal", kind: "money", prefix: "currency", default: "10000000" },
|
|
1188
1198
|
{ key: "years", label: "Years to goal", kind: "years", suffix: "years", default: 15 },
|
|
1189
|
-
{ key: "expectedReturnPct", label: "Expected return", kind: "percent", suffix: "% p.a.", default:
|
|
1190
|
-
{ key: "inflationPct", label: "Inflation", kind: "percent", suffix: "% p.a.", default:
|
|
1199
|
+
{ key: "expectedReturnPct", label: "Expected return", kind: "percent", suffix: "% p.a.", default: lt },
|
|
1200
|
+
{ key: "inflationPct", label: "Inflation", kind: "percent", suffix: "% p.a.", default: Wa },
|
|
1191
1201
|
{ key: "existingSavings", label: "Existing savings", kind: "money", prefix: "currency", default: "0", optional: !0 }
|
|
1192
1202
|
],
|
|
1193
1203
|
compute(e, t) {
|
|
1194
|
-
const { D: n, fmt: a } = t, r = D(e.targetCorpus, "10000000"), s = Math.max(1, Math.round(C(e.years, 15))), u = C(e.expectedReturnPct, Number(t.settings.defaults.sipReturnPercent)), m = n(C(e.inflationPct, Number(t.settings.defaults.inflationPercent))).div(100), d = D(e.existingSavings, "0"), i = s * 12, c = J(u, 12), l = r.times(m.plus(1).pow(s)), p =
|
|
1204
|
+
const { D: n, fmt: a } = t, r = D(e.targetCorpus, "10000000"), s = Math.max(1, Math.round(C(e.years, 15))), u = C(e.expectedReturnPct, Number(t.settings.defaults.sipReturnPercent)), m = n(C(e.inflationPct, Number(t.settings.defaults.inflationPercent))).div(100), d = D(e.existingSavings, "0"), i = s * 12, c = J(u, 12), l = r.times(m.plus(1).pow(s)), p = nt(d, c, i), h = l.minus(p), f = be(1, c, i, !0), y = h.gt(0) ? h.div(f) : n(0), w = y.times(i), k = h.gt(0) ? h.minus(w) : n(0), S = [
|
|
1195
1205
|
`Target grows with ${a.pct(m.times(100))} inflation to ${a.money(l)} in ${s} years.`
|
|
1196
1206
|
];
|
|
1197
1207
|
d.gt(0) && S.push(`Existing savings grow to ${a.money(p)}, reducing what the SIP must fund.`);
|
|
@@ -1215,14 +1225,14 @@ const Ua = {
|
|
|
1215
1225
|
}
|
|
1216
1226
|
};
|
|
1217
1227
|
}
|
|
1218
|
-
},
|
|
1228
|
+
}, nr = [za, Ja, Xa, er, tr], Dn = "10% TDS applies on interest above ₹40,000/yr (₹50,000 for senior citizens). Submit Form 15G/15H to waive if income is below the taxable limit.", Oe = (e, t, n) => ({
|
|
1219
1229
|
labels: e,
|
|
1220
1230
|
series: [{ name: n, tone: "accent", points: t, area: !0 }]
|
|
1221
1231
|
}), Be = (e, t, n) => ({
|
|
1222
1232
|
columns: e,
|
|
1223
1233
|
rows: t,
|
|
1224
1234
|
toneCols: { [n]: "interest" }
|
|
1225
|
-
}),
|
|
1235
|
+
}), ar = {
|
|
1226
1236
|
id: "invest.fd",
|
|
1227
1237
|
group: "invest",
|
|
1228
1238
|
title: "Fixed Deposit (FD)",
|
|
@@ -1283,7 +1293,7 @@ const Ua = {
|
|
|
1283
1293
|
formula: i ? "Interest/period = P·(r/f); principal returned at maturity" : "A = P·(1 + r/f)^(f·t)",
|
|
1284
1294
|
notes: [
|
|
1285
1295
|
i ? "Interest is paid out each period; the principal is returned at maturity." : "Interest is reinvested (compounded) and paid with the principal at maturity.",
|
|
1286
|
-
|
|
1296
|
+
Dn
|
|
1287
1297
|
],
|
|
1288
1298
|
raw: {
|
|
1289
1299
|
maturity: k.toFixed(2),
|
|
@@ -1294,7 +1304,7 @@ const Ua = {
|
|
|
1294
1304
|
}
|
|
1295
1305
|
};
|
|
1296
1306
|
}
|
|
1297
|
-
},
|
|
1307
|
+
}, rr = {
|
|
1298
1308
|
id: "invest.rd",
|
|
1299
1309
|
group: "invest",
|
|
1300
1310
|
title: "Recurring Deposit (RD)",
|
|
@@ -1335,12 +1345,12 @@ const Ua = {
|
|
|
1335
1345
|
schedule: Be(["Year", "Invested", "Interest", "Value"], p, 2),
|
|
1336
1346
|
chart: Oe(p.map((f) => f.label), h, "Value"),
|
|
1337
1347
|
formula: "M = Σ deposit·(1 + r/4)^(quarters remaining)",
|
|
1338
|
-
notes: ["Interest is compounded quarterly, the standard for bank recurring deposits.",
|
|
1348
|
+
notes: ["Interest is compounded quarterly, the standard for bank recurring deposits.", Dn],
|
|
1339
1349
|
warnings: d,
|
|
1340
1350
|
raw: { maturity: i.toFixed(2), invested: c.toFixed(2), interest: l.toFixed(2) }
|
|
1341
1351
|
};
|
|
1342
1352
|
}
|
|
1343
|
-
},
|
|
1353
|
+
}, or = {
|
|
1344
1354
|
id: "invest.ppf",
|
|
1345
1355
|
group: "invest",
|
|
1346
1356
|
title: "Public Provident Fund (PPF)",
|
|
@@ -1397,7 +1407,7 @@ const Ua = {
|
|
|
1397
1407
|
raw: { maturity: i.toFixed(2), invested: p.toFixed(2), interest: h.toFixed(2) }
|
|
1398
1408
|
};
|
|
1399
1409
|
}
|
|
1400
|
-
},
|
|
1410
|
+
}, ir = {
|
|
1401
1411
|
id: "invest.nps",
|
|
1402
1412
|
group: "invest",
|
|
1403
1413
|
title: "National Pension System (NPS)",
|
|
@@ -1441,7 +1451,7 @@ const Ua = {
|
|
|
1441
1451
|
}
|
|
1442
1452
|
};
|
|
1443
1453
|
}
|
|
1444
|
-
},
|
|
1454
|
+
}, sr = {
|
|
1445
1455
|
id: "invest.epf",
|
|
1446
1456
|
group: "invest",
|
|
1447
1457
|
title: "Employees’ Provident Fund (EPF)",
|
|
@@ -1490,7 +1500,7 @@ const Ua = {
|
|
|
1490
1500
|
raw: { corpus: h.toFixed(2), contributions: f.toFixed(2), interest: k.toFixed(2) }
|
|
1491
1501
|
};
|
|
1492
1502
|
}
|
|
1493
|
-
},
|
|
1503
|
+
}, lr = {
|
|
1494
1504
|
id: "invest.ssy",
|
|
1495
1505
|
group: "invest",
|
|
1496
1506
|
title: "Sukanya Samriddhi Yojana (SSY)",
|
|
@@ -1533,7 +1543,7 @@ const Ua = {
|
|
|
1533
1543
|
raw: { maturity: l.toFixed(2), invested: f.toFixed(2), interest: y.toFixed(2) }
|
|
1534
1544
|
};
|
|
1535
1545
|
}
|
|
1536
|
-
},
|
|
1546
|
+
}, cr = [ar, rr, or, ir, sr, lr], ur = {
|
|
1537
1547
|
id: "invest.401k",
|
|
1538
1548
|
group: "invest",
|
|
1539
1549
|
title: "401(k) with Employer Match",
|
|
@@ -1597,7 +1607,7 @@ const Ua = {
|
|
|
1597
1607
|
}
|
|
1598
1608
|
};
|
|
1599
1609
|
}
|
|
1600
|
-
},
|
|
1610
|
+
}, dr = {
|
|
1601
1611
|
id: "invest.iraCompare",
|
|
1602
1612
|
group: "invest",
|
|
1603
1613
|
title: "Roth vs Traditional IRA",
|
|
@@ -1651,7 +1661,7 @@ const Ua = {
|
|
|
1651
1661
|
}
|
|
1652
1662
|
};
|
|
1653
1663
|
}
|
|
1654
|
-
},
|
|
1664
|
+
}, mr = {
|
|
1655
1665
|
id: "invest.529",
|
|
1656
1666
|
group: "invest",
|
|
1657
1667
|
title: "529 College Savings",
|
|
@@ -1667,7 +1677,7 @@ const Ua = {
|
|
|
1667
1677
|
{ key: "collegeCostInflationPct", label: "College cost inflation", kind: "percent", suffix: "%", default: 5, advanced: !0 }
|
|
1668
1678
|
],
|
|
1669
1679
|
compute(e, t) {
|
|
1670
|
-
const { fmt: n } = t, a = g(C(e.currentSavings)), r = g(C(e.monthlyContribution)), s = Math.max(0, Math.round(C(e.yearsUntilCollege))), u = s * 12, m = J(C(e.expectedReturnPct), 12), d =
|
|
1680
|
+
const { fmt: n } = t, a = g(C(e.currentSavings)), r = g(C(e.monthlyContribution)), s = Math.max(0, Math.round(C(e.yearsUntilCollege))), u = s * 12, m = J(C(e.expectedReturnPct), 12), d = nt(a, m, u), i = be(r, m, u), c = d.plus(i), l = a.plus(r.times(u)), p = c.minus(l), h = [
|
|
1671
1681
|
v("Total invested", n.money(l), "principal"),
|
|
1672
1682
|
v("Investment growth", n.money(p), "interest")
|
|
1673
1683
|
], f = {
|
|
@@ -1681,7 +1691,7 @@ const Ua = {
|
|
|
1681
1691
|
const k = g(C(e.currentAnnualCost)), S = g(C(e.collegeCostInflationPct)).div(100);
|
|
1682
1692
|
let F = g(0);
|
|
1683
1693
|
for (let x = 0; x < 4; x++)
|
|
1684
|
-
F = F.plus(
|
|
1694
|
+
F = F.plus(nt(k, S, s + x));
|
|
1685
1695
|
const N = c.minus(F), P = N.gte(0);
|
|
1686
1696
|
h.push(v("4-year college cost", n.money(F), "default", "inflation-adjusted")), h.push(
|
|
1687
1697
|
v(
|
|
@@ -1706,7 +1716,7 @@ const Ua = {
|
|
|
1706
1716
|
raw: f
|
|
1707
1717
|
};
|
|
1708
1718
|
}
|
|
1709
|
-
},
|
|
1719
|
+
}, pr = [ur, dr, mr], hr = (e) => e === "annual" ? 1 : e === "semiannual" ? 2 : e === "quarterly" ? 4 : 12, ut = (e) => _(e).split(/[, ]+/).map((t) => t.trim()).filter(Boolean).map(Number).filter((t) => Number.isFinite(t)), fr = {
|
|
1710
1720
|
id: "returns.tvm",
|
|
1711
1721
|
group: "returns",
|
|
1712
1722
|
title: "Time value of money (TVM)",
|
|
@@ -1737,7 +1747,7 @@ const Ua = {
|
|
|
1737
1747
|
] }
|
|
1738
1748
|
],
|
|
1739
1749
|
compute(e) {
|
|
1740
|
-
const t = _(e.solveFor, "FV"), n =
|
|
1750
|
+
const t = _(e.solveFor, "FV"), n = hr(_(e.compounding, "monthly")), a = g(C(e.ratePct)).div(100).div(n), r = C(e.n), s = _(e.timing) === "begin", u = g(C(e.pv)), m = g(C(e.pmt)), d = g(C(e.fv)), i = (f, y) => ce(f) ? g(y) : f.plus(1).pow(y).minus(1).div(f).times(s ? f.plus(1) : 1), c = (f, y) => f.plus(1).pow(y);
|
|
1741
1751
|
let l = "Future value", p = g(0), h = "PV·(1+i)^n + PMT·[((1+i)^n − 1)/i]·timing + FV = 0";
|
|
1742
1752
|
if (t === "FV")
|
|
1743
1753
|
p = u.times(c(a, r)).plus(m.times(i(a, r))).neg(), l = "Future value";
|
|
@@ -1774,7 +1784,7 @@ const Ua = {
|
|
|
1774
1784
|
}
|
|
1775
1785
|
return { primary: v(l, p.toDecimalPlaces(2).toString(), "accent"), formula: h, raw: { value: p.toNumber() } };
|
|
1776
1786
|
}
|
|
1777
|
-
},
|
|
1787
|
+
}, yr = {
|
|
1778
1788
|
id: "returns.cagr",
|
|
1779
1789
|
group: "returns",
|
|
1780
1790
|
title: "CAGR",
|
|
@@ -1786,7 +1796,7 @@ const Ua = {
|
|
|
1786
1796
|
{ key: "years", label: "Period", kind: "years", default: "10" }
|
|
1787
1797
|
],
|
|
1788
1798
|
compute(e, t) {
|
|
1789
|
-
const n = t.D(C(e.begin)), a = t.D(C(e.end)), r = C(e.years) || 1, s =
|
|
1799
|
+
const n = t.D(C(e.begin)), a = t.D(C(e.end)), r = C(e.years) || 1, s = st(n, a, r).times(100), u = a.minus(n).div(n).times(100);
|
|
1790
1800
|
return {
|
|
1791
1801
|
primary: v("CAGR", `${t.fmt.num(s, 2)}%`, "accent"),
|
|
1792
1802
|
secondary: [
|
|
@@ -1797,7 +1807,7 @@ const Ua = {
|
|
|
1797
1807
|
raw: { cagr: s.toNumber(), absolute: u.toNumber() }
|
|
1798
1808
|
};
|
|
1799
1809
|
}
|
|
1800
|
-
},
|
|
1810
|
+
}, br = {
|
|
1801
1811
|
id: "returns.absolute",
|
|
1802
1812
|
group: "returns",
|
|
1803
1813
|
title: "Absolute return",
|
|
@@ -1810,14 +1820,14 @@ const Ua = {
|
|
|
1810
1820
|
],
|
|
1811
1821
|
compute(e, t) {
|
|
1812
1822
|
const n = t.D(C(e.invested)), a = t.D(C(e.current)), r = a.minus(n).div(n).times(100), s = C(e.years), u = [v("Total gain", t.fmt.money(a.minus(n)), a.gte(n) ? "positive" : "negative")];
|
|
1813
|
-
return s > 0 && u.push(v("Annualised (CAGR)", `${t.fmt.num(
|
|
1823
|
+
return s > 0 && u.push(v("Annualised (CAGR)", `${t.fmt.num(st(n, a, s).times(100), 2)}%`)), {
|
|
1814
1824
|
primary: v("Absolute return", `${t.fmt.num(r, 2)}%`, "accent"),
|
|
1815
1825
|
secondary: u,
|
|
1816
1826
|
formula: "Absolute return = (Current − Invested) / Invested",
|
|
1817
1827
|
raw: { absolute: r.toNumber() }
|
|
1818
1828
|
};
|
|
1819
1829
|
}
|
|
1820
|
-
},
|
|
1830
|
+
}, gr = {
|
|
1821
1831
|
id: "returns.xirr",
|
|
1822
1832
|
group: "returns",
|
|
1823
1833
|
title: "XIRR",
|
|
@@ -1833,7 +1843,7 @@ const Ua = {
|
|
|
1833
1843
|
compute(e, t) {
|
|
1834
1844
|
const a = (e.flows ?? []).filter((u) => u.date && u.amount !== "").map((u) => ({ date: u.date, amount: u.amount }));
|
|
1835
1845
|
if (a.length < 2) return { primary: v("XIRR", "—"), warnings: ["Enter at least two dated cashflows."] };
|
|
1836
|
-
const r =
|
|
1846
|
+
const r = Mn(a);
|
|
1837
1847
|
if (!r) return { primary: v("XIRR", "—"), warnings: ["Need at least one negative and one positive cashflow."] };
|
|
1838
1848
|
const s = r.times(100);
|
|
1839
1849
|
return {
|
|
@@ -1842,7 +1852,7 @@ const Ua = {
|
|
|
1842
1852
|
raw: { xirr: s.toNumber() }
|
|
1843
1853
|
};
|
|
1844
1854
|
}
|
|
1845
|
-
},
|
|
1855
|
+
}, vr = {
|
|
1846
1856
|
id: "returns.irr",
|
|
1847
1857
|
group: "returns",
|
|
1848
1858
|
title: "IRR",
|
|
@@ -1850,12 +1860,12 @@ const Ua = {
|
|
|
1850
1860
|
keywords: ["irr", "internal rate of return"],
|
|
1851
1861
|
inputs: [{ key: "series", label: "Cashflows (comma-separated, period 0 first)", kind: "text", default: "-100000, 30000, 40000, 50000, 40000", help: "-100000, 30000, ..." }],
|
|
1852
1862
|
compute(e, t) {
|
|
1853
|
-
const n =
|
|
1863
|
+
const n = ut(_(e.series));
|
|
1854
1864
|
if (n.length < 2) return { primary: v("IRR", "—"), warnings: ["Enter at least two cashflows."] };
|
|
1855
|
-
const a =
|
|
1865
|
+
const a = Rn(n);
|
|
1856
1866
|
return a ? { primary: v("IRR", `${t.fmt.num(a.times(100), 2)}%`, "accent"), formula: "IRR: rate where NPV = 0", raw: { irr: a.times(100).toNumber() } } : { primary: v("IRR", "—"), warnings: ["No sign change — IRR is undefined for these flows."] };
|
|
1857
1867
|
}
|
|
1858
|
-
},
|
|
1868
|
+
}, kr = {
|
|
1859
1869
|
id: "returns.npv",
|
|
1860
1870
|
group: "returns",
|
|
1861
1871
|
title: "NPV",
|
|
@@ -1866,7 +1876,7 @@ const Ua = {
|
|
|
1866
1876
|
{ key: "series", label: "Cashflows (comma-separated, period 0 first)", kind: "text", default: "-100000, 30000, 40000, 50000, 40000" }
|
|
1867
1877
|
],
|
|
1868
1878
|
compute(e, t) {
|
|
1869
|
-
const n =
|
|
1879
|
+
const n = ut(_(e.series)), a = At(g(C(e.ratePct)).div(100), n);
|
|
1870
1880
|
return {
|
|
1871
1881
|
primary: v("NPV", t.fmt.money(a), a.gte(0) ? "positive" : "negative"),
|
|
1872
1882
|
secondary: [v(a.gte(0) ? "Value-creating" : "Value-destroying", a.gte(0) ? "NPV ≥ 0" : "NPV < 0")],
|
|
@@ -1874,7 +1884,7 @@ const Ua = {
|
|
|
1874
1884
|
raw: { npv: a.toNumber() }
|
|
1875
1885
|
};
|
|
1876
1886
|
}
|
|
1877
|
-
},
|
|
1887
|
+
}, wr = {
|
|
1878
1888
|
id: "returns.mirr",
|
|
1879
1889
|
group: "returns",
|
|
1880
1890
|
title: "MIRR",
|
|
@@ -1886,7 +1896,7 @@ const Ua = {
|
|
|
1886
1896
|
{ key: "reinvestPct", label: "Reinvestment rate", kind: "percent", default: "12" }
|
|
1887
1897
|
],
|
|
1888
1898
|
compute(e, t) {
|
|
1889
|
-
const n =
|
|
1899
|
+
const n = ut(_(e.series)), a = n.length - 1;
|
|
1890
1900
|
if (a < 1) return { primary: v("MIRR", "—"), warnings: ["Enter at least two cashflows."] };
|
|
1891
1901
|
const r = g(C(e.financePct)).div(100), s = g(C(e.reinvestPct)).div(100);
|
|
1892
1902
|
let u = g(0), m = g(0);
|
|
@@ -1896,7 +1906,7 @@ const Ua = {
|
|
|
1896
1906
|
const d = u.div(m.neg()).pow(g(1).div(a)).minus(1).times(100);
|
|
1897
1907
|
return { primary: v("MIRR", `${t.fmt.num(d, 2)}%`, "accent"), formula: "MIRR = (FV(inflows@reinvest) / −PV(outflows@finance))^(1/n) − 1", raw: { mirr: d.toNumber() } };
|
|
1898
1908
|
}
|
|
1899
|
-
},
|
|
1909
|
+
}, Nr = {
|
|
1900
1910
|
id: "returns.payback",
|
|
1901
1911
|
group: "returns",
|
|
1902
1912
|
title: "Payback period",
|
|
@@ -1908,7 +1918,7 @@ const Ua = {
|
|
|
1908
1918
|
{ key: "discountPct", label: "Discount rate (for discounted payback)", kind: "percent", default: "0", optional: !0, advanced: !0 }
|
|
1909
1919
|
],
|
|
1910
1920
|
compute(e, t) {
|
|
1911
|
-
const n = t.D(C(e.investment)), a =
|
|
1921
|
+
const n = t.D(C(e.investment)), a = ut(_(e.series)), r = g(C(e.discountPct)).div(100), s = r.gt(0);
|
|
1912
1922
|
let u = g(0), m = 0, d = null;
|
|
1913
1923
|
for (let i = 0; i < a.length; i++) {
|
|
1914
1924
|
const c = s ? g(a[i]).div(r.plus(1).pow(i + 1)) : g(a[i]), l = u;
|
|
@@ -1925,7 +1935,7 @@ const Ua = {
|
|
|
1925
1935
|
raw: { payback: d }
|
|
1926
1936
|
};
|
|
1927
1937
|
}
|
|
1928
|
-
},
|
|
1938
|
+
}, xr = {
|
|
1929
1939
|
id: "returns.realReturn",
|
|
1930
1940
|
group: "returns",
|
|
1931
1941
|
title: "Real (inflation-adjusted) return",
|
|
@@ -1944,7 +1954,7 @@ const Ua = {
|
|
|
1944
1954
|
raw: { real: r.toNumber() }
|
|
1945
1955
|
};
|
|
1946
1956
|
}
|
|
1947
|
-
},
|
|
1957
|
+
}, Sr = {
|
|
1948
1958
|
id: "returns.rule72",
|
|
1949
1959
|
group: "returns",
|
|
1950
1960
|
title: "Rule of 72",
|
|
@@ -1965,9 +1975,7 @@ const Ua = {
|
|
|
1965
1975
|
raw: { approx: a.toNumber(), exact: r.toNumber() }
|
|
1966
1976
|
};
|
|
1967
1977
|
}
|
|
1968
|
-
},
|
|
1969
|
-
pr,
|
|
1970
|
-
hr,
|
|
1978
|
+
}, Cr = [
|
|
1971
1979
|
fr,
|
|
1972
1980
|
yr,
|
|
1973
1981
|
br,
|
|
@@ -1975,7 +1983,9 @@ const Ua = {
|
|
|
1975
1983
|
vr,
|
|
1976
1984
|
kr,
|
|
1977
1985
|
wr,
|
|
1978
|
-
Nr
|
|
1986
|
+
Nr,
|
|
1987
|
+
xr,
|
|
1988
|
+
Sr
|
|
1979
1989
|
], Ne = "Estimate for planning only — not tax advice. Verify against current law and your own situation.";
|
|
1980
1990
|
function Ut(e, t, n) {
|
|
1981
1991
|
let a = g(0), r = 0;
|
|
@@ -1993,7 +2003,7 @@ function Ut(e, t, n) {
|
|
|
1993
2003
|
}
|
|
1994
2004
|
return { tax: a, rows: s };
|
|
1995
2005
|
}
|
|
1996
|
-
const
|
|
2006
|
+
const Pr = (e, t) => Ut(e, t, Tr).tax, Tr = { money: (e) => String(e) }, jt = (e, t) => e.gt(t) ? g(t) : e, dt = (e, t) => v(e, t, "positive"), Fr = {
|
|
1997
2007
|
id: "tax.gst",
|
|
1998
2008
|
group: "tax",
|
|
1999
2009
|
title: "GST Calculator",
|
|
@@ -2074,7 +2084,7 @@ const Sr = (e, t) => Ut(e, t, Cr).tax, Cr = { money: (e) => String(e) }, jt = (e
|
|
|
2074
2084
|
}
|
|
2075
2085
|
};
|
|
2076
2086
|
}
|
|
2077
|
-
},
|
|
2087
|
+
}, Ir = {
|
|
2078
2088
|
id: "tax.tds",
|
|
2079
2089
|
group: "tax",
|
|
2080
2090
|
title: "TDS on Interest",
|
|
@@ -2108,7 +2118,7 @@ const Sr = (e, t) => Ut(e, t, Cr).tax, Cr = { money: (e) => String(e) }, jt = (e
|
|
|
2108
2118
|
), {
|
|
2109
2119
|
primary: v("TDS deducted", n.money(p), p.gt(0) ? "negative" : "positive"),
|
|
2110
2120
|
secondary: [
|
|
2111
|
-
|
|
2121
|
+
dt("Net interest received", n.money(h)),
|
|
2112
2122
|
v("Effective TDS rate", n.pct(f), "accent"),
|
|
2113
2123
|
v("Applicable threshold", n.money(d), "default")
|
|
2114
2124
|
],
|
|
@@ -2121,7 +2131,7 @@ const Sr = (e, t) => Ut(e, t, Cr).tax, Cr = { money: (e) => String(e) }, jt = (e
|
|
|
2121
2131
|
"<60": [{ to: 25e4, rate: 0 }, { to: 5e5, rate: 5 }, { to: 1e6, rate: 20 }, { to: 1 / 0, rate: 30 }],
|
|
2122
2132
|
"60-80": [{ to: 3e5, rate: 0 }, { to: 5e5, rate: 5 }, { to: 1e6, rate: 20 }, { to: 1 / 0, rate: 30 }],
|
|
2123
2133
|
"80+": [{ to: 5e5, rate: 0 }, { to: 1e6, rate: 20 }, { to: 1 / 0, rate: 30 }]
|
|
2124
|
-
},
|
|
2134
|
+
}, Rr = [
|
|
2125
2135
|
{ to: 3e5, rate: 0 },
|
|
2126
2136
|
{ to: 7e5, rate: 5 },
|
|
2127
2137
|
{ to: 1e6, rate: 10 },
|
|
@@ -2129,7 +2139,7 @@ const Sr = (e, t) => Ut(e, t, Cr).tax, Cr = { money: (e) => String(e) }, jt = (e
|
|
|
2129
2139
|
{ to: 15e5, rate: 20 },
|
|
2130
2140
|
{ to: 1 / 0, rate: 30 }
|
|
2131
2141
|
];
|
|
2132
|
-
function
|
|
2142
|
+
function Er(e, t, n) {
|
|
2133
2143
|
const r = [
|
|
2134
2144
|
{ threshold: 5e7, rate: 25, prev: 20 },
|
|
2135
2145
|
{ threshold: 2e7, rate: 20, prev: 15 },
|
|
@@ -2141,10 +2151,10 @@ function Ir(e, t, n) {
|
|
|
2141
2151
|
return i.gt(0) ? s.minus(i) : s;
|
|
2142
2152
|
}
|
|
2143
2153
|
function Yt(e, t, n, a, r) {
|
|
2144
|
-
const { tax: s, rows: u } = Ut(e, t, r), m = e.gt(n) ? g(0) : s.lt(a) ? s : g(a), d = s.minus(m), i =
|
|
2154
|
+
const { tax: s, rows: u } = Ut(e, t, r), m = e.gt(n) ? g(0) : s.lt(a) ? s : g(a), d = s.minus(m), i = Er(e, d, (p) => Pr(g(p), t)), c = d.plus(i).times("0.04"), l = d.plus(i).plus(c);
|
|
2145
2155
|
return { taxable: e, base: s, rebate: m, surcharge: i, cess: c, total: l, rows: u };
|
|
2146
2156
|
}
|
|
2147
|
-
const
|
|
2157
|
+
const Mr = {
|
|
2148
2158
|
id: "tax.incomeIN",
|
|
2149
2159
|
group: "tax",
|
|
2150
2160
|
title: "Income Tax (Old vs New)",
|
|
@@ -2170,7 +2180,7 @@ const Rr = {
|
|
|
2170
2180
|
{ key: "homeLoanInterest", label: "Home loan interest (24b)", kind: "money", prefix: "currency", default: "0", help: "max ₹2L", optional: !0 }
|
|
2171
2181
|
],
|
|
2172
2182
|
compute(e, t) {
|
|
2173
|
-
const { fmt: n } = t, a = D(e.grossIncome, "1200000"), r = _(e.age, "<60"), s = jt(D(e.ded80C, "0"), 15e4), u = D(e.ded80D, "0"), m = D(e.hraExemption, "0"), d = jt(D(e.homeLoanInterest, "0"), 2e5), i = g(5e4).plus(s).plus(u).plus(m).plus(d), c = a.minus(i), l = c.gt(0) ? c : g(0), p = Yt(l, Vt[r] ?? Vt["<60"], 5e5, 12500, n), h = a.minus(75e3), f = h.gt(0) ? h : g(0), y = Yt(f,
|
|
2183
|
+
const { fmt: n } = t, a = D(e.grossIncome, "1200000"), r = _(e.age, "<60"), s = jt(D(e.ded80C, "0"), 15e4), u = D(e.ded80D, "0"), m = D(e.hraExemption, "0"), d = jt(D(e.homeLoanInterest, "0"), 2e5), i = g(5e4).plus(s).plus(u).plus(m).plus(d), c = a.minus(i), l = c.gt(0) ? c : g(0), p = Yt(l, Vt[r] ?? Vt["<60"], 5e5, 12500, n), h = a.minus(75e3), f = h.gt(0) ? h : g(0), y = Yt(f, Rr, 7e5, 25e3, n), w = !y.total.gt(p.total), k = w ? y : p, S = p.total.minus(y.total).abs();
|
|
2174
2184
|
return {
|
|
2175
2185
|
primary: v(
|
|
2176
2186
|
`${w ? "New" : "Old"} regime is cheaper`,
|
|
@@ -2206,7 +2216,7 @@ const Rr = {
|
|
|
2206
2216
|
}
|
|
2207
2217
|
};
|
|
2208
2218
|
}
|
|
2209
|
-
},
|
|
2219
|
+
}, $r = {
|
|
2210
2220
|
id: "tax.capitalGains",
|
|
2211
2221
|
group: "tax",
|
|
2212
2222
|
title: "Capital Gains Tax",
|
|
@@ -2255,7 +2265,7 @@ const Rr = {
|
|
|
2255
2265
|
raw: { gain: d.toFixed(2), tax: h ? null : l.toFixed(2), type: p, isLong: c ? 1 : 0 }
|
|
2256
2266
|
};
|
|
2257
2267
|
}
|
|
2258
|
-
},
|
|
2268
|
+
}, Ar = {
|
|
2259
2269
|
id: "tax.hra",
|
|
2260
2270
|
group: "tax",
|
|
2261
2271
|
title: "HRA Exemption",
|
|
@@ -2275,7 +2285,7 @@ const Rr = {
|
|
|
2275
2285
|
l.lt(h) && (h = l), p.lt(h) && (h = p);
|
|
2276
2286
|
const f = s.minus(h);
|
|
2277
2287
|
return {
|
|
2278
|
-
primary:
|
|
2288
|
+
primary: dt("HRA exempt", n.money(h)),
|
|
2279
2289
|
secondary: [
|
|
2280
2290
|
v("Taxable HRA", n.money(f), "negative"),
|
|
2281
2291
|
v("HRA received", n.money(s), "principal"),
|
|
@@ -2290,7 +2300,7 @@ const Rr = {
|
|
|
2290
2300
|
raw: { exempt: h.toFixed(2), taxable: f.toFixed(2), limitRent: l.toFixed(2), limitPct: p.toFixed(2) }
|
|
2291
2301
|
};
|
|
2292
2302
|
}
|
|
2293
|
-
},
|
|
2303
|
+
}, Dr = {
|
|
2294
2304
|
id: "tax.advanceTax",
|
|
2295
2305
|
group: "tax",
|
|
2296
2306
|
title: "Advance Tax Instalments",
|
|
@@ -2331,7 +2341,7 @@ const Rr = {
|
|
|
2331
2341
|
raw: { advanceTaxDue: u.toFixed(2), liability: a.toFixed(2), tdsPaid: r.toFixed(2) }
|
|
2332
2342
|
};
|
|
2333
2343
|
}
|
|
2334
|
-
},
|
|
2344
|
+
}, Lr = {
|
|
2335
2345
|
id: "tax.salesTaxUS",
|
|
2336
2346
|
group: "tax",
|
|
2337
2347
|
title: "Sales Tax",
|
|
@@ -2389,7 +2399,7 @@ const Rr = {
|
|
|
2389
2399
|
{ to: 609350, rate: 35 },
|
|
2390
2400
|
{ to: 1 / 0, rate: 37 }
|
|
2391
2401
|
]
|
|
2392
|
-
},
|
|
2402
|
+
}, Ur = { single: 14600, marriedJoint: 29200, headOfHousehold: 21900 }, Or = {
|
|
2393
2403
|
id: "tax.incomeUS",
|
|
2394
2404
|
group: "tax",
|
|
2395
2405
|
title: "Federal Income Tax",
|
|
@@ -2429,14 +2439,14 @@ const Rr = {
|
|
|
2429
2439
|
}
|
|
2430
2440
|
],
|
|
2431
2441
|
compute(e, t) {
|
|
2432
|
-
const { fmt: n } = t, a = D(e.grossIncome, "60000"), r = _(e.filingStatus, "single"), s = Kt[r] ?? Kt.single, m = _(e.deductionMode, "standard") === "itemized" ? D(e.itemizedAmount, "0") : g(
|
|
2442
|
+
const { fmt: n } = t, a = D(e.grossIncome, "60000"), r = _(e.filingStatus, "single"), s = Kt[r] ?? Kt.single, m = _(e.deductionMode, "standard") === "itemized" ? D(e.itemizedAmount, "0") : g(Ur[r] ?? 14600), d = a.minus(m), i = d.gt(0) ? d : g(0), { tax: c, rows: l } = Ut(i, s, n), p = a.gt(0) ? c.div(a).times(100) : g(0), h = s.find((w) => i.lte(w.to)) ?? s[s.length - 1], f = i.gt(0) ? h.rate : 0, y = a.minus(c);
|
|
2433
2443
|
return {
|
|
2434
2444
|
primary: v("Federal income tax", n.money(c), "negative"),
|
|
2435
2445
|
secondary: [
|
|
2436
2446
|
v("Taxable income", n.money(i), "principal", `after ${n.money(m)} deduction`),
|
|
2437
2447
|
v("Effective rate", n.pct(p), "accent"),
|
|
2438
2448
|
v("Marginal rate", `${f}%`, "default"),
|
|
2439
|
-
|
|
2449
|
+
dt("After-tax income", n.money(y))
|
|
2440
2450
|
],
|
|
2441
2451
|
schedule: {
|
|
2442
2452
|
title: "Bracket breakdown",
|
|
@@ -2458,7 +2468,7 @@ const Rr = {
|
|
|
2458
2468
|
}
|
|
2459
2469
|
};
|
|
2460
2470
|
}
|
|
2461
|
-
},
|
|
2471
|
+
}, Br = {
|
|
2462
2472
|
id: "tax.mortgageDeductionUS",
|
|
2463
2473
|
group: "tax",
|
|
2464
2474
|
title: "Mortgage Interest Deduction",
|
|
@@ -2476,7 +2486,7 @@ const Rr = {
|
|
|
2476
2486
|
"Acquisition-debt limit is $750,000 ($375,000 if married filing separately) for loans after 15 Dec 2017. " + Ne
|
|
2477
2487
|
];
|
|
2478
2488
|
return s.gt(u) && i.unshift(`Loan balance exceeds $750k: only ${n.pct(g(u).div(s).times(100))} of the interest is deductible.`), {
|
|
2479
|
-
primary:
|
|
2489
|
+
primary: dt("Estimated tax savings", n.money(d)),
|
|
2480
2490
|
secondary: [
|
|
2481
2491
|
v("Deductible interest", n.money(m), "principal"),
|
|
2482
2492
|
v("Marginal tax rate", n.pct(g(C(e.marginalTaxRatePct, 24))), "accent")
|
|
@@ -2486,16 +2496,16 @@ const Rr = {
|
|
|
2486
2496
|
raw: { savings: d.toFixed(2), deductibleInterest: m.toFixed(2) }
|
|
2487
2497
|
};
|
|
2488
2498
|
}
|
|
2489
|
-
},
|
|
2490
|
-
|
|
2491
|
-
|
|
2492
|
-
Rr,
|
|
2493
|
-
Er,
|
|
2499
|
+
}, _r = [
|
|
2500
|
+
Fr,
|
|
2501
|
+
Ir,
|
|
2494
2502
|
Mr,
|
|
2495
2503
|
$r,
|
|
2496
2504
|
Ar,
|
|
2505
|
+
Dr,
|
|
2497
2506
|
Lr,
|
|
2498
|
-
|
|
2507
|
+
Or,
|
|
2508
|
+
Br
|
|
2499
2509
|
], $e = {
|
|
2500
2510
|
length: { m: 1, km: 1e3, cm: 0.01, mm: 1e-3, mi: 1609.344, yd: 0.9144, ft: 0.3048, in: 0.0254 },
|
|
2501
2511
|
area: { sqm: 1, sqft: 0.092903, sqyd: 0.836127, acre: 4046.8564224, hectare: 1e4, bigha: 1337.8, gunta: 101.17, cent: 40.4686 },
|
|
@@ -2535,10 +2545,10 @@ const Rr = {
|
|
|
2535
2545
|
C: "Celsius (°C)",
|
|
2536
2546
|
F: "Fahrenheit (°F)",
|
|
2537
2547
|
K: "Kelvin (K)"
|
|
2538
|
-
},
|
|
2548
|
+
}, Hr = ["C", "F", "K"], Wt = (e) => e.map((t) => ({ value: t, label: Pt[t] ?? t })), Ae = (e, t, n, a) => [
|
|
2539
2549
|
{ key: `${e}From`, label: "From", kind: "select", default: n, options: Wt(t), showIf: (r) => r.category === e },
|
|
2540
2550
|
{ key: `${e}To`, label: "To", kind: "select", default: a, options: Wt(t), showIf: (r) => r.category === e }
|
|
2541
|
-
],
|
|
2551
|
+
], qr = {
|
|
2542
2552
|
id: "tools.units",
|
|
2543
2553
|
group: "tools",
|
|
2544
2554
|
title: "Unit Converter",
|
|
@@ -2563,7 +2573,7 @@ const Rr = {
|
|
|
2563
2573
|
...Ae("area", Object.keys($e.area), "acre", "sqm"),
|
|
2564
2574
|
...Ae("weight", Object.keys($e.weight), "kg", "lb"),
|
|
2565
2575
|
...Ae("volume", Object.keys($e.volume), "l", "gal_us"),
|
|
2566
|
-
...Ae("temperature",
|
|
2576
|
+
...Ae("temperature", Hr, "C", "F")
|
|
2567
2577
|
],
|
|
2568
2578
|
compute(e, t) {
|
|
2569
2579
|
const { D: n, fmt: a } = t, r = n(C(e.value, 0)), s = _(e.category, "length"), u = _(e[`${s}From`], ""), m = _(e[`${s}To`], ""), d = [];
|
|
@@ -2582,14 +2592,14 @@ const Rr = {
|
|
|
2582
2592
|
raw: { result: i.toFixed(6), from: u, to: m, category: s }
|
|
2583
2593
|
};
|
|
2584
2594
|
}
|
|
2585
|
-
},
|
|
2595
|
+
}, Ve = 864e5, ft = (e) => {
|
|
2586
2596
|
if (!e) {
|
|
2587
2597
|
const r = /* @__PURE__ */ new Date();
|
|
2588
2598
|
return new Date(Date.UTC(r.getUTCFullYear(), r.getUTCMonth(), r.getUTCDate()));
|
|
2589
2599
|
}
|
|
2590
2600
|
const [t, n, a] = e.split("-").map(Number);
|
|
2591
2601
|
return new Date(Date.UTC(t, (n || 1) - 1, a || 1));
|
|
2592
|
-
}, yt = (e, t) => new Date(Date.UTC(e, t, 0)).getUTCDate(),
|
|
2602
|
+
}, yt = (e, t) => new Date(Date.UTC(e, t, 0)).getUTCDate(), Ye = (e) => e.toISOString().slice(0, 10), Gr = {
|
|
2593
2603
|
id: "tools.dateCalc",
|
|
2594
2604
|
group: "tools",
|
|
2595
2605
|
title: "Date Calculator",
|
|
@@ -2639,7 +2649,7 @@ const Rr = {
|
|
|
2639
2649
|
const l = ft(_(e.startDate, "")), p = Math.round(C(e.count, 0)), h = _(e.unit, "days"), f = _(e.direction, "add") === "subtract" ? -1 : 1, y = f * p;
|
|
2640
2650
|
let w;
|
|
2641
2651
|
if (h === "days" || h === "weeks")
|
|
2642
|
-
w = new Date(l.getTime() + y * (h === "weeks" ? 7 : 1) *
|
|
2652
|
+
w = new Date(l.getTime() + y * (h === "weeks" ? 7 : 1) * Ve);
|
|
2643
2653
|
else if (h === "months") {
|
|
2644
2654
|
const S = l.getUTCMonth() + y, F = l.getUTCFullYear() + Math.floor(S / 12), N = (S % 12 + 12) % 12, P = Math.min(l.getUTCDate(), yt(F, N + 1));
|
|
2645
2655
|
w = new Date(Date.UTC(F, N, P));
|
|
@@ -2649,18 +2659,18 @@ const Rr = {
|
|
|
2649
2659
|
}
|
|
2650
2660
|
const k = ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"][w.getUTCDay()];
|
|
2651
2661
|
return {
|
|
2652
|
-
primary: v("Result date",
|
|
2653
|
-
secondary: [v("From",
|
|
2654
|
-
raw: { resultDate:
|
|
2662
|
+
primary: v("Result date", Ye(w), "accent", k),
|
|
2663
|
+
secondary: [v("From", Ye(l)), v("Shift", `${f < 0 ? "−" : "+"}${p} ${h}`)],
|
|
2664
|
+
raw: { resultDate: Ye(w), weekday: k, from: Ye(l) }
|
|
2655
2665
|
};
|
|
2656
2666
|
}
|
|
2657
2667
|
let n = ft(_(e.startDate, "")), a = ft(_(e.endDate, "")), r = !1;
|
|
2658
2668
|
a.getTime() < n.getTime() && ([n, a] = [a, n], r = !0);
|
|
2659
2669
|
let s = a.getUTCFullYear() - n.getUTCFullYear(), u = a.getUTCMonth() - n.getUTCMonth(), m = a.getUTCDate() - n.getUTCDate();
|
|
2660
2670
|
m < 0 && (u -= 1, m += yt(a.getUTCFullYear(), a.getUTCMonth())), u < 0 && (s -= 1, u += 12);
|
|
2661
|
-
const d = Math.round((a.getTime() - n.getTime()) /
|
|
2671
|
+
const d = Math.round((a.getTime() - n.getTime()) / Ve);
|
|
2662
2672
|
let i = 0;
|
|
2663
|
-
for (let l = n.getTime() +
|
|
2673
|
+
for (let l = n.getTime() + Ve; l <= a.getTime(); l += Ve) {
|
|
2664
2674
|
const p = new Date(l).getUTCDay();
|
|
2665
2675
|
p !== 0 && p !== 6 && i++;
|
|
2666
2676
|
}
|
|
@@ -2676,10 +2686,10 @@ const Rr = {
|
|
|
2676
2686
|
raw: { years: s, months: u, days: m, totalDays: d, weeks: Number((d / 7).toFixed(2)), businessDays: i }
|
|
2677
2687
|
};
|
|
2678
2688
|
}
|
|
2679
|
-
}, Tt = ["Zero", "One", "Two", "Three", "Four", "Five", "Six", "Seven", "Eight", "Nine", "Ten", "Eleven", "Twelve", "Thirteen", "Fourteen", "Fifteen", "Sixteen", "Seventeen", "Eighteen", "Nineteen"],
|
|
2689
|
+
}, Tt = ["Zero", "One", "Two", "Three", "Four", "Five", "Six", "Seven", "Eight", "Nine", "Ten", "Eleven", "Twelve", "Thirteen", "Fourteen", "Fifteen", "Sixteen", "Seventeen", "Eighteen", "Nineteen"], jr = ["", "", "Twenty", "Thirty", "Forty", "Fifty", "Sixty", "Seventy", "Eighty", "Ninety"], at = (e) => e < 20 ? Tt[e] : jr[Math.floor(e / 10)] + (e % 10 ? " " + Tt[e % 10] : ""), Ft = (e) => {
|
|
2680
2690
|
const t = Math.floor(e / 100), n = e % 100, a = [];
|
|
2681
|
-
return t && a.push(Tt[t] + " Hundred"), n && a.push(
|
|
2682
|
-
},
|
|
2691
|
+
return t && a.push(Tt[t] + " Hundred"), n && a.push(at(n)), a.join(" ");
|
|
2692
|
+
}, Ln = (e) => {
|
|
2683
2693
|
if (e === 0) return "Zero";
|
|
2684
2694
|
const t = ["", " Thousand", " Million", " Billion", " Trillion"], n = [];
|
|
2685
2695
|
let a = 0;
|
|
@@ -2688,11 +2698,11 @@ const Rr = {
|
|
|
2688
2698
|
r && n.unshift(Ft(r) + t[a]), e = Math.floor(e / 1e3), a++;
|
|
2689
2699
|
}
|
|
2690
2700
|
return n.length ? n.join(" ") : "Zero";
|
|
2691
|
-
},
|
|
2701
|
+
}, Vr = (e) => {
|
|
2692
2702
|
if (e === 0) return "Zero";
|
|
2693
2703
|
const t = Math.floor(e / 1e7), n = Math.floor(e / 1e5) % 100, a = Math.floor(e / 1e3) % 100, r = e % 1e3, s = [];
|
|
2694
|
-
return t && s.push((t <= 999 ? Ft(t) :
|
|
2695
|
-
},
|
|
2704
|
+
return t && s.push((t <= 999 ? Ft(t) : Ln(t)) + " Crore"), n && s.push(at(n) + " Lakh"), a && s.push(at(a) + " Thousand"), r && s.push(Ft(r)), s.join(" ");
|
|
2705
|
+
}, Yr = {
|
|
2696
2706
|
id: "tools.numToWords",
|
|
2697
2707
|
group: "tools",
|
|
2698
2708
|
title: "Number to Words",
|
|
@@ -2714,15 +2724,15 @@ const Rr = {
|
|
|
2714
2724
|
],
|
|
2715
2725
|
compute(e, t) {
|
|
2716
2726
|
const { D: n, fmt: a } = t, r = _(e.scale, "indian"), s = ye(e.cheque, !1), u = n(_(e.amount, "0").replace(/[, ]/g, "") || "0"), m = u.isNegative(), d = u.abs(), i = d.floor(), c = Number(d.minus(i).times(100).toDecimalPlaces(0).toString()), l = Number(i.toString()), p = t.settings.currency.code, h = p === "INR" ? "Rupees" : p === "USD" ? "Dollars" : p, f = p === "INR" ? "Paise" : "Cents";
|
|
2717
|
-
let y = r === "western" ?
|
|
2718
|
-
return c > 0 && (y += ` and ${
|
|
2727
|
+
let y = r === "western" ? Ln(l) : Vr(l);
|
|
2728
|
+
return c > 0 && (y += ` and ${at(c)} ${f}`), s && (y = `${h} ${y} Only`), m && (y = `Minus ${y}`), {
|
|
2719
2729
|
primary: v("In words", y, "accent"),
|
|
2720
2730
|
secondary: [v("In figures", a.num(u, c > 0 ? 2 : 0))],
|
|
2721
2731
|
notes: ['Words are Title Case with the chosen number scale; the cheque format adds the currency name and "Only".'],
|
|
2722
2732
|
raw: { words: y, integer: l, fraction: c }
|
|
2723
2733
|
};
|
|
2724
2734
|
}
|
|
2725
|
-
},
|
|
2735
|
+
}, Kr = [qr, Gr, Yr], Wr = [
|
|
2726
2736
|
{
|
|
2727
2737
|
id: "tools.scientific",
|
|
2728
2738
|
group: "tools",
|
|
@@ -2733,7 +2743,7 @@ const Rr = {
|
|
|
2733
2743
|
compute: () => ({ primary: { label: "Scientific calculator", value: "" } }),
|
|
2734
2744
|
custom: "scientific"
|
|
2735
2745
|
}
|
|
2736
|
-
],
|
|
2746
|
+
], zr = {
|
|
2737
2747
|
id: "loan.emi",
|
|
2738
2748
|
group: "loans",
|
|
2739
2749
|
title: "EMI / Loan",
|
|
@@ -2742,7 +2752,7 @@ const Rr = {
|
|
|
2742
2752
|
inputs: [],
|
|
2743
2753
|
compute: () => ({ primary: { label: "", value: "" } }),
|
|
2744
2754
|
custom: "loan.emi"
|
|
2745
|
-
},
|
|
2755
|
+
}, Jr = {
|
|
2746
2756
|
id: "tools.currency",
|
|
2747
2757
|
group: "tools",
|
|
2748
2758
|
title: "Currency converter",
|
|
@@ -2751,49 +2761,49 @@ const Rr = {
|
|
|
2751
2761
|
inputs: [],
|
|
2752
2762
|
compute: () => ({ primary: { label: "", value: "" } }),
|
|
2753
2763
|
custom: "currency"
|
|
2754
|
-
},
|
|
2755
|
-
|
|
2756
|
-
|
|
2757
|
-
...
|
|
2758
|
-
...
|
|
2759
|
-
...
|
|
2760
|
-
...
|
|
2761
|
-
...
|
|
2762
|
-
...
|
|
2763
|
-
...
|
|
2764
|
-
...
|
|
2764
|
+
}, Zr = [
|
|
2765
|
+
zr,
|
|
2766
|
+
Jr,
|
|
2767
|
+
...Ka,
|
|
2768
|
+
...nr,
|
|
2769
|
+
...cr,
|
|
2770
|
+
...pr,
|
|
2771
|
+
...Cr,
|
|
2772
|
+
..._r,
|
|
2773
|
+
...Kr,
|
|
2774
|
+
...Wr
|
|
2765
2775
|
], It = [];
|
|
2766
|
-
function
|
|
2776
|
+
function bs(e) {
|
|
2767
2777
|
It.some((t) => t.id === e.id) || It.push(e);
|
|
2768
2778
|
}
|
|
2769
|
-
function
|
|
2770
|
-
return [...
|
|
2779
|
+
function Un() {
|
|
2780
|
+
return [...Zr, ...It];
|
|
2771
2781
|
}
|
|
2772
|
-
function
|
|
2773
|
-
return
|
|
2782
|
+
function Xr(e) {
|
|
2783
|
+
return Un().filter((t) => !t.regions || t.regions.includes(e));
|
|
2774
2784
|
}
|
|
2775
2785
|
function Rt(e) {
|
|
2776
|
-
return
|
|
2786
|
+
return Un().find((t) => t.id === e);
|
|
2777
2787
|
}
|
|
2778
|
-
const
|
|
2788
|
+
const Qr = [
|
|
2779
2789
|
{ id: "loans", label: "Loans" },
|
|
2780
2790
|
{ id: "invest", label: "Invest" },
|
|
2781
2791
|
{ id: "returns", label: "Returns" },
|
|
2782
2792
|
{ id: "tax", label: "Tax" },
|
|
2783
2793
|
{ id: "tools", label: "Tools" }
|
|
2784
2794
|
];
|
|
2785
|
-
function
|
|
2795
|
+
function eo(e, t) {
|
|
2786
2796
|
var n;
|
|
2787
2797
|
return ((n = e.labelByRegion) == null ? void 0 : n[t]) ?? e.label;
|
|
2788
2798
|
}
|
|
2789
|
-
function
|
|
2799
|
+
function to({
|
|
2790
2800
|
f: e,
|
|
2791
2801
|
value: t,
|
|
2792
2802
|
onChange: n,
|
|
2793
2803
|
values: a
|
|
2794
2804
|
}) {
|
|
2795
2805
|
var i, c;
|
|
2796
|
-
const { settings: r } = ue(), s = r.region, u =
|
|
2806
|
+
const { settings: r } = ue(), s = r.region, u = eo(e, s), m = r.currency.symbol, d = t == null ? "" : String(t);
|
|
2797
2807
|
switch (e.kind) {
|
|
2798
2808
|
case "money":
|
|
2799
2809
|
case "number":
|
|
@@ -2831,7 +2841,7 @@ function Qr({
|
|
|
2831
2841
|
] })
|
|
2832
2842
|
] });
|
|
2833
2843
|
case "tenure":
|
|
2834
|
-
return /* @__PURE__ */ o(
|
|
2844
|
+
return /* @__PURE__ */ o(no, { f: e, label: u, months: Number(t) || 0, onChange: n });
|
|
2835
2845
|
case "select":
|
|
2836
2846
|
return /* @__PURE__ */ b("label", { className: "field", children: [
|
|
2837
2847
|
/* @__PURE__ */ o("span", { className: "lbl", children: u }),
|
|
@@ -2869,12 +2879,12 @@ function Qr({
|
|
|
2869
2879
|
/* @__PURE__ */ o("div", { className: "input-wrap", children: /* @__PURE__ */ o("input", { value: d, placeholder: e.help, onChange: (l) => n(l.target.value), "aria-label": u }) })
|
|
2870
2880
|
] });
|
|
2871
2881
|
case "cashflows":
|
|
2872
|
-
return /* @__PURE__ */ o(
|
|
2882
|
+
return /* @__PURE__ */ o(ao, { f: e, label: u, value: t ?? [], onChange: n });
|
|
2873
2883
|
default:
|
|
2874
2884
|
return null;
|
|
2875
2885
|
}
|
|
2876
2886
|
}
|
|
2877
|
-
function
|
|
2887
|
+
function no({
|
|
2878
2888
|
f: e,
|
|
2879
2889
|
label: t,
|
|
2880
2890
|
months: n,
|
|
@@ -2914,7 +2924,7 @@ function eo({
|
|
|
2914
2924
|
e.suffix && /* @__PURE__ */ o("div", { className: "solved-note", children: e.suffix })
|
|
2915
2925
|
] });
|
|
2916
2926
|
}
|
|
2917
|
-
function
|
|
2927
|
+
function ao({
|
|
2918
2928
|
label: e,
|
|
2919
2929
|
value: t,
|
|
2920
2930
|
onChange: n
|
|
@@ -2937,7 +2947,7 @@ function to({
|
|
|
2937
2947
|
/* @__PURE__ */ o("button", { type: "button", className: "icon-btn", onClick: () => s([...a, { date: "", amount: "" }]), children: "+ Add cashflow" })
|
|
2938
2948
|
] });
|
|
2939
2949
|
}
|
|
2940
|
-
const
|
|
2950
|
+
const On = {
|
|
2941
2951
|
principal: "pr-txt",
|
|
2942
2952
|
interest: "in-txt",
|
|
2943
2953
|
accent: "accent-txt",
|
|
@@ -2945,11 +2955,11 @@ const Un = {
|
|
|
2945
2955
|
negative: "neg-txt",
|
|
2946
2956
|
default: ""
|
|
2947
2957
|
};
|
|
2948
|
-
function
|
|
2958
|
+
function ro({ view: e }) {
|
|
2949
2959
|
const { settings: t } = ue(), n = t.currency.symbol, a = e.primary.value, r = a.startsWith(n), s = r ? a.slice(n.length).trim() : a, u = /[A-Za-z]{3,}/.test(a);
|
|
2950
2960
|
return /* @__PURE__ */ b("div", { className: "result", "aria-live": "polite", children: [
|
|
2951
2961
|
/* @__PURE__ */ o("div", { className: "label", children: e.primary.label }),
|
|
2952
|
-
/* @__PURE__ */ b("div", { className: `value num ${u ? "value-text" : ""} ${
|
|
2962
|
+
/* @__PURE__ */ b("div", { className: `value num ${u ? "value-text" : ""} ${On[e.primary.tone ?? "default"]}`, children: [
|
|
2953
2963
|
r && /* @__PURE__ */ o("span", { className: "cur", children: n }),
|
|
2954
2964
|
s,
|
|
2955
2965
|
e.primaryPer && /* @__PURE__ */ b("span", { className: "per", children: [
|
|
@@ -2958,18 +2968,18 @@ function no({ view: e }) {
|
|
|
2958
2968
|
] })
|
|
2959
2969
|
] }),
|
|
2960
2970
|
e.primary.sub && /* @__PURE__ */ o("div", { className: "per", children: e.primary.sub }),
|
|
2961
|
-
e.split && e.split.length > 0 && /* @__PURE__ */ o(
|
|
2962
|
-
e.secondary && e.secondary.length > 0 && /* @__PURE__ */ o("div", { className: "secondary", children: e.secondary.map((m, d) => /* @__PURE__ */ o(
|
|
2971
|
+
e.split && e.split.length > 0 && /* @__PURE__ */ o(io, { split: e.split }),
|
|
2972
|
+
e.secondary && e.secondary.length > 0 && /* @__PURE__ */ o("div", { className: "secondary", children: e.secondary.map((m, d) => /* @__PURE__ */ o(oo, { m }, d)) })
|
|
2963
2973
|
] });
|
|
2964
2974
|
}
|
|
2965
|
-
function
|
|
2975
|
+
function oo({ m: e }) {
|
|
2966
2976
|
return /* @__PURE__ */ b("div", { className: "kv", children: [
|
|
2967
2977
|
/* @__PURE__ */ o("div", { className: "k", children: e.label }),
|
|
2968
|
-
/* @__PURE__ */ o("div", { className: `v num ${
|
|
2978
|
+
/* @__PURE__ */ o("div", { className: `v num ${On[e.tone ?? "default"]}`, children: e.value }),
|
|
2969
2979
|
e.sub && /* @__PURE__ */ o("div", { className: "k", children: e.sub })
|
|
2970
2980
|
] });
|
|
2971
2981
|
}
|
|
2972
|
-
function
|
|
2982
|
+
function io({ split: e }) {
|
|
2973
2983
|
const t = e.reduce((a, r) => a + Math.max(0, r.value), 0) || 1, n = e.map((a) => Math.round(Math.max(0, a.value) / t * 100));
|
|
2974
2984
|
return /* @__PURE__ */ b(re, { children: [
|
|
2975
2985
|
/* @__PURE__ */ o("div", { className: "splitbar", role: "img", "aria-label": e.map((a, r) => `${a.label} ${n[r]}%`).join(", "), children: e.map((a, r) => /* @__PURE__ */ o("div", { className: a.tone, style: { width: `${n[r]}%` } }, r)) }),
|
|
@@ -2982,7 +2992,7 @@ function ro({ split: e }) {
|
|
|
2982
2992
|
] }, r)) })
|
|
2983
2993
|
] });
|
|
2984
2994
|
}
|
|
2985
|
-
function
|
|
2995
|
+
function so({ schedule: e }) {
|
|
2986
2996
|
var u;
|
|
2987
2997
|
const [t, n] = M(/* @__PURE__ */ new Set([0])), a = (m) => {
|
|
2988
2998
|
var d;
|
|
@@ -3024,7 +3034,7 @@ const zt = {
|
|
|
3024
3034
|
interest: "var(--fc-interest)",
|
|
3025
3035
|
accent: "var(--fc-accent)"
|
|
3026
3036
|
};
|
|
3027
|
-
function
|
|
3037
|
+
function lo({ chart: e }) {
|
|
3028
3038
|
const m = Math.max(...e.series.map((h) => h.points.length), 1), d = Math.max(...e.series.flatMap((h) => h.points), 1), i = (h) => 8 + h / Math.max(m - 1, 1) * 704, c = (h) => 12 + (1 - h / d) * 226, l = (h) => h.map((f, y) => `${y === 0 ? "M" : "L"}${i(y).toFixed(1)},${c(f).toFixed(1)}`).join(" "), p = (h) => `M${i(0)},${c(0)} ${h.map((f, y) => `L${i(y).toFixed(1)},${c(f).toFixed(1)}`).join(" ")} L${i(h.length - 1)},${c(0)} Z`;
|
|
3029
3039
|
return /* @__PURE__ */ b("div", { className: "chart", children: [
|
|
3030
3040
|
/* @__PURE__ */ b("svg", { viewBox: "0 0 720 260", role: "img", "aria-label": "Projection chart", children: [
|
|
@@ -3040,7 +3050,7 @@ function io({ chart: e }) {
|
|
|
3040
3050
|
] }, f)) })
|
|
3041
3051
|
] });
|
|
3042
3052
|
}
|
|
3043
|
-
const
|
|
3053
|
+
const Bn = 1, co = [
|
|
3044
3054
|
{ id: "csv", label: "CSV (.csv)" },
|
|
3045
3055
|
{ id: "tsv", label: "TSV (.tsv)" },
|
|
3046
3056
|
{ id: "json", label: "JSON (.json)" },
|
|
@@ -3069,7 +3079,7 @@ function _e(e) {
|
|
|
3069
3079
|
for (const n of e.rows) t.push([n.label, ...n.cells]);
|
|
3070
3080
|
return { header: e.columns, rows: t };
|
|
3071
3081
|
}
|
|
3072
|
-
function
|
|
3082
|
+
function uo(e) {
|
|
3073
3083
|
var t;
|
|
3074
3084
|
return e ? e.groups ? e.groups.reduce((n, a) => n + a.rows.length, 0) : ((t = e.rows) == null ? void 0 : t.length) ?? 0 : 0;
|
|
3075
3085
|
}
|
|
@@ -3089,32 +3099,32 @@ function Se(e, t, n = "application/octet-stream") {
|
|
|
3089
3099
|
URL.revokeObjectURL(r), s.remove();
|
|
3090
3100
|
}, 0);
|
|
3091
3101
|
}
|
|
3092
|
-
function
|
|
3102
|
+
function mo(e, t) {
|
|
3093
3103
|
let n = e == null ? "" : String(e);
|
|
3094
3104
|
return /^[=+\-@\t\r]/.test(n) && (n = `'${n}`), (n.includes(t) || n.includes('"') || n.includes(`
|
|
3095
3105
|
`) || n.includes("\r")) && (n = `"${n.replace(/"/g, '""')}"`), n;
|
|
3096
3106
|
}
|
|
3097
|
-
function
|
|
3107
|
+
function po(e) {
|
|
3098
3108
|
var t;
|
|
3099
3109
|
return ((t = e == null ? void 0 : e.numberFormat) == null ? void 0 : t.grouping) === "european" ? ";" : ",";
|
|
3100
3110
|
}
|
|
3101
|
-
function
|
|
3111
|
+
function _n(e, t) {
|
|
3102
3112
|
const n = [["ArthaGanaka export"], ["Calculator", e.title]];
|
|
3103
3113
|
for (const a of Re(e)) n.push(a);
|
|
3104
3114
|
if (n.push([]), e.result.schedule) {
|
|
3105
3115
|
const a = _e(e.result.schedule);
|
|
3106
3116
|
n.push(a.header, ...a.rows);
|
|
3107
3117
|
}
|
|
3108
|
-
return n.map((a) => a.map((r) =>
|
|
3118
|
+
return n.map((a) => a.map((r) => mo(r, t)).join(t)).join(`\r
|
|
3109
3119
|
`);
|
|
3110
3120
|
}
|
|
3111
|
-
function
|
|
3112
|
-
return
|
|
3121
|
+
function ho(e) {
|
|
3122
|
+
return _n(e, po(e.settingsSnapshot));
|
|
3113
3123
|
}
|
|
3114
|
-
function
|
|
3115
|
-
return
|
|
3124
|
+
function fo(e) {
|
|
3125
|
+
return _n(e, " ");
|
|
3116
3126
|
}
|
|
3117
|
-
function
|
|
3127
|
+
function yo(e, t = Bn) {
|
|
3118
3128
|
return JSON.stringify(
|
|
3119
3129
|
{
|
|
3120
3130
|
schemaVersion: t,
|
|
@@ -3134,7 +3144,7 @@ function ho(e, t = On) {
|
|
|
3134
3144
|
2
|
|
3135
3145
|
);
|
|
3136
3146
|
}
|
|
3137
|
-
function
|
|
3147
|
+
function bo(e) {
|
|
3138
3148
|
const t = new TextEncoder().encode(e);
|
|
3139
3149
|
if (typeof btoa == "function") {
|
|
3140
3150
|
let n = "";
|
|
@@ -3143,41 +3153,41 @@ function fo(e) {
|
|
|
3143
3153
|
}
|
|
3144
3154
|
return globalThis.Buffer.from(t).toString("base64");
|
|
3145
3155
|
}
|
|
3146
|
-
const
|
|
3147
|
-
function
|
|
3148
|
-
const n =
|
|
3156
|
+
const go = (e) => bo(e).replace(/\+/g, "-").replace(/\//g, "_").replace(/=+$/, "");
|
|
3157
|
+
function Hn(e, t) {
|
|
3158
|
+
const n = go(JSON.stringify({ id: e, values: t }));
|
|
3149
3159
|
return `#fincalc=${encodeURIComponent(e)}&s=${n}`;
|
|
3150
3160
|
}
|
|
3151
|
-
const
|
|
3161
|
+
const Ke = (e) => String(e ?? "").replace(/\|/g, "\\|").replace(/\n/g, " ");
|
|
3152
3162
|
function Jt(e) {
|
|
3153
3163
|
const t = [`# ${e.title}`, ""];
|
|
3154
3164
|
t.push("| Metric | Value |", "| --- | --- |");
|
|
3155
|
-
for (const [n, a] of Re(e)) t.push(`| ${
|
|
3165
|
+
for (const [n, a] of Re(e)) t.push(`| ${Ke(n)} | ${Ke(a)} |`);
|
|
3156
3166
|
if (e.result.schedule) {
|
|
3157
3167
|
const n = _e(e.result.schedule);
|
|
3158
|
-
t.push("", `## ${e.result.schedule.title ?? "Schedule"}`, ""), t.push(`| ${n.header.map(
|
|
3159
|
-
for (const a of n.rows) t.push(`| ${a.map(
|
|
3168
|
+
t.push("", `## ${e.result.schedule.title ?? "Schedule"}`, ""), t.push(`| ${n.header.map(Ke).join(" | ")} |`), t.push(`| ${n.header.map(() => "---").join(" | ")} |`);
|
|
3169
|
+
for (const a of n.rows) t.push(`| ${a.map(Ke).join(" | ")} |`);
|
|
3160
3170
|
}
|
|
3161
3171
|
return t.push("", `_Generated by ArthaGanaka · ${e.meta.computedAt}_`), t.join(`
|
|
3162
3172
|
`);
|
|
3163
3173
|
}
|
|
3164
3174
|
const Pe = (e) => String(e ?? "").replace(/[&<>"]/g, (t) => ({ "&": "&", "<": "<", ">": ">", '"': """ })[t]);
|
|
3165
|
-
function
|
|
3175
|
+
function vo(e) {
|
|
3166
3176
|
return `<table><tbody>${Re(e).map(([n, a]) => `<tr><th>${Pe(n)}</th><td>${Pe(a)}</td></tr>`).join("")}</tbody></table>`;
|
|
3167
3177
|
}
|
|
3168
|
-
function
|
|
3178
|
+
function ko(e) {
|
|
3169
3179
|
const t = _e(e), n = `<tr>${t.header.map((r) => `<th>${Pe(r)}</th>`).join("")}</tr>`, a = t.rows.map((r) => `<tr>${r.map((s) => `<td>${Pe(s)}</td>`).join("")}</tr>`).join("");
|
|
3170
3180
|
return `<table><thead>${n}</thead><tbody>${a}</tbody></table>`;
|
|
3171
3181
|
}
|
|
3172
|
-
function
|
|
3173
|
-
const t = e.result.schedule ? `<h2>${Pe(e.result.schedule.title ?? "Schedule")}</h2>${
|
|
3174
|
-
return `<h1>${Pe(e.title)}</h1>${
|
|
3182
|
+
function qn(e) {
|
|
3183
|
+
const t = e.result.schedule ? `<h2>${Pe(e.result.schedule.title ?? "Schedule")}</h2>${ko(e.result.schedule)}` : "";
|
|
3184
|
+
return `<h1>${Pe(e.title)}</h1>${vo(e)}${t}<p class="fc-print-foot">Generated by ArthaGanaka · ${Pe(e.meta.computedAt)}</p>`;
|
|
3175
3185
|
}
|
|
3176
|
-
const Zt = (e) => String(e ?? "").replace(/\\/g, "\\\\").replace(/[;,]/g, (t) => `\\${t}`).replace(/\n/g, "\\n"), Xt = (e) => `${e.getFullYear()}${String(e.getMonth() + 1).padStart(2, "0")}${String(e.getDate()).padStart(2, "0")}`,
|
|
3186
|
+
const Zt = (e) => String(e ?? "").replace(/\\/g, "\\\\").replace(/[;,]/g, (t) => `\\${t}`).replace(/\n/g, "\\n"), Xt = (e) => `${e.getFullYear()}${String(e.getMonth() + 1).padStart(2, "0")}${String(e.getDate()).padStart(2, "0")}`, wo = (e) => new Date(e || Date.now()).toISOString().replace(/[-:]/g, "").replace(/\.\d{3}Z$/, "Z"), No = (e, t) => {
|
|
3177
3187
|
const n = new Date(e);
|
|
3178
3188
|
return n.setMonth(n.getMonth() + t), n;
|
|
3179
3189
|
};
|
|
3180
|
-
function
|
|
3190
|
+
function xo(e) {
|
|
3181
3191
|
for (const t of Object.values(e))
|
|
3182
3192
|
if (typeof t == "string" && /^\d{4}-\d{2}-\d{2}/.test(t)) {
|
|
3183
3193
|
const n = new Date(t);
|
|
@@ -3185,12 +3195,12 @@ function wo(e) {
|
|
|
3185
3195
|
}
|
|
3186
3196
|
return /* @__PURE__ */ new Date();
|
|
3187
3197
|
}
|
|
3188
|
-
function
|
|
3189
|
-
const t =
|
|
3198
|
+
function So(e) {
|
|
3199
|
+
const t = uo(e.result.schedule);
|
|
3190
3200
|
if (!t) throw new Error("This calculator has no instalment schedule to put on a calendar.");
|
|
3191
|
-
const n =
|
|
3201
|
+
const n = xo(e.values), a = t <= 60, r = a ? t : Math.ceil(t / 12), s = wo(e.meta.computedAt), u = ["BEGIN:VCALENDAR", "VERSION:2.0", "PRODID:-//ArthaGanaka//Export//EN", "CALSCALE:GREGORIAN"];
|
|
3192
3202
|
for (let m = 0; m < r; m++) {
|
|
3193
|
-
const d =
|
|
3203
|
+
const d = No(n, a ? m + 1 : (m + 1) * 12), i = a ? `instalment ${m + 1}` : `year ${m + 1}`;
|
|
3194
3204
|
u.push(
|
|
3195
3205
|
"BEGIN:VEVENT",
|
|
3196
3206
|
`UID:${Zt(e.calculatorId)}-${m + 1}-${Xt(d)}@arthaganaka`,
|
|
@@ -3203,13 +3213,13 @@ function No(e) {
|
|
|
3203
3213
|
return u.push("END:VCALENDAR"), u.join(`\r
|
|
3204
3214
|
`);
|
|
3205
3215
|
}
|
|
3206
|
-
async function
|
|
3216
|
+
async function Gn(e) {
|
|
3207
3217
|
var n;
|
|
3208
3218
|
const t = typeof navigator < "u" ? navigator : void 0;
|
|
3209
3219
|
if ((n = t == null ? void 0 : t.clipboard) != null && n.writeText) return t.clipboard.writeText(e);
|
|
3210
3220
|
throw new Error("Clipboard is not available in this browser.");
|
|
3211
3221
|
}
|
|
3212
|
-
async function
|
|
3222
|
+
async function Co(e, t) {
|
|
3213
3223
|
var a;
|
|
3214
3224
|
const n = typeof navigator < "u" ? navigator : void 0;
|
|
3215
3225
|
if ((a = n == null ? void 0 : n.clipboard) != null && a.write && typeof ClipboardItem < "u" && typeof Blob < "u")
|
|
@@ -3223,18 +3233,18 @@ async function xo(e, t) {
|
|
|
3223
3233
|
return;
|
|
3224
3234
|
} catch {
|
|
3225
3235
|
}
|
|
3226
|
-
await
|
|
3236
|
+
await Gn(t);
|
|
3227
3237
|
}
|
|
3228
|
-
function
|
|
3238
|
+
function Po(e) {
|
|
3229
3239
|
if (!Ot() || typeof window > "u") throw new Error("Print is only available in the browser.");
|
|
3230
3240
|
const t = document.createElement("div");
|
|
3231
|
-
t.className = "fc-print-root", t.innerHTML =
|
|
3241
|
+
t.className = "fc-print-root", t.innerHTML = qn(e), document.body.appendChild(t), document.body.classList.add("fc-printing");
|
|
3232
3242
|
const n = () => {
|
|
3233
3243
|
document.body.classList.remove("fc-printing"), t.remove(), window.removeEventListener("afterprint", n);
|
|
3234
3244
|
};
|
|
3235
3245
|
window.addEventListener("afterprint", n), window.print(), setTimeout(n, 1500);
|
|
3236
3246
|
}
|
|
3237
|
-
function
|
|
3247
|
+
function To(e, t = 2) {
|
|
3238
3248
|
if (!Ot()) return Promise.reject(new Error("PNG export is only available in the browser."));
|
|
3239
3249
|
const n = Re(e), a = 620, r = 120 + n.length * 30 + 30, s = document.createElement("canvas");
|
|
3240
3250
|
s.width = a * t, s.height = r * t;
|
|
@@ -3251,7 +3261,7 @@ function Co(e, t = 2) {
|
|
|
3251
3261
|
(i, c) => s.toBlob((l) => l ? i(l) : c(new Error("Could not render PNG.")), "image/png")
|
|
3252
3262
|
);
|
|
3253
3263
|
}
|
|
3254
|
-
async function
|
|
3264
|
+
async function Fo(e) {
|
|
3255
3265
|
let t;
|
|
3256
3266
|
try {
|
|
3257
3267
|
t = await import(
|
|
@@ -3277,7 +3287,7 @@ async function Po(e) {
|
|
|
3277
3287
|
const s = ve(e, "pdf");
|
|
3278
3288
|
return a.save(s), { ok: !0, filename: s };
|
|
3279
3289
|
}
|
|
3280
|
-
async function
|
|
3290
|
+
async function Io(e) {
|
|
3281
3291
|
var i, c;
|
|
3282
3292
|
let t;
|
|
3283
3293
|
try {
|
|
@@ -3300,12 +3310,12 @@ async function To(e) {
|
|
|
3300
3310
|
const m = a(u, { type: "array", bookType: "xlsx" }), d = ve(e, "xlsx");
|
|
3301
3311
|
return Se(d, new Blob([m], { type: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet" })), { ok: !0, filename: d };
|
|
3302
3312
|
}
|
|
3303
|
-
function
|
|
3304
|
-
const t =
|
|
3313
|
+
function jn(e) {
|
|
3314
|
+
const t = Hn(e.calculatorId, e.values);
|
|
3305
3315
|
return (typeof location < "u" ? location.origin + location.pathname : "") + t;
|
|
3306
3316
|
}
|
|
3307
|
-
async function
|
|
3308
|
-
const t =
|
|
3317
|
+
async function Ro(e) {
|
|
3318
|
+
const t = Hn(e.calculatorId, e.values), n = jn(e);
|
|
3309
3319
|
if (typeof location < "u")
|
|
3310
3320
|
try {
|
|
3311
3321
|
location.hash = t;
|
|
@@ -3313,31 +3323,31 @@ async function Fo(e) {
|
|
|
3313
3323
|
}
|
|
3314
3324
|
const a = n.length > 2e3 ? `Link is long (${n.length} chars) — some apps may trim it. ` : "";
|
|
3315
3325
|
try {
|
|
3316
|
-
return await
|
|
3326
|
+
return await Gn(n), { ok: !0, data: n, note: `${a}Link copied to clipboard.` };
|
|
3317
3327
|
} catch {
|
|
3318
3328
|
return { ok: !0, data: n, note: `${a}Link is in the address bar — copy it from there.` };
|
|
3319
3329
|
}
|
|
3320
3330
|
}
|
|
3321
|
-
function
|
|
3331
|
+
function Eo(e) {
|
|
3322
3332
|
return {
|
|
3323
3333
|
ok: !0,
|
|
3324
|
-
data:
|
|
3334
|
+
data: jn(e),
|
|
3325
3335
|
note: "A QR image needs an optional QR library — share this link instead."
|
|
3326
3336
|
};
|
|
3327
3337
|
}
|
|
3328
|
-
function
|
|
3329
|
-
const t = e.schemaVersion ??
|
|
3338
|
+
function Mo(e = {}) {
|
|
3339
|
+
const t = e.schemaVersion ?? Bn, n = {
|
|
3330
3340
|
csv: (a) => {
|
|
3331
3341
|
const r = ve(a, "csv");
|
|
3332
|
-
return Se(r,
|
|
3342
|
+
return Se(r, ho(a), "text/csv;charset=utf-8"), { ok: !0, filename: r };
|
|
3333
3343
|
},
|
|
3334
3344
|
tsv: (a) => {
|
|
3335
3345
|
const r = ve(a, "tsv");
|
|
3336
|
-
return Se(r,
|
|
3346
|
+
return Se(r, fo(a), "text/tab-separated-values;charset=utf-8"), { ok: !0, filename: r };
|
|
3337
3347
|
},
|
|
3338
3348
|
json: (a) => {
|
|
3339
3349
|
const r = ve(a, "json");
|
|
3340
|
-
return Se(r,
|
|
3350
|
+
return Se(r, yo(a, t), "application/json"), { ok: !0, filename: r };
|
|
3341
3351
|
},
|
|
3342
3352
|
markdown: (a) => {
|
|
3343
3353
|
const r = ve(a, "md");
|
|
@@ -3345,18 +3355,18 @@ function Ro(e = {}) {
|
|
|
3345
3355
|
},
|
|
3346
3356
|
ics: (a) => {
|
|
3347
3357
|
const r = ve(a, "ics");
|
|
3348
|
-
return Se(r,
|
|
3358
|
+
return Se(r, So(a), "text/calendar;charset=utf-8"), { ok: !0, filename: r };
|
|
3349
3359
|
},
|
|
3350
|
-
clipboard: async (a) => (await
|
|
3351
|
-
print: (a) => (
|
|
3352
|
-
url: (a) =>
|
|
3353
|
-
qr: (a) =>
|
|
3360
|
+
clipboard: async (a) => (await Co(qn(a), Jt(a)), { ok: !0, note: "Copied table to clipboard." }),
|
|
3361
|
+
print: (a) => (Po(a), { ok: !0 }),
|
|
3362
|
+
url: (a) => Ro(a),
|
|
3363
|
+
qr: (a) => Eo(a),
|
|
3354
3364
|
png: async (a, r) => {
|
|
3355
3365
|
const s = ve(a, "png");
|
|
3356
|
-
return Se(s, await
|
|
3366
|
+
return Se(s, await To(a, r.scale ?? 2)), { ok: !0, filename: s };
|
|
3357
3367
|
},
|
|
3358
|
-
pdf: (a) =>
|
|
3359
|
-
xlsx: (a) =>
|
|
3368
|
+
pdf: (a) => Fo(a),
|
|
3369
|
+
xlsx: (a) => Io(a)
|
|
3360
3370
|
};
|
|
3361
3371
|
return {
|
|
3362
3372
|
formats: Object.keys(n),
|
|
@@ -3366,8 +3376,8 @@ function Ro(e = {}) {
|
|
|
3366
3376
|
}
|
|
3367
3377
|
};
|
|
3368
3378
|
}
|
|
3369
|
-
function
|
|
3370
|
-
const t = X(() =>
|
|
3379
|
+
function Vn({ payload: e }) {
|
|
3380
|
+
const t = X(() => Mo(), []), [n, a] = M(!1), [r, s] = M(null), u = de(null), m = de(null), d = de([]);
|
|
3371
3381
|
Q(() => {
|
|
3372
3382
|
if (!r) return;
|
|
3373
3383
|
const p = setTimeout(() => s(null), 4500);
|
|
@@ -3435,7 +3445,7 @@ function jn({ payload: e }) {
|
|
|
3435
3445
|
}
|
|
3436
3446
|
)
|
|
3437
3447
|
] }),
|
|
3438
|
-
n && /* @__PURE__ */ o("div", { ref: m, className: "menu-list", role: "menu", "aria-label": "Export as", children:
|
|
3448
|
+
n && /* @__PURE__ */ o("div", { ref: m, className: "menu-list", role: "menu", "aria-label": "Export as", children: co.map((p, h) => /* @__PURE__ */ o(
|
|
3439
3449
|
"button",
|
|
3440
3450
|
{
|
|
3441
3451
|
type: "button",
|
|
@@ -3452,10 +3462,10 @@ function jn({ payload: e }) {
|
|
|
3452
3462
|
r && /* @__PURE__ */ o("div", { className: `export-toast ${r.kind}`, role: "status", "aria-live": "polite", children: r.msg })
|
|
3453
3463
|
] });
|
|
3454
3464
|
}
|
|
3455
|
-
const Bt = "calcsuite:history",
|
|
3465
|
+
const Bt = "calcsuite:history", $o = 100, Ao = [];
|
|
3456
3466
|
let Ce = null;
|
|
3457
|
-
const
|
|
3458
|
-
function
|
|
3467
|
+
const Ze = /* @__PURE__ */ new Set();
|
|
3468
|
+
function Yn() {
|
|
3459
3469
|
if (Ce) return Ce;
|
|
3460
3470
|
try {
|
|
3461
3471
|
Ce = JSON.parse(localStorage.getItem(Bt) || "[]");
|
|
@@ -3464,38 +3474,38 @@ function Vn() {
|
|
|
3464
3474
|
}
|
|
3465
3475
|
return Ce;
|
|
3466
3476
|
}
|
|
3467
|
-
function
|
|
3477
|
+
function Kn(e) {
|
|
3468
3478
|
Ce = e;
|
|
3469
3479
|
try {
|
|
3470
3480
|
localStorage.setItem(Bt, JSON.stringify(e));
|
|
3471
3481
|
} catch {
|
|
3472
3482
|
}
|
|
3473
|
-
|
|
3483
|
+
Ze.forEach((t) => t());
|
|
3474
3484
|
}
|
|
3475
3485
|
let Qt = !1;
|
|
3476
|
-
function
|
|
3477
|
-
return
|
|
3478
|
-
t.key === Bt && (Ce = null,
|
|
3479
|
-
})), () =>
|
|
3486
|
+
function Do(e) {
|
|
3487
|
+
return Ze.add(e), !Qt && typeof window < "u" && (Qt = !0, window.addEventListener("storage", (t) => {
|
|
3488
|
+
t.key === Bt && (Ce = null, Ze.forEach((n) => n()));
|
|
3489
|
+
})), () => Ze.delete(e);
|
|
3480
3490
|
}
|
|
3481
|
-
function
|
|
3482
|
-
|
|
3491
|
+
function Wn(e) {
|
|
3492
|
+
Kn([{ ...e, at: Date.now() }, ...Yn()].slice(0, $o));
|
|
3483
3493
|
}
|
|
3484
|
-
function
|
|
3485
|
-
|
|
3494
|
+
function Lo() {
|
|
3495
|
+
Kn([]);
|
|
3486
3496
|
}
|
|
3487
|
-
function
|
|
3488
|
-
const e =
|
|
3497
|
+
function Uo() {
|
|
3498
|
+
const e = va(Do, Yn, () => Ao), t = ke((a) => Wn(a), []), n = ke(() => Lo(), []);
|
|
3489
3499
|
return { items: e, save: t, clear: n };
|
|
3490
3500
|
}
|
|
3491
|
-
function
|
|
3501
|
+
function zn({ item: e }) {
|
|
3492
3502
|
const [t, n] = M(!1), a = de();
|
|
3493
3503
|
return Q(() => () => clearTimeout(a.current), []), /* @__PURE__ */ o("button", { className: `icon-btn ${t ? "saved" : ""}`, onClick: () => {
|
|
3494
|
-
|
|
3504
|
+
Wn(e), n(!0), clearTimeout(a.current), a.current = setTimeout(() => n(!1), 1500);
|
|
3495
3505
|
}, "aria-live": "polite", children: t ? "Saved ✓" : "Save" });
|
|
3496
3506
|
}
|
|
3497
|
-
const
|
|
3498
|
-
function
|
|
3507
|
+
const Oo = { payment: "Payment", principal: "Amount", rate: "Rate", tenure: "Term" };
|
|
3508
|
+
function Jn() {
|
|
3499
3509
|
const { settings: e, fmt: t } = ue(), n = e.region, a = me[n], [r, s] = M("payment"), [u, m] = M(a.defaultBasis), [d, i] = M(n === "IN" ? "2500000" : "300000"), [c, l] = M(a.defaultRatePct), [p, h] = M(String(Math.floor(a.defaultTermMonths / 12))), [f, y] = M(String(a.defaultTermMonths % 12)), [w, k] = M(n === "IN" ? "21934" : "1896"), [S, F] = M("schedule"), N = u === "flat" ? ["payment", "principal"] : ["payment", "principal", "rate", "tenure"], P = (parseInt(p || "0", 10) || 0) * 12 + (parseInt(f || "0", 10) || 0), x = (R) => R.replace(/[, ]/g, "").trim(), { result: T, error: $ } = X(() => {
|
|
3500
3510
|
try {
|
|
3501
3511
|
return { result: Ie({
|
|
@@ -3571,7 +3581,7 @@ function zn() {
|
|
|
3571
3581
|
/* @__PURE__ */ b("section", { className: "card", children: [
|
|
3572
3582
|
/* @__PURE__ */ b("div", { className: "solve-row", children: [
|
|
3573
3583
|
/* @__PURE__ */ o("span", { className: "lbl", children: "Solve for" }),
|
|
3574
|
-
/* @__PURE__ */ o("div", { className: "seg", role: "group", "aria-label": "Solve for", children: N.map((R) => /* @__PURE__ */ o("button", { "aria-pressed": r === R, onClick: () => s(R), children:
|
|
3584
|
+
/* @__PURE__ */ o("div", { className: "seg", role: "group", "aria-label": "Solve for", children: N.map((R) => /* @__PURE__ */ o("button", { "aria-pressed": r === R, onClick: () => s(R), children: Oo[R] }, R)) })
|
|
3575
3585
|
] }),
|
|
3576
3586
|
/* @__PURE__ */ b("div", { className: "field", style: { marginBottom: "calc(var(--fc-space) * 2)" }, children: [
|
|
3577
3587
|
/* @__PURE__ */ o("span", { className: "lbl", children: "Interest basis" }),
|
|
@@ -3625,7 +3635,7 @@ function zn() {
|
|
|
3625
3635
|
/* @__PURE__ */ o("span", { className: "per", children: " /month" })
|
|
3626
3636
|
] })
|
|
3627
3637
|
] }),
|
|
3628
|
-
/* @__PURE__ */ o(
|
|
3638
|
+
/* @__PURE__ */ o(Bo, { result: T }),
|
|
3629
3639
|
/* @__PURE__ */ b("div", { className: "secondary", children: [
|
|
3630
3640
|
/* @__PURE__ */ b("div", { className: "kv", children: [
|
|
3631
3641
|
/* @__PURE__ */ o("div", { className: "k", children: "Principal" }),
|
|
@@ -3646,13 +3656,13 @@ function zn() {
|
|
|
3646
3656
|
] }),
|
|
3647
3657
|
/* @__PURE__ */ b("div", { className: "actions-row", children: [
|
|
3648
3658
|
/* @__PURE__ */ o(
|
|
3649
|
-
|
|
3659
|
+
zn,
|
|
3650
3660
|
{
|
|
3651
3661
|
item: { id: "loan.emi", title: `Loan — ${t.money(T.payment)}/mo`, primary: t.money(T.payment), values: A }
|
|
3652
3662
|
}
|
|
3653
3663
|
),
|
|
3654
3664
|
/* @__PURE__ */ o(
|
|
3655
|
-
|
|
3665
|
+
Vn,
|
|
3656
3666
|
{
|
|
3657
3667
|
payload: {
|
|
3658
3668
|
calculatorId: "loan.emi",
|
|
@@ -3684,8 +3694,8 @@ function zn() {
|
|
|
3684
3694
|
e.ui.showFormulas && /* @__PURE__ */ o("button", { role: "tab", "aria-selected": S === "formula", onClick: () => F("formula"), children: "Formula" })
|
|
3685
3695
|
] }),
|
|
3686
3696
|
/* @__PURE__ */ b("div", { className: "tab-anim", children: [
|
|
3687
|
-
S === "schedule" && /* @__PURE__ */ o(
|
|
3688
|
-
S === "chart" && /* @__PURE__ */ o(
|
|
3697
|
+
S === "schedule" && /* @__PURE__ */ o(_o, { result: T }),
|
|
3698
|
+
S === "chart" && /* @__PURE__ */ o(Ho, { result: T }),
|
|
3689
3699
|
S === "formula" && e.ui.showFormulas && /* @__PURE__ */ b("div", { className: "formula", children: [
|
|
3690
3700
|
/* @__PURE__ */ o("code", { children: T.formula }),
|
|
3691
3701
|
/* @__PURE__ */ b("div", { className: "assumptions", children: [
|
|
@@ -3730,7 +3740,7 @@ function bt({
|
|
|
3730
3740
|
] })
|
|
3731
3741
|
] });
|
|
3732
3742
|
}
|
|
3733
|
-
function
|
|
3743
|
+
function Bo({ result: e }) {
|
|
3734
3744
|
const { fmt: t } = ue(), n = Number(e.principal.toFixed(2)), a = Number(e.totalInterest.toFixed(2)), r = n + a || 1, s = Math.round(n / r * 100);
|
|
3735
3745
|
return /* @__PURE__ */ b(re, { children: [
|
|
3736
3746
|
/* @__PURE__ */ b("div", { className: "splitbar", role: "img", "aria-label": `Principal ${s}%, interest ${100 - s}%`, children: [
|
|
@@ -3755,7 +3765,7 @@ function Uo({ result: e }) {
|
|
|
3755
3765
|
] })
|
|
3756
3766
|
] });
|
|
3757
3767
|
}
|
|
3758
|
-
function
|
|
3768
|
+
function _o({ result: e }) {
|
|
3759
3769
|
const { fmt: t } = ue(), [n, a] = M("yearly"), [r, s] = M(/* @__PURE__ */ new Set([1])), u = (d) => s((i) => {
|
|
3760
3770
|
const c = new Set(i);
|
|
3761
3771
|
return c.has(d) ? c.delete(d) : c.add(d), c;
|
|
@@ -3817,7 +3827,7 @@ function Oo({ result: e }) {
|
|
|
3817
3827
|
] }) })
|
|
3818
3828
|
] });
|
|
3819
3829
|
}
|
|
3820
|
-
function
|
|
3830
|
+
function Ho({ result: e }) {
|
|
3821
3831
|
const { fmt: t } = ue(), n = e.chart.balance.map((k) => k.toNumber()), a = e.chart.cumulativeInterest.map((k) => k.toNumber()), r = n.length, s = 720, u = 260, m = 8, d = 8, i = 12, c = 22, l = e.principal.toNumber(), p = Math.max(l, a[a.length - 1] ?? 0) || 1, h = (k) => m + k / Math.max(r - 1, 1) * (s - m - d), f = (k) => i + (1 - k / p) * (u - i - c), y = (k) => k.map((S, F) => `${F === 0 ? "M" : "L"}${h(F).toFixed(1)},${f(S).toFixed(1)}`).join(" "), w = `M${h(0)},${f(l)} ${n.map((k, S) => `L${h(S).toFixed(1)},${f(k).toFixed(1)}`).join(" ")} L${h(r - 1)},${f(0)} L${h(0)},${f(0)} Z`;
|
|
3822
3832
|
return /* @__PURE__ */ b("div", { className: "chart", children: [
|
|
3823
3833
|
/* @__PURE__ */ b("svg", { viewBox: `0 0 ${s} ${u}`, role: "img", "aria-label": "Balance and cumulative interest over the term", children: [
|
|
@@ -3840,7 +3850,7 @@ function Bo({ result: e }) {
|
|
|
3840
3850
|
] })
|
|
3841
3851
|
] });
|
|
3842
3852
|
}
|
|
3843
|
-
const
|
|
3853
|
+
const qo = /* @__PURE__ */ new Set([
|
|
3844
3854
|
"sin",
|
|
3845
3855
|
"cos",
|
|
3846
3856
|
"tan",
|
|
@@ -3877,7 +3887,7 @@ const _o = /* @__PURE__ */ new Set([
|
|
|
3877
3887
|
"sq",
|
|
3878
3888
|
"cube",
|
|
3879
3889
|
"recip"
|
|
3880
|
-
]),
|
|
3890
|
+
]), Go = {
|
|
3881
3891
|
arcsin: "asin",
|
|
3882
3892
|
arccos: "acos",
|
|
3883
3893
|
arctan: "atan",
|
|
@@ -3885,14 +3895,14 @@ const _o = /* @__PURE__ */ new Set([
|
|
|
3885
3895
|
log10: "log",
|
|
3886
3896
|
ncr: "ncr",
|
|
3887
3897
|
npr: "npr"
|
|
3888
|
-
},
|
|
3889
|
-
` || e === "\r", fe = (e) => e >= "0" && e <= "9", en = (e) => e >= "a" && e <= "z" || e >= "A" && e <= "Z",
|
|
3890
|
-
function
|
|
3891
|
-
return e === "HEX" ?
|
|
3892
|
-
}
|
|
3893
|
-
function
|
|
3894
|
-
const t = e.toLowerCase(), n =
|
|
3895
|
-
if (
|
|
3898
|
+
}, jo = (e) => e === " " || e === " " || e === `
|
|
3899
|
+
` || e === "\r", fe = (e) => e >= "0" && e <= "9", en = (e) => e >= "a" && e <= "z" || e >= "A" && e <= "Z", Zn = (e) => fe(e) || e >= "a" && e <= "f" || e >= "A" && e <= "F", tn = /* @__PURE__ */ new Set(["num", "const", "var", "func", "lparen", "uop"]), Vo = /* @__PURE__ */ new Set(["num", "const", "var", "rparen", "postfix"]);
|
|
3900
|
+
function Yo(e) {
|
|
3901
|
+
return e === "HEX" ? Zn : e === "OCT" ? (t) => t >= "0" && t <= "7" : e === "BIN" ? (t) => t === "0" || t === "1" : fe;
|
|
3902
|
+
}
|
|
3903
|
+
function Ko(e) {
|
|
3904
|
+
const t = e.toLowerCase(), n = Go[t] ?? t;
|
|
3905
|
+
if (qo.has(n)) return { type: "func", value: n };
|
|
3896
3906
|
if (t === "mod") return { type: "op", value: "mod" };
|
|
3897
3907
|
if (t === "and") return { type: "op", value: "and" };
|
|
3898
3908
|
if (t === "or") return { type: "op", value: "or" };
|
|
@@ -3909,12 +3919,12 @@ function Vo(e) {
|
|
|
3909
3919
|
}
|
|
3910
3920
|
throw new Error(`Unknown name: ${e}`);
|
|
3911
3921
|
}
|
|
3912
|
-
function
|
|
3922
|
+
function Wo(e, t = {}) {
|
|
3913
3923
|
const n = t.base ?? "DEC", a = e, r = [];
|
|
3914
3924
|
let s = 0;
|
|
3915
3925
|
for (; s < a.length; ) {
|
|
3916
3926
|
const d = a[s];
|
|
3917
|
-
if (
|
|
3927
|
+
if (jo(d)) {
|
|
3918
3928
|
s++;
|
|
3919
3929
|
continue;
|
|
3920
3930
|
}
|
|
@@ -3922,14 +3932,14 @@ function Yo(e, t = {}) {
|
|
|
3922
3932
|
if (d === "0" && (a[s + 1] === "x" || a[s + 1] === "X" || a[s + 1] === "o" || a[s + 1] === "O" || a[s + 1] === "b" || a[s + 1] === "B")) {
|
|
3923
3933
|
const l = a[s + 1].toLowerCase();
|
|
3924
3934
|
let p = s + 2;
|
|
3925
|
-
const h = l === "x" ?
|
|
3935
|
+
const h = l === "x" ? Zn : l === "o" ? (y) => y >= "0" && y <= "7" : (y) => y === "0" || y === "1", f = p;
|
|
3926
3936
|
for (; p < a.length && h(a[p]); ) p++;
|
|
3927
3937
|
if (p === f) throw new Error(`Malformed 0${l} literal`);
|
|
3928
3938
|
r.push({ type: "num", value: BigInt(`0${l}${a.slice(f, p)}`).toString() }), s = p;
|
|
3929
3939
|
continue;
|
|
3930
3940
|
}
|
|
3931
3941
|
if (n !== "DEC") {
|
|
3932
|
-
const l =
|
|
3942
|
+
const l = Yo(n);
|
|
3933
3943
|
let p = s;
|
|
3934
3944
|
for (; p < a.length && l(a[p]); ) p++;
|
|
3935
3945
|
const h = a.slice(s, p), f = n === "HEX" ? "0x" : n === "OCT" ? "0o" : "0b";
|
|
@@ -3953,7 +3963,7 @@ function Yo(e, t = {}) {
|
|
|
3953
3963
|
if (en(d) || d === "_") {
|
|
3954
3964
|
let c = s;
|
|
3955
3965
|
for (; c < a.length && (en(a[c]) || fe(a[c]) || a[c] === "_"); ) c++;
|
|
3956
|
-
r.push(
|
|
3966
|
+
r.push(Ko(a.slice(s, c))), s = c;
|
|
3957
3967
|
continue;
|
|
3958
3968
|
}
|
|
3959
3969
|
const i = a.slice(s, s + 2);
|
|
@@ -4033,11 +4043,11 @@ function Yo(e, t = {}) {
|
|
|
4033
4043
|
}), m = [];
|
|
4034
4044
|
for (let d = 0; d < u.length; d++) {
|
|
4035
4045
|
const i = u[d], c = m[m.length - 1];
|
|
4036
|
-
c &&
|
|
4046
|
+
c && Vo.has(c.type) && tn.has(i.type) && m.push({ type: "op", value: "*", implicit: !0 }), m.push(i);
|
|
4037
4047
|
}
|
|
4038
4048
|
return m;
|
|
4039
4049
|
}
|
|
4040
|
-
const
|
|
4050
|
+
const zo = {
|
|
4041
4051
|
or: { prec: 1 },
|
|
4042
4052
|
xor: { prec: 2 },
|
|
4043
4053
|
and: { prec: 3 },
|
|
@@ -4051,7 +4061,7 @@ const Ko = {
|
|
|
4051
4061
|
"%": { prec: 6 },
|
|
4052
4062
|
"^": { prec: 8, right: !0 }
|
|
4053
4063
|
}, nn = { neg: 7, bnot: 7, sqrt: 10, cbrt: 10, qdrt: 10 }, De = Symbol("arg");
|
|
4054
|
-
function
|
|
4064
|
+
function Jo(e) {
|
|
4055
4065
|
const t = [], n = [];
|
|
4056
4066
|
let a = !0;
|
|
4057
4067
|
const r = () => {
|
|
@@ -4102,7 +4112,7 @@ function Wo(e) {
|
|
|
4102
4112
|
else if (d.value !== "+") throw new Error(`Unexpected operator: ${d.value}`);
|
|
4103
4113
|
a = !0;
|
|
4104
4114
|
} else {
|
|
4105
|
-
const i =
|
|
4115
|
+
const i = zo[d.value];
|
|
4106
4116
|
if (!i) throw new Error(`Unknown operator: ${d.value}`);
|
|
4107
4117
|
for (; n.length; ) {
|
|
4108
4118
|
const c = n[n.length - 1];
|
|
@@ -4143,7 +4153,7 @@ function Wo(e) {
|
|
|
4143
4153
|
if (m === De) throw new Error("Malformed expression");
|
|
4144
4154
|
return m;
|
|
4145
4155
|
}
|
|
4146
|
-
const
|
|
4156
|
+
const Zo = new H("3.141592653589793238462643383279502884197"), Xo = new H("2.718281828459045235360287471352662497757"), Qo = new H("1.618033988749894848204586834365638117720");
|
|
4147
4157
|
function gt(e, t) {
|
|
4148
4158
|
return t === "deg" ? e * Math.PI / 180 : t === "grad" ? e * Math.PI / 200 : e;
|
|
4149
4159
|
}
|
|
@@ -4157,13 +4167,13 @@ function an(e) {
|
|
|
4157
4167
|
for (let n = 2; n <= e.toNumber(); n++) t = t.times(n);
|
|
4158
4168
|
return t;
|
|
4159
4169
|
}
|
|
4160
|
-
function
|
|
4170
|
+
function ei(e, t) {
|
|
4161
4171
|
if (!e.isInteger() || !t.isInteger() || t.isNegative() || t.gt(e)) throw new Error("nPr domain");
|
|
4162
4172
|
let n = g(1);
|
|
4163
4173
|
for (let a = 0; a < t.toNumber(); a++) n = n.times(e.minus(a));
|
|
4164
4174
|
return n;
|
|
4165
4175
|
}
|
|
4166
|
-
function
|
|
4176
|
+
function ti(e, t) {
|
|
4167
4177
|
if (!e.isInteger() || !t.isInteger() || t.isNegative() || t.gt(e)) throw new Error("nCr domain");
|
|
4168
4178
|
const n = H.min(t, e.minus(t));
|
|
4169
4179
|
let a = g(1);
|
|
@@ -4186,7 +4196,7 @@ function kt(e, t) {
|
|
|
4186
4196
|
return e.pow(g(1).div(t));
|
|
4187
4197
|
}
|
|
4188
4198
|
const ie = (e) => BigInt(e.trunc().toFixed(0));
|
|
4189
|
-
function
|
|
4199
|
+
function ni(e, t = {}) {
|
|
4190
4200
|
const n = t.angleMode ?? "deg", a = t.percentMode ?? "of", r = (i) => {
|
|
4191
4201
|
var l;
|
|
4192
4202
|
if (i === "ans") return g(t.ans ?? 0);
|
|
@@ -4268,9 +4278,9 @@ function ei(e, t = {}) {
|
|
|
4268
4278
|
case "tenpow":
|
|
4269
4279
|
return p(1), g(10).pow(l);
|
|
4270
4280
|
case "ncr":
|
|
4271
|
-
return p(2),
|
|
4281
|
+
return p(2), ti(l, c[1]);
|
|
4272
4282
|
case "npr":
|
|
4273
|
-
return p(2),
|
|
4283
|
+
return p(2), ei(l, c[1]);
|
|
4274
4284
|
case "gcd":
|
|
4275
4285
|
return p(2), rn(l, c[1]);
|
|
4276
4286
|
case "lcm":
|
|
@@ -4336,7 +4346,7 @@ function ei(e, t = {}) {
|
|
|
4336
4346
|
case "num":
|
|
4337
4347
|
return g(i.value);
|
|
4338
4348
|
case "const":
|
|
4339
|
-
return i.name === "PI" ?
|
|
4349
|
+
return i.name === "PI" ? Zo : i.name === "E" ? Xo : Qo;
|
|
4340
4350
|
case "var":
|
|
4341
4351
|
return r(i.name);
|
|
4342
4352
|
case "percent":
|
|
@@ -4363,7 +4373,7 @@ function ei(e, t = {}) {
|
|
|
4363
4373
|
function on(e, t = {}) {
|
|
4364
4374
|
if (e == null || e.trim() === "") return { value: new H(0) };
|
|
4365
4375
|
try {
|
|
4366
|
-
const n =
|
|
4376
|
+
const n = Wo(e, { base: t.base }), a = Jo(n), r = ni(a, t);
|
|
4367
4377
|
return r.isNaN() ? { value: r, error: "Not a number" } : { value: r };
|
|
4368
4378
|
} catch (n) {
|
|
4369
4379
|
return { value: new H(NaN), error: n instanceof Error ? n.message : String(n) };
|
|
@@ -4378,7 +4388,7 @@ function sn(e, t) {
|
|
|
4378
4388
|
}
|
|
4379
4389
|
return e.toSignificantDigits(12).toString();
|
|
4380
4390
|
}
|
|
4381
|
-
function
|
|
4391
|
+
function Xn({ def: e }) {
|
|
4382
4392
|
const { settings: t } = ue(), n = t.percentMode ?? "of", [a, r] = M(""), [s, u] = M("deg"), [m, d] = M("DEC"), [i, c] = M(!1), [l, p] = M(() => new H(0)), [h, f] = M(() => new H(0)), [y, w] = M([]), k = de(null), S = X(
|
|
4383
4393
|
() => on(a, { angleMode: s, percentMode: n, base: m, ans: h, memory: l }),
|
|
4384
4394
|
[a, s, n, m, h, l]
|
|
@@ -4567,7 +4577,7 @@ function Zn({ def: e }) {
|
|
|
4567
4577
|
] })
|
|
4568
4578
|
] });
|
|
4569
4579
|
}
|
|
4570
|
-
const
|
|
4580
|
+
const rt = [
|
|
4571
4581
|
{ code: "USD", name: "US Dollar", symbol: "$" },
|
|
4572
4582
|
{ code: "EUR", name: "Euro", symbol: "€" },
|
|
4573
4583
|
{ code: "GBP", name: "British Pound", symbol: "£" },
|
|
@@ -4612,28 +4622,28 @@ const at = [
|
|
|
4612
4622
|
{ code: "BDT", name: "Bangladeshi Taka", symbol: "৳" },
|
|
4613
4623
|
{ code: "LKR", name: "Sri Lankan Rupee", symbol: "Rs" },
|
|
4614
4624
|
{ code: "NPR", name: "Nepalese Rupee", symbol: "रू" }
|
|
4615
|
-
],
|
|
4625
|
+
], ai = (e) => rt.find((t) => t.code === e), ri = (e) => e === "INR" ? "en-IN" : "en-US", Qn = (e, t) => g(e).times(t), ea = (e) => {
|
|
4616
4626
|
const t = g(e);
|
|
4617
4627
|
return t.gt(0) ? g(1).div(t) : g(0);
|
|
4618
4628
|
};
|
|
4619
4629
|
function Mt(e, t) {
|
|
4620
4630
|
const n = g(e);
|
|
4621
4631
|
try {
|
|
4622
|
-
return new Intl.NumberFormat(
|
|
4632
|
+
return new Intl.NumberFormat(ri(t), { style: "currency", currency: t }).format(
|
|
4623
4633
|
Number(n.toFixed(4))
|
|
4624
4634
|
);
|
|
4625
4635
|
} catch {
|
|
4626
4636
|
return `${new Intl.NumberFormat("en-US", { maximumFractionDigits: 4 }).format(Number(n.toFixed(4)))} ${t}`;
|
|
4627
4637
|
}
|
|
4628
4638
|
}
|
|
4629
|
-
function
|
|
4639
|
+
function ta(e) {
|
|
4630
4640
|
try {
|
|
4631
4641
|
return new Intl.NumberFormat("en-US", { style: "currency", currency: e }).resolvedOptions().maximumFractionDigits ?? 2;
|
|
4632
4642
|
} catch {
|
|
4633
4643
|
return 2;
|
|
4634
4644
|
}
|
|
4635
4645
|
}
|
|
4636
|
-
function
|
|
4646
|
+
function Xe(e, t) {
|
|
4637
4647
|
const n = Math.max(0, Math.floor((t - e) / 1e3));
|
|
4638
4648
|
if (n < 60) return "just now";
|
|
4639
4649
|
const a = Math.floor(n / 60);
|
|
@@ -4645,23 +4655,23 @@ function Ze(e, t) {
|
|
|
4645
4655
|
const u = Math.floor(s / 30);
|
|
4646
4656
|
return `${u} month${u === 1 ? "" : "s"} ago`;
|
|
4647
4657
|
}
|
|
4648
|
-
const
|
|
4658
|
+
const na = (e, t) => t - e > 864e5, gs = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
|
|
4649
4659
|
__proto__: null,
|
|
4650
|
-
CURRENCIES:
|
|
4651
|
-
convert:
|
|
4652
|
-
currencyByCode:
|
|
4653
|
-
currencyDecimals:
|
|
4660
|
+
CURRENCIES: rt,
|
|
4661
|
+
convert: Qn,
|
|
4662
|
+
currencyByCode: ai,
|
|
4663
|
+
currencyDecimals: ta,
|
|
4654
4664
|
formatCurrency: Mt,
|
|
4655
|
-
inverseRate:
|
|
4656
|
-
isStale:
|
|
4657
|
-
stalenessLabel:
|
|
4658
|
-
}, Symbol.toStringTag, { value: "Module" })),
|
|
4659
|
-
async function
|
|
4665
|
+
inverseRate: ea,
|
|
4666
|
+
isStale: na,
|
|
4667
|
+
stalenessLabel: Xe
|
|
4668
|
+
}, Symbol.toStringTag, { value: "Module" })), oi = (e) => `https://open.er-api.com/v6/latest/${encodeURIComponent(e)}`;
|
|
4669
|
+
async function ii(e, t, n = {}) {
|
|
4660
4670
|
var m;
|
|
4661
4671
|
if (e === t) return { rate: "1", asOf: "", provider: "identity" };
|
|
4662
4672
|
const a = n.fetchImpl ?? (typeof fetch < "u" ? fetch : void 0);
|
|
4663
4673
|
if (!a) throw new Error("No fetch available in this environment");
|
|
4664
|
-
const r = await a(
|
|
4674
|
+
const r = await a(oi(e), { signal: n.signal });
|
|
4665
4675
|
if (!r.ok) throw new Error(`Rate service returned HTTP ${r.status}`);
|
|
4666
4676
|
const s = await r.json();
|
|
4667
4677
|
if (s != null && s.result && s.result !== "success") throw new Error(s["error-type"] || "Rate service error");
|
|
@@ -4673,35 +4683,35 @@ function ln(e, t) {
|
|
|
4673
4683
|
const n = Date.parse(e);
|
|
4674
4684
|
return Number.isFinite(n) ? n : t;
|
|
4675
4685
|
}
|
|
4676
|
-
const
|
|
4686
|
+
const aa = "calcsuite:fxrates", ra = "calcsuite:fxmode", wt = () => {
|
|
4677
4687
|
try {
|
|
4678
|
-
return JSON.parse(localStorage.getItem(
|
|
4688
|
+
return JSON.parse(localStorage.getItem(aa) || "{}");
|
|
4679
4689
|
} catch {
|
|
4680
4690
|
return {};
|
|
4681
4691
|
}
|
|
4682
|
-
},
|
|
4692
|
+
}, si = (e) => {
|
|
4683
4693
|
try {
|
|
4684
|
-
localStorage.setItem(
|
|
4694
|
+
localStorage.setItem(aa, JSON.stringify(e));
|
|
4685
4695
|
} catch {
|
|
4686
4696
|
}
|
|
4687
|
-
},
|
|
4697
|
+
}, li = () => {
|
|
4688
4698
|
try {
|
|
4689
|
-
return localStorage.getItem(
|
|
4699
|
+
return localStorage.getItem(ra) === "offline" ? "offline" : "online";
|
|
4690
4700
|
} catch {
|
|
4691
4701
|
return "online";
|
|
4692
4702
|
}
|
|
4693
|
-
},
|
|
4694
|
-
function
|
|
4703
|
+
}, We = (e, t) => `${e}_${t}`;
|
|
4704
|
+
function oa() {
|
|
4695
4705
|
var _t;
|
|
4696
|
-
const [e, t] = M("USD"), [n, a] = M("INR"), [r, s] = M(""), [u, m] = M(""), [d, i] = M("none"), [c, l] = M(""), [p, h] = M("idle"), [f, y] = M(""), [w, k] = M(() =>
|
|
4706
|
+
const [e, t] = M("USD"), [n, a] = M("INR"), [r, s] = M(""), [u, m] = M(""), [d, i] = M("none"), [c, l] = M(""), [p, h] = M("idle"), [f, y] = M(""), [w, k] = M(() => li()), [S, F] = M(() => wt()), [N, P] = M(() => Date.now()), x = de(null);
|
|
4697
4707
|
Q(() => {
|
|
4698
4708
|
const O = setInterval(() => P(Date.now()), 3e4);
|
|
4699
4709
|
return () => clearInterval(O);
|
|
4700
4710
|
}, []);
|
|
4701
4711
|
const T = (O, Z) => {
|
|
4702
4712
|
F((ae) => {
|
|
4703
|
-
const oe = { ...ae, [
|
|
4704
|
-
return
|
|
4713
|
+
const oe = { ...ae, [We(e, n)]: { rate: O, at: Z } };
|
|
4714
|
+
return si(oe), oe;
|
|
4705
4715
|
});
|
|
4706
4716
|
}, $ = (O, Z) => {
|
|
4707
4717
|
var oe;
|
|
@@ -4711,11 +4721,11 @@ function ra() {
|
|
|
4711
4721
|
m("1"), i("live"), l(""), h("idle");
|
|
4712
4722
|
return;
|
|
4713
4723
|
}
|
|
4714
|
-
h("loading"), y(""),
|
|
4724
|
+
h("loading"), y(""), ii(O, Z, { signal: ae.signal }).then((xe) => {
|
|
4715
4725
|
ae.signal.aborted || (m(xe.rate), i("live"), l(xe.asOf), h("idle"), T(xe.rate, ln(xe.asOf, Date.now())));
|
|
4716
4726
|
}).catch((xe) => {
|
|
4717
4727
|
if (ae.signal.aborted) return;
|
|
4718
|
-
const Ht = wt()[
|
|
4728
|
+
const Ht = wt()[We(O, Z)];
|
|
4719
4729
|
Ht ? (m(Ht.rate), i("saved"), h("error"), y("Offline — showing your last saved rate. Refresh when back online.")) : (i("none"), h("error"), y(`Couldn’t fetch a live rate (${xe instanceof Error ? xe.message : "offline"}). Enter one manually.`));
|
|
4720
4730
|
});
|
|
4721
4731
|
}, L = (O, Z) => {
|
|
@@ -4724,7 +4734,7 @@ function ra() {
|
|
|
4724
4734
|
m("1"), i("saved");
|
|
4725
4735
|
return;
|
|
4726
4736
|
}
|
|
4727
|
-
const ae = wt()[
|
|
4737
|
+
const ae = wt()[We(O, Z)];
|
|
4728
4738
|
ae ? (m(ae.rate), i("saved")) : (m(""), i("none"));
|
|
4729
4739
|
};
|
|
4730
4740
|
Q(() => (w === "online" ? $(e, n) : L(e, n), () => {
|
|
@@ -4734,21 +4744,21 @@ function ra() {
|
|
|
4734
4744
|
const B = (O) => {
|
|
4735
4745
|
k(O);
|
|
4736
4746
|
try {
|
|
4737
|
-
localStorage.setItem(
|
|
4747
|
+
localStorage.setItem(ra, O);
|
|
4738
4748
|
} catch {
|
|
4739
4749
|
}
|
|
4740
4750
|
}, G = (O) => O.replace(/[, ]/g, "").trim(), q = G(r), A = G(u), I = q !== "" && Number(q) >= 0 && Number.isFinite(Number(q)), R = A !== "" && Number(A) > 0 && Number.isFinite(Number(A)), j = X(
|
|
4741
|
-
() => I && R ?
|
|
4751
|
+
() => I && R ? Qn(q, A) : null,
|
|
4742
4752
|
[I, R, q, A]
|
|
4743
|
-
), Y = R ?
|
|
4753
|
+
), Y = R ? ea(A) : null, V = (O) => {
|
|
4744
4754
|
m(O), i("manual"), h("idle"), y(""), (R || O.trim() !== "") && T(G(O), Date.now());
|
|
4745
4755
|
}, ee = () => {
|
|
4746
4756
|
t(n), a(e);
|
|
4747
|
-
}, Ee = c ?
|
|
4757
|
+
}, Ee = c ? Xe(ln(c, N), N) : "just now", K = (_t = S[We(e, n)]) == null ? void 0 : _t.at, pe = (O) => /* @__PURE__ */ b("option", { value: O.code, children: [
|
|
4748
4758
|
O.code,
|
|
4749
4759
|
" — ",
|
|
4750
4760
|
O.name
|
|
4751
|
-
] }, O.code), Me = Object.entries(S).sort((O, Z) => Z[1].at - O[1].at),
|
|
4761
|
+
] }, O.code), Me = Object.entries(S).sort((O, Z) => Z[1].at - O[1].at), je = () => p === "error" ? /* @__PURE__ */ b("span", { children: [
|
|
4752
4762
|
"⚠ ",
|
|
4753
4763
|
f
|
|
4754
4764
|
] }) : d === "manual" ? /* @__PURE__ */ o("span", { children: "Manual rate (you entered this)" }) : w === "online" ? p === "loading" ? /* @__PURE__ */ o("span", { children: "Fetching live rate…" }) : d === "live" ? /* @__PURE__ */ b("span", { children: [
|
|
@@ -4758,7 +4768,7 @@ function ra() {
|
|
|
4758
4768
|
" · open.er-api.com"
|
|
4759
4769
|
] }) : null : d === "saved" && K ? /* @__PURE__ */ b("span", { children: [
|
|
4760
4770
|
"✈ Offline · saved rate ",
|
|
4761
|
-
|
|
4771
|
+
Xe(K, N)
|
|
4762
4772
|
] }) : /* @__PURE__ */ o("span", { children: "✈ Offline · enter a rate manually" });
|
|
4763
4773
|
return /* @__PURE__ */ b("div", { "data-part": "calculator", "data-calculator": "tools.currency", children: [
|
|
4764
4774
|
/* @__PURE__ */ b("section", { className: "card", children: [
|
|
@@ -4783,12 +4793,12 @@ function ra() {
|
|
|
4783
4793
|
] }),
|
|
4784
4794
|
/* @__PURE__ */ b("label", { className: "field cc-cur", children: [
|
|
4785
4795
|
/* @__PURE__ */ o("span", { className: "lbl", children: "From" }),
|
|
4786
|
-
/* @__PURE__ */ o("div", { className: "input-wrap", children: /* @__PURE__ */ o("select", { value: e, onChange: (O) => t(O.target.value), "aria-label": "From currency", children:
|
|
4796
|
+
/* @__PURE__ */ o("div", { className: "input-wrap", children: /* @__PURE__ */ o("select", { value: e, onChange: (O) => t(O.target.value), "aria-label": "From currency", children: rt.map(pe) }) })
|
|
4787
4797
|
] }),
|
|
4788
4798
|
/* @__PURE__ */ o("button", { type: "button", className: "cc-swap", onClick: ee, "aria-label": "Swap currencies", title: "Swap", children: "⇄" }),
|
|
4789
4799
|
/* @__PURE__ */ b("label", { className: "field cc-cur", children: [
|
|
4790
4800
|
/* @__PURE__ */ o("span", { className: "lbl", children: "To" }),
|
|
4791
|
-
/* @__PURE__ */ o("div", { className: "input-wrap", children: /* @__PURE__ */ o("select", { value: n, onChange: (O) => a(O.target.value), "aria-label": "To currency", children:
|
|
4801
|
+
/* @__PURE__ */ o("div", { className: "input-wrap", children: /* @__PURE__ */ o("select", { value: n, onChange: (O) => a(O.target.value), "aria-label": "To currency", children: rt.map(pe) }) })
|
|
4792
4802
|
] })
|
|
4793
4803
|
] }),
|
|
4794
4804
|
/* @__PURE__ */ b("label", { className: "field", style: { marginTop: 16 }, children: [
|
|
@@ -4822,7 +4832,7 @@ function ra() {
|
|
|
4822
4832
|
}
|
|
4823
4833
|
)
|
|
4824
4834
|
] }),
|
|
4825
|
-
/* @__PURE__ */ o("div", { className: `cc-status ${p === "error" ? "cc-stale" : ""}`, "aria-live": "polite", children:
|
|
4835
|
+
/* @__PURE__ */ o("div", { className: `cc-status ${p === "error" ? "cc-stale" : ""}`, "aria-live": "polite", children: je() }),
|
|
4826
4836
|
e === n && /* @__PURE__ */ o("div", { className: "notice", children: "“From” and “To” are the same currency — the rate is 1." })
|
|
4827
4837
|
] })
|
|
4828
4838
|
] }),
|
|
@@ -4859,7 +4869,7 @@ function ra() {
|
|
|
4859
4869
|
/* @__PURE__ */ b("div", { className: "kv", children: [
|
|
4860
4870
|
/* @__PURE__ */ o("div", { className: "k", children: "Precision" }),
|
|
4861
4871
|
/* @__PURE__ */ b("div", { className: "v num", children: [
|
|
4862
|
-
|
|
4872
|
+
ta(n),
|
|
4863
4873
|
" dp · ",
|
|
4864
4874
|
n
|
|
4865
4875
|
] })
|
|
@@ -4892,7 +4902,7 @@ function ra() {
|
|
|
4892
4902
|
oe
|
|
4893
4903
|
] }),
|
|
4894
4904
|
/* @__PURE__ */ o("span", { className: "num", children: Z.rate }),
|
|
4895
|
-
/* @__PURE__ */ o("span", { className: `cc-book-when ${
|
|
4905
|
+
/* @__PURE__ */ o("span", { className: `cc-book-when ${na(Z.at, N) ? "cc-stale" : ""}`, children: Xe(Z.at, N) })
|
|
4896
4906
|
]
|
|
4897
4907
|
}
|
|
4898
4908
|
) }, O);
|
|
@@ -4900,23 +4910,23 @@ function ra() {
|
|
|
4900
4910
|
] })
|
|
4901
4911
|
] });
|
|
4902
4912
|
}
|
|
4903
|
-
const
|
|
4913
|
+
const ci = {
|
|
4904
4914
|
id: "",
|
|
4905
4915
|
group: "tools",
|
|
4906
4916
|
title: "",
|
|
4907
4917
|
inputs: [],
|
|
4908
4918
|
compute: () => ({ primary: { label: "", value: "" } })
|
|
4909
|
-
},
|
|
4910
|
-
"loan.emi":
|
|
4911
|
-
scientific:
|
|
4912
|
-
currency:
|
|
4919
|
+
}, ui = {
|
|
4920
|
+
"loan.emi": Jn,
|
|
4921
|
+
scientific: Xn,
|
|
4922
|
+
currency: oa
|
|
4913
4923
|
};
|
|
4914
4924
|
function cn(e, t) {
|
|
4915
4925
|
const n = {};
|
|
4916
4926
|
for (const a of e.inputs) a.default !== void 0 && (n[a.key] = a.default);
|
|
4917
4927
|
return t ? { ...n, ...t } : n;
|
|
4918
4928
|
}
|
|
4919
|
-
function
|
|
4929
|
+
function di({
|
|
4920
4930
|
def: e,
|
|
4921
4931
|
id: t,
|
|
4922
4932
|
seed: n,
|
|
@@ -4925,7 +4935,7 @@ function ci({
|
|
|
4925
4935
|
actions: s
|
|
4926
4936
|
}) {
|
|
4927
4937
|
var L, B, G, q;
|
|
4928
|
-
const u = e ?? (t ? Rt(t) : void 0), m = u ??
|
|
4938
|
+
const u = e ?? (t ? Rt(t) : void 0), m = u ?? ci, d = { ...ui, ...a }, { settings: i, fmt: c } = ue(), [l, p] = M(() => cn(m, n)), [h, f] = M("schedule"), [y, w] = M(!1);
|
|
4929
4939
|
Q(() => p(cn(m, n)), [m.id, n]);
|
|
4930
4940
|
const k = i.region, S = (A, I) => p((R) => ({ ...R, [A]: I })), F = m.inputs.filter((A) => A.showIf ? A.showIf(l, k) : !0), N = F.filter((A) => !A.advanced), P = F.filter((A) => A.advanced), { result: x, error: T } = X(() => {
|
|
4931
4941
|
const A = { settings: i, region: k, fmt: c, D: g };
|
|
@@ -4963,7 +4973,7 @@ function ci({
|
|
|
4963
4973
|
T && /* @__PURE__ */ o("div", { className: "error", role: "alert", style: { marginTop: 16 }, children: T })
|
|
4964
4974
|
] }),
|
|
4965
4975
|
x && !T && /* @__PURE__ */ b("section", { className: "card", children: [
|
|
4966
|
-
/* @__PURE__ */ o(
|
|
4976
|
+
/* @__PURE__ */ o(ro, { view: x }),
|
|
4967
4977
|
(B = x.warnings) == null ? void 0 : B.map((A, I) => /* @__PURE__ */ o("div", { className: "notice", children: A }, I)),
|
|
4968
4978
|
s && /* @__PURE__ */ o("div", { className: "actions-row", children: s(x, l) }),
|
|
4969
4979
|
$ && /* @__PURE__ */ b(re, { children: [
|
|
@@ -4974,8 +4984,8 @@ function ci({
|
|
|
4974
4984
|
(((G = x.notes) == null ? void 0 : G.length) ?? 0) > 0 && i.ui.showAssumptions && /* @__PURE__ */ o("button", { role: "tab", "aria-selected": h === "assumptions", onClick: () => f("assumptions"), children: "Assumptions" })
|
|
4975
4985
|
] }),
|
|
4976
4986
|
/* @__PURE__ */ b("div", { className: "tab-anim", children: [
|
|
4977
|
-
h === "schedule" && x.schedule && /* @__PURE__ */ o(
|
|
4978
|
-
h === "chart" && x.chart && /* @__PURE__ */ o(
|
|
4987
|
+
h === "schedule" && x.schedule && /* @__PURE__ */ o(so, { schedule: x.schedule }),
|
|
4988
|
+
h === "chart" && x.chart && /* @__PURE__ */ o(lo, { chart: x.chart }),
|
|
4979
4989
|
h === "formula" && x.formula && i.ui.showFormulas && /* @__PURE__ */ b("div", { className: "formula", children: [
|
|
4980
4990
|
/* @__PURE__ */ o("code", { children: x.formula }),
|
|
4981
4991
|
x.formulaSubstituted && /* @__PURE__ */ o("code", { style: { marginTop: 8 }, children: x.formulaSubstituted })
|
|
@@ -4998,7 +5008,7 @@ function un({ def: e, region: t }) {
|
|
|
4998
5008
|
}
|
|
4999
5009
|
function dn({ f: e, values: t, set: n }) {
|
|
5000
5010
|
const a = e.kind === "cashflows" || e.kind === "segmented" ? "span2" : "";
|
|
5001
|
-
return /* @__PURE__ */ o("div", { className: a, children: /* @__PURE__ */ o(
|
|
5011
|
+
return /* @__PURE__ */ o("div", { className: a, children: /* @__PURE__ */ o(to, { f: e, value: t[e.key], onChange: (r) => n(e.key, r), values: t }) });
|
|
5002
5012
|
}
|
|
5003
5013
|
class z extends Error {
|
|
5004
5014
|
constructor(n, a = { code: "transport_error" }) {
|
|
@@ -5010,17 +5020,17 @@ class z extends Error {
|
|
|
5010
5020
|
this.name = "TransportError", this.code = a.code, this.status = a.status ?? 0, this.request = a.request;
|
|
5011
5021
|
}
|
|
5012
5022
|
}
|
|
5013
|
-
const
|
|
5023
|
+
const mi = ["authorization", "cookie", "x-api-key", "x-auth-token", "api-key"], pi = {
|
|
5014
5024
|
attempts: 3,
|
|
5015
5025
|
backoff: "exponential",
|
|
5016
5026
|
baseDelayMs: 300,
|
|
5017
5027
|
retryOn: [408, 429, 500, 502, 503, 504],
|
|
5018
5028
|
respectRetryAfter: !0
|
|
5019
|
-
},
|
|
5029
|
+
}, hi = {
|
|
5020
5030
|
enabled: !0,
|
|
5021
5031
|
headerName: "Idempotency-Key",
|
|
5022
5032
|
keyFrom: "inputsHash"
|
|
5023
|
-
},
|
|
5033
|
+
}, fi = {
|
|
5024
5034
|
enabled: !0,
|
|
5025
5035
|
storage: "memory",
|
|
5026
5036
|
maxItems: 200,
|
|
@@ -5032,7 +5042,7 @@ const ui = ["authorization", "cookie", "x-api-key", "x-auth-token", "api-key"],
|
|
|
5032
5042
|
return !1;
|
|
5033
5043
|
}
|
|
5034
5044
|
};
|
|
5035
|
-
function
|
|
5045
|
+
function ia() {
|
|
5036
5046
|
const e = globalThis.crypto;
|
|
5037
5047
|
return e != null && e.randomUUID ? e.randomUUID() : "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, (t) => {
|
|
5038
5048
|
const n = Math.random() * 16 | 0;
|
|
@@ -5040,21 +5050,21 @@ function oa() {
|
|
|
5040
5050
|
});
|
|
5041
5051
|
}
|
|
5042
5052
|
const pn = (e) => new Promise((t) => setTimeout(t, Math.max(0, e)));
|
|
5043
|
-
function
|
|
5053
|
+
function yi(e) {
|
|
5044
5054
|
let t = String(e).replace(/[\\/]+/g, "-").replace(/[\x00-\x1f\x7f]+/g, "").replace(/[<>:"|?*]+/g, "").replace(/^\.+/, "");
|
|
5045
5055
|
return t = t.trim(), t || "file";
|
|
5046
5056
|
}
|
|
5047
|
-
function
|
|
5057
|
+
function sa(e, t) {
|
|
5048
5058
|
var m;
|
|
5049
5059
|
const n = /* @__PURE__ */ new Date(), a = (d) => String(d).padStart(2, "0"), r = (((m = t.filename) == null ? void 0 : m.split(".").pop()) || t.kind || "bin").toLowerCase(), s = (t.inputsHash || "").replace(/^sha256:/, "").slice(0, 8) || "00000000", u = e.replace(/\{calculator\}/g, t.calculator || "calc").replace(/\{yyyy\}/g, String(n.getFullYear())).replace(/\{MM\}/g, a(n.getMonth() + 1)).replace(/\{dd\}/g, a(n.getDate())).replace(/\{hash8\}/g, s).replace(/\{ext\}/g, r).replace(/\{kind\}/g, t.kind || "file");
|
|
5050
|
-
return
|
|
5060
|
+
return yi(u);
|
|
5051
5061
|
}
|
|
5052
5062
|
function $t(e, t = []) {
|
|
5053
|
-
const n = /* @__PURE__ */ new Set([...
|
|
5063
|
+
const n = /* @__PURE__ */ new Set([...mi, ...t.map((r) => r.toLowerCase())]), a = {};
|
|
5054
5064
|
for (const [r, s] of Object.entries(e)) a[r] = n.has(r.toLowerCase()) ? "***" : s;
|
|
5055
5065
|
return a;
|
|
5056
5066
|
}
|
|
5057
|
-
class
|
|
5067
|
+
class bi {
|
|
5058
5068
|
constructor(t, n) {
|
|
5059
5069
|
ge(this, "items", []);
|
|
5060
5070
|
ge(this, "key");
|
|
@@ -5082,7 +5092,7 @@ class fi {
|
|
|
5082
5092
|
return this.items.length;
|
|
5083
5093
|
}
|
|
5084
5094
|
enqueue(t) {
|
|
5085
|
-
const n = { ...t, id:
|
|
5095
|
+
const n = { ...t, id: ia(), createdAt: (/* @__PURE__ */ new Date()).toISOString(), retryCount: 0 };
|
|
5086
5096
|
for (this.items.push(n); this.items.length > this.cfg.maxItems; ) this.items.shift();
|
|
5087
5097
|
return this.save(), n;
|
|
5088
5098
|
}
|
|
@@ -5104,12 +5114,12 @@ class fi {
|
|
|
5104
5114
|
}
|
|
5105
5115
|
}
|
|
5106
5116
|
const hn = /* @__PURE__ */ new Set(["POST", "PUT", "PATCH", "DELETE"]);
|
|
5107
|
-
function
|
|
5108
|
-
const t = e.fetch ?? globalThis.fetch, n = { ...
|
|
5117
|
+
function gi(e) {
|
|
5118
|
+
const t = e.fetch ?? globalThis.fetch, n = { ...pi, ...e.retry }, a = { ...hi, ...e.idempotency }, r = { ...fi, ...e.offlineQueue }, s = e.timeoutMs ?? 15e3, u = e.credentials ?? "same-origin", m = new bi(r, "calcsuite");
|
|
5109
5119
|
function d(N, P) {
|
|
5110
5120
|
const x = e.endpoints[N];
|
|
5111
5121
|
if (!x) throw new z(`Endpoint "${N}" is not configured`, { code: "no_endpoint" });
|
|
5112
|
-
let T = /^https?:\/\//i.test(x) ? x :
|
|
5122
|
+
let T = /^https?:\/\//i.test(x) ? x : vi(e.baseUrl, x);
|
|
5113
5123
|
return P != null && (T = T.replace(/:id\b/, encodeURIComponent(P))), T;
|
|
5114
5124
|
}
|
|
5115
5125
|
function i() {
|
|
@@ -5124,10 +5134,10 @@ function yi(e) {
|
|
|
5124
5134
|
if (!a.enabled || x) return x;
|
|
5125
5135
|
if (hn.has(fn(N))) {
|
|
5126
5136
|
if (a.keyFrom === "inputsHash") {
|
|
5127
|
-
const T =
|
|
5137
|
+
const T = wi(P);
|
|
5128
5138
|
if (T) return T;
|
|
5129
5139
|
}
|
|
5130
|
-
return
|
|
5140
|
+
return ia();
|
|
5131
5141
|
}
|
|
5132
5142
|
}
|
|
5133
5143
|
async function p(N, P, x) {
|
|
@@ -5154,7 +5164,7 @@ function yi(e) {
|
|
|
5154
5164
|
}
|
|
5155
5165
|
async function f(N, P = {}) {
|
|
5156
5166
|
var B, G, q, A;
|
|
5157
|
-
const x = fn(N), T =
|
|
5167
|
+
const x = fn(N), T = ki(d(N, P.pathParam), P.query), $ = l(N, P.body, P.idempotencyKey);
|
|
5158
5168
|
let L;
|
|
5159
5169
|
for (let I = 1; I <= Math.max(1, n.attempts); I++) {
|
|
5160
5170
|
const R = await c(), j = {
|
|
@@ -5184,7 +5194,7 @@ function yi(e) {
|
|
|
5184
5194
|
await pn(h(I, K));
|
|
5185
5195
|
continue;
|
|
5186
5196
|
}
|
|
5187
|
-
const pe = await
|
|
5197
|
+
const pe = await la(K), Me = {
|
|
5188
5198
|
...ee,
|
|
5189
5199
|
status: K.status,
|
|
5190
5200
|
ok: K.ok,
|
|
@@ -5192,12 +5202,12 @@ function yi(e) {
|
|
|
5192
5202
|
data: pe
|
|
5193
5203
|
};
|
|
5194
5204
|
if ((G = e.onResponse) == null || G.call(e, Me), !K.ok) {
|
|
5195
|
-
const
|
|
5205
|
+
const je = new z(`Request failed with ${K.status}`, {
|
|
5196
5206
|
code: "http_error",
|
|
5197
5207
|
status: K.status,
|
|
5198
5208
|
request: ee
|
|
5199
5209
|
});
|
|
5200
|
-
throw (q = e.onError) == null || q.call(e,
|
|
5210
|
+
throw (q = e.onError) == null || q.call(e, je, ee), je;
|
|
5201
5211
|
}
|
|
5202
5212
|
return e.transformResponse ? e.transformResponse(pe, ee) : pe;
|
|
5203
5213
|
} catch (K) {
|
|
@@ -5223,8 +5233,8 @@ function yi(e) {
|
|
|
5223
5233
|
}
|
|
5224
5234
|
async function y(N, P, x = {}) {
|
|
5225
5235
|
const T = e.upload;
|
|
5226
|
-
|
|
5227
|
-
const $ = P.filename ??
|
|
5236
|
+
xi(N, P, T.accept, T.maxBytes);
|
|
5237
|
+
const $ = P.filename ?? sa(T.filenameTemplate, P), L = { ...P, filename: $, bytes: N.size, contentType: P.contentType ?? ca(N) };
|
|
5228
5238
|
if (T.beforeUpload && !await T.beforeUpload(N, L))
|
|
5229
5239
|
throw new z("Upload cancelled by host", { code: "upload_cancelled" });
|
|
5230
5240
|
return T.strategy === "presigned" ? F(N, L, x) : T.strategy === "base64Json" ? S(N, L, x) : k(N, L, x);
|
|
@@ -5255,10 +5265,10 @@ function yi(e) {
|
|
|
5255
5265
|
{ method: "POST", credentials: u, headers: B, body: $ },
|
|
5256
5266
|
x.signal
|
|
5257
5267
|
);
|
|
5258
|
-
return
|
|
5268
|
+
return Ni(G);
|
|
5259
5269
|
}
|
|
5260
5270
|
async function S(N, P, x) {
|
|
5261
|
-
const T = await
|
|
5271
|
+
const T = await Si(N);
|
|
5262
5272
|
return f("upload", {
|
|
5263
5273
|
...x,
|
|
5264
5274
|
body: {
|
|
@@ -5345,23 +5355,23 @@ function fn(e) {
|
|
|
5345
5355
|
function yn() {
|
|
5346
5356
|
return typeof performance < "u" && performance.now ? performance.now() : Date.now();
|
|
5347
5357
|
}
|
|
5348
|
-
function
|
|
5358
|
+
function vi(e, t) {
|
|
5349
5359
|
return e ? `${e.replace(/\/+$/, "")}/${t.replace(/^\/+/, "")}` : t;
|
|
5350
5360
|
}
|
|
5351
|
-
function
|
|
5361
|
+
function ki(e, t) {
|
|
5352
5362
|
if (!t) return e;
|
|
5353
5363
|
const n = [];
|
|
5354
5364
|
for (const [a, r] of Object.entries(t))
|
|
5355
5365
|
r == null || r === "" || n.push(`${encodeURIComponent(a)}=${encodeURIComponent(String(r))}`);
|
|
5356
5366
|
return n.length ? e + (e.includes("?") ? "&" : "?") + n.join("&") : e;
|
|
5357
5367
|
}
|
|
5358
|
-
function
|
|
5368
|
+
function wi(e) {
|
|
5359
5369
|
var a;
|
|
5360
5370
|
if (!e || typeof e != "object") return;
|
|
5361
5371
|
const t = e, n = ((a = t == null ? void 0 : t.meta) == null ? void 0 : a.inputsHash) ?? (t == null ? void 0 : t.inputsHash);
|
|
5362
5372
|
return typeof n == "string" && n ? n : void 0;
|
|
5363
5373
|
}
|
|
5364
|
-
async function
|
|
5374
|
+
async function la(e) {
|
|
5365
5375
|
const t = e.headers.get("content-type") || "";
|
|
5366
5376
|
try {
|
|
5367
5377
|
return t.includes("application/json") ? await e.json() : await e.text() || null;
|
|
@@ -5369,21 +5379,21 @@ async function sa(e) {
|
|
|
5369
5379
|
return null;
|
|
5370
5380
|
}
|
|
5371
5381
|
}
|
|
5372
|
-
async function
|
|
5382
|
+
async function Ni(e) {
|
|
5373
5383
|
if (!e.ok) throw new z(`Upload failed (${e.status})`, { code: "upload_failed", status: e.status });
|
|
5374
|
-
return
|
|
5384
|
+
return la(e);
|
|
5375
5385
|
}
|
|
5376
|
-
function
|
|
5386
|
+
function ca(e) {
|
|
5377
5387
|
return e.type || "application/octet-stream";
|
|
5378
5388
|
}
|
|
5379
|
-
function
|
|
5389
|
+
function xi(e, t, n, a) {
|
|
5380
5390
|
if (e.size > a)
|
|
5381
5391
|
throw new z(`File exceeds ${a} bytes`, { code: "too_large" });
|
|
5382
|
-
const r = t.contentType ??
|
|
5392
|
+
const r = t.contentType ?? ca(e);
|
|
5383
5393
|
if (n.length && r && !n.includes(r))
|
|
5384
5394
|
throw new z(`Content type ${r} not accepted`, { code: "bad_type" });
|
|
5385
5395
|
}
|
|
5386
|
-
async function
|
|
5396
|
+
async function Si(e) {
|
|
5387
5397
|
const t = await e.arrayBuffer(), n = new Uint8Array(t);
|
|
5388
5398
|
if (typeof btoa == "function") {
|
|
5389
5399
|
let r = "";
|
|
@@ -5394,7 +5404,7 @@ async function Ni(e) {
|
|
|
5394
5404
|
if (a) return a.from(n).toString("base64");
|
|
5395
5405
|
throw new z("No base64 encoder available", { code: "no_base64" });
|
|
5396
5406
|
}
|
|
5397
|
-
function
|
|
5407
|
+
function ze(e, t) {
|
|
5398
5408
|
if (!t) return e;
|
|
5399
5409
|
let n = e;
|
|
5400
5410
|
for (const a of t.split(".")) {
|
|
@@ -5412,15 +5422,15 @@ function bn(e, t, n) {
|
|
|
5412
5422
|
}
|
|
5413
5423
|
r[a[a.length - 1]] = n;
|
|
5414
5424
|
}
|
|
5415
|
-
function
|
|
5425
|
+
function Ci(e, t) {
|
|
5416
5426
|
if (t === "asIs") return e;
|
|
5417
5427
|
const n = e.replace(/([a-z0-9])([A-Z])/g, "$1 $2").replace(/[_\-\s]+/g, " ").trim().split(" ").filter(Boolean);
|
|
5418
5428
|
return n.length === 0 ? e : t === "snake" ? n.map((a) => a.toLowerCase()).join("_") : t === "kebab" ? n.map((a) => a.toLowerCase()).join("-") : n.map((a, r) => r === 0 ? a.toLowerCase() : a[0].toUpperCase() + a.slice(1).toLowerCase()).join("");
|
|
5419
5429
|
}
|
|
5420
5430
|
function gn(e, t) {
|
|
5421
|
-
return e.split(".").map((n) =>
|
|
5431
|
+
return e.split(".").map((n) => Ci(n, t)).join(".");
|
|
5422
5432
|
}
|
|
5423
|
-
function
|
|
5433
|
+
function Pi(e, t) {
|
|
5424
5434
|
switch (t) {
|
|
5425
5435
|
case "toFixed2":
|
|
5426
5436
|
return Number(e).toFixed(2);
|
|
@@ -5437,11 +5447,11 @@ function Si(e, t) {
|
|
|
5437
5447
|
return e;
|
|
5438
5448
|
}
|
|
5439
5449
|
}
|
|
5440
|
-
function
|
|
5450
|
+
function Ti(e, t) {
|
|
5441
5451
|
const n = e instanceof Date ? e : new Date(e);
|
|
5442
5452
|
return Number.isNaN(n.getTime()) ? String(e) : n.toISOString();
|
|
5443
5453
|
}
|
|
5444
|
-
function
|
|
5454
|
+
function Fi(e, t, n) {
|
|
5445
5455
|
switch (t) {
|
|
5446
5456
|
case "number": {
|
|
5447
5457
|
if (n.numberEncoding === "number") {
|
|
@@ -5453,7 +5463,7 @@ function Pi(e, t, n) {
|
|
|
5453
5463
|
case "boolean":
|
|
5454
5464
|
return typeof e == "string" ? e.toLowerCase() === "true" : !!e;
|
|
5455
5465
|
case "date":
|
|
5456
|
-
return
|
|
5466
|
+
return Ti(e, n.dateFormat);
|
|
5457
5467
|
case "json":
|
|
5458
5468
|
return e;
|
|
5459
5469
|
case "string":
|
|
@@ -5461,30 +5471,30 @@ function Pi(e, t, n) {
|
|
|
5461
5471
|
return String(e);
|
|
5462
5472
|
}
|
|
5463
5473
|
}
|
|
5464
|
-
function
|
|
5474
|
+
function ot(e, t) {
|
|
5465
5475
|
if (t === "number") return e;
|
|
5466
5476
|
if (typeof e == "number") return String(e);
|
|
5467
|
-
if (Array.isArray(e)) return e.map((n) =>
|
|
5477
|
+
if (Array.isArray(e)) return e.map((n) => ot(n, t));
|
|
5468
5478
|
if (e && typeof e == "object") {
|
|
5469
5479
|
const n = {};
|
|
5470
|
-
for (const [a, r] of Object.entries(e)) n[a] =
|
|
5480
|
+
for (const [a, r] of Object.entries(e)) n[a] = ot(r, t);
|
|
5471
5481
|
return n;
|
|
5472
5482
|
}
|
|
5473
5483
|
return e;
|
|
5474
5484
|
}
|
|
5475
|
-
function
|
|
5485
|
+
function Ii(e, t) {
|
|
5476
5486
|
var n;
|
|
5477
5487
|
switch (e.kind) {
|
|
5478
5488
|
case "static":
|
|
5479
5489
|
return e.value;
|
|
5480
5490
|
case "input":
|
|
5481
|
-
return
|
|
5491
|
+
return ze(t.inputs, e.path);
|
|
5482
5492
|
case "output":
|
|
5483
|
-
return
|
|
5493
|
+
return ze(t.outputs, e.path);
|
|
5484
5494
|
case "setting":
|
|
5485
|
-
return
|
|
5495
|
+
return ze(t.settings, e.path);
|
|
5486
5496
|
case "context":
|
|
5487
|
-
return
|
|
5497
|
+
return ze(t.context, e.path);
|
|
5488
5498
|
case "token":
|
|
5489
5499
|
return (n = t.tokens) == null ? void 0 : n[e.name];
|
|
5490
5500
|
case "callback":
|
|
@@ -5493,10 +5503,10 @@ function Ti(e, t) {
|
|
|
5493
5503
|
return;
|
|
5494
5504
|
}
|
|
5495
5505
|
}
|
|
5496
|
-
function
|
|
5506
|
+
function Ri(e, t, n) {
|
|
5497
5507
|
const a = {};
|
|
5498
5508
|
for (const u of e) {
|
|
5499
|
-
let m =
|
|
5509
|
+
let m = Ii(u.source, n);
|
|
5500
5510
|
const d = m === "" || m == null;
|
|
5501
5511
|
if (u.omitWhenEmpty && d) continue;
|
|
5502
5512
|
const i = gn(u.key, t.keyCase);
|
|
@@ -5505,14 +5515,14 @@ function Fi(e, t, n) {
|
|
|
5505
5515
|
bn(a, i, null);
|
|
5506
5516
|
continue;
|
|
5507
5517
|
}
|
|
5508
|
-
u.transform && u.transform !== "none" && (m =
|
|
5518
|
+
u.transform && u.transform !== "none" && (m = Pi(m, u.transform)), bn(a, i, Fi(m, u.type, t));
|
|
5509
5519
|
}
|
|
5510
5520
|
const r = t.include, s = (u, m) => {
|
|
5511
|
-
m !== void 0 && (a[gn(u, t.keyCase)] =
|
|
5521
|
+
m !== void 0 && (a[gn(u, t.keyCase)] = ot(m, t.numberEncoding));
|
|
5512
5522
|
};
|
|
5513
5523
|
return r != null && r.inputs && s("inputs", n.inputs), r != null && r.outputs && s("outputs", n.outputs), r != null && r.schedule && s("schedule", n.schedule), r != null && r.settingsSnapshot && s("settingsSnapshot", n.settings), r != null && r.meta && s("meta", n.context), t.numberEncoding === "number" && console.warn('[fincalc] numberEncoding="number" reintroduces float error; prefer "string".'), t.mode === "wrapped" && t.wrapperKey ? { [t.wrapperKey]: a } : a;
|
|
5514
5524
|
}
|
|
5515
|
-
const
|
|
5525
|
+
const vs = {
|
|
5516
5526
|
mode: "flat",
|
|
5517
5527
|
keyCase: "asIs",
|
|
5518
5528
|
dateFormat: "iso",
|
|
@@ -5521,9 +5531,9 @@ const bs = {
|
|
|
5521
5531
|
include: { inputs: !0, outputs: !0, schedule: !1, settingsSnapshot: !0, meta: !0 }
|
|
5522
5532
|
};
|
|
5523
5533
|
function vn(e) {
|
|
5524
|
-
return
|
|
5534
|
+
return ot(e, "string");
|
|
5525
5535
|
}
|
|
5526
|
-
function
|
|
5536
|
+
function ks(e) {
|
|
5527
5537
|
const t = e.settings;
|
|
5528
5538
|
return {
|
|
5529
5539
|
schemaVersion: 1,
|
|
@@ -5557,17 +5567,17 @@ function gs(e) {
|
|
|
5557
5567
|
warnings: e.warnings ?? []
|
|
5558
5568
|
},
|
|
5559
5569
|
...e.attachments && e.attachments.length ? { attachments: e.attachments } : {},
|
|
5560
|
-
client: { tz: e.clientTz ??
|
|
5570
|
+
client: { tz: e.clientTz ?? Ei(), platform: "web" }
|
|
5561
5571
|
};
|
|
5562
5572
|
}
|
|
5563
|
-
function
|
|
5573
|
+
function Ei() {
|
|
5564
5574
|
try {
|
|
5565
5575
|
return Intl.DateTimeFormat().resolvedOptions().timeZone || "UTC";
|
|
5566
5576
|
} catch {
|
|
5567
5577
|
return "UTC";
|
|
5568
5578
|
}
|
|
5569
5579
|
}
|
|
5570
|
-
const He = ["save", "update", "get", "list", "delete", "upload", "uploadUrl", "rates", "settings"],
|
|
5580
|
+
const He = ["save", "update", "get", "list", "delete", "upload", "uploadUrl", "rates", "settings"], Mi = {
|
|
5571
5581
|
save: "POST",
|
|
5572
5582
|
update: "PUT",
|
|
5573
5583
|
get: "GET",
|
|
@@ -5577,7 +5587,7 @@ const He = ["save", "update", "get", "list", "delete", "upload", "uploadUrl", "r
|
|
|
5577
5587
|
uploadUrl: "GET",
|
|
5578
5588
|
rates: "GET",
|
|
5579
5589
|
settings: "GET"
|
|
5580
|
-
},
|
|
5590
|
+
}, ua = ["bearer", "apiKeyHeader", "basic", "custom"], $i = {
|
|
5581
5591
|
strategy: "multipart",
|
|
5582
5592
|
fieldName: "file",
|
|
5583
5593
|
maxBytes: 10 * 1024 * 1024,
|
|
@@ -5586,10 +5596,10 @@ const He = ["save", "update", "get", "list", "delete", "upload", "uploadUrl", "r
|
|
|
5586
5596
|
checksum: "none",
|
|
5587
5597
|
chunked: { enabled: !1, chunkBytes: 1024 * 1024 }
|
|
5588
5598
|
};
|
|
5589
|
-
function
|
|
5599
|
+
function da() {
|
|
5590
5600
|
const e = {};
|
|
5591
5601
|
for (const t of He)
|
|
5592
|
-
e[t] = { path: `/calculations${t === "save" || t === "list" ? "" : t === "get" || t === "update" || t === "delete" ? "/:id" : "/" + t}`, method:
|
|
5602
|
+
e[t] = { path: `/calculations${t === "save" || t === "list" ? "" : t === "get" || t === "update" || t === "delete" ? "/:id" : "/" + t}`, method: Mi[t], enabled: t === "save" || t === "list" };
|
|
5593
5603
|
return {
|
|
5594
5604
|
baseUrl: "https://api.example.com/v1",
|
|
5595
5605
|
auth: { strategy: "bearer", headerName: "Authorization" },
|
|
@@ -5597,17 +5607,17 @@ function ua() {
|
|
|
5597
5607
|
credentials: "same-origin",
|
|
5598
5608
|
retry: { attempts: 3, backoff: "exponential", baseDelayMs: 300, retryOn: [408, 429, 500, 502, 503, 504], respectRetryAfter: !0 },
|
|
5599
5609
|
endpoints: e,
|
|
5600
|
-
upload:
|
|
5610
|
+
upload: $i
|
|
5601
5611
|
};
|
|
5602
5612
|
}
|
|
5603
|
-
const
|
|
5613
|
+
const Ai = {
|
|
5604
5614
|
mode: "flat",
|
|
5605
5615
|
keyCase: "asIs",
|
|
5606
5616
|
dateFormat: "iso",
|
|
5607
5617
|
nullHandling: "omit",
|
|
5608
5618
|
numberEncoding: "string",
|
|
5609
5619
|
include: { inputs: !0, outputs: !0, schedule: !1, settingsSnapshot: !0, meta: !0 }
|
|
5610
|
-
},
|
|
5620
|
+
}, Di = [
|
|
5611
5621
|
{ key: "calculator", source: { kind: "context", path: "calculator" }, type: "string", required: !0, omitWhenEmpty: !1 },
|
|
5612
5622
|
{ key: "principal", source: { kind: "input", path: "principal" }, type: "number", required: !0, omitWhenEmpty: !1 },
|
|
5613
5623
|
{ key: "payment", source: { kind: "output", path: "payment" }, type: "number", required: !1, omitWhenEmpty: !1 },
|
|
@@ -5626,7 +5636,7 @@ function kn(e) {
|
|
|
5626
5636
|
n /= 1024, a++;
|
|
5627
5637
|
return `${n.toFixed(n < 10 ? 1 : 0)} ${t[a]}`;
|
|
5628
5638
|
}
|
|
5629
|
-
function
|
|
5639
|
+
function ma(e, t, n) {
|
|
5630
5640
|
switch (e) {
|
|
5631
5641
|
case "bearer":
|
|
5632
5642
|
return { Authorization: `Bearer ${n}` };
|
|
@@ -5644,9 +5654,9 @@ function da(e, t, n) {
|
|
|
5644
5654
|
function qe(e, t) {
|
|
5645
5655
|
return t ? /^https?:\/\//i.test(t) ? t : `${e.replace(/\/+$/, "")}/${t.replace(/^\/+/, "")}` : e;
|
|
5646
5656
|
}
|
|
5647
|
-
const
|
|
5648
|
-
function
|
|
5649
|
-
const { settings: n } = ue(), [a, r] = M("Connection"), [s, u] = M(
|
|
5657
|
+
const Li = ["Connection", "Endpoints", "Upload", "Payload", "Test", "cURL", "Queue"];
|
|
5658
|
+
function pa({ hostConfig: e, getToken: t } = {}) {
|
|
5659
|
+
const { settings: n } = ue(), [a, r] = M("Connection"), [s, u] = M(da), [m, d] = M(Ai), [i, c] = M(Di);
|
|
5650
5660
|
if (!n.features.integrationPanel)
|
|
5651
5661
|
return /* @__PURE__ */ o("section", { className: "card", "data-part": "integration-panel", children: /* @__PURE__ */ b("div", { className: "panel-head", children: [
|
|
5652
5662
|
/* @__PURE__ */ o("h2", { children: "Integration" }),
|
|
@@ -5668,12 +5678,12 @@ function ma({ hostConfig: e, getToken: t } = {}) {
|
|
|
5668
5678
|
/* @__PURE__ */ o("h2", { children: "Integration" }),
|
|
5669
5679
|
/* @__PURE__ */ o("p", { children: "Point the library at your backend without a code change. Nothing here stores a secret." })
|
|
5670
5680
|
] }),
|
|
5671
|
-
/* @__PURE__ */ o("div", { className: "tabs", role: "tablist", "aria-label": "Integration settings", children:
|
|
5681
|
+
/* @__PURE__ */ o("div", { className: "tabs", role: "tablist", "aria-label": "Integration settings", children: Li.map((f) => /* @__PURE__ */ o("button", { role: "tab", "aria-selected": a === f, onClick: () => r(f), children: f }, f)) }),
|
|
5672
5682
|
/* @__PURE__ */ b("div", { role: "tabpanel", "aria-label": a, children: [
|
|
5673
|
-
a === "Connection" && /* @__PURE__ */ o(
|
|
5674
|
-
a === "Endpoints" && /* @__PURE__ */ o(
|
|
5683
|
+
a === "Connection" && /* @__PURE__ */ o(Ui, { cfg: s, patch: p, hostLocked: l, getToken: t }),
|
|
5684
|
+
a === "Endpoints" && /* @__PURE__ */ o(Oi, { cfg: s, setCfg: u, locked: l("endpoints") }),
|
|
5675
5685
|
a === "Upload" && /* @__PURE__ */ o(
|
|
5676
|
-
|
|
5686
|
+
Bi,
|
|
5677
5687
|
{
|
|
5678
5688
|
upload: s.upload,
|
|
5679
5689
|
baseUrl: s.baseUrl,
|
|
@@ -5683,7 +5693,7 @@ function ma({ hostConfig: e, getToken: t } = {}) {
|
|
|
5683
5693
|
}
|
|
5684
5694
|
),
|
|
5685
5695
|
a === "Payload" && /* @__PURE__ */ o(
|
|
5686
|
-
|
|
5696
|
+
ji,
|
|
5687
5697
|
{
|
|
5688
5698
|
fields: i,
|
|
5689
5699
|
setFields: c,
|
|
@@ -5692,11 +5702,11 @@ function ma({ hostConfig: e, getToken: t } = {}) {
|
|
|
5692
5702
|
ctx: h
|
|
5693
5703
|
}
|
|
5694
5704
|
),
|
|
5695
|
-
a === "Test" && /* @__PURE__ */ o(
|
|
5696
|
-
a === "cURL" && /* @__PURE__ */ o(
|
|
5697
|
-
a === "Queue" && /* @__PURE__ */ o(
|
|
5705
|
+
a === "Test" && /* @__PURE__ */ o(Yi, { cfg: s, getToken: t }),
|
|
5706
|
+
a === "cURL" && /* @__PURE__ */ o(Ki, { cfg: s }),
|
|
5707
|
+
a === "Queue" && /* @__PURE__ */ o(Wi, { cfg: s, getToken: t })
|
|
5698
5708
|
] }),
|
|
5699
|
-
/* @__PURE__ */ o(
|
|
5709
|
+
/* @__PURE__ */ o(zi, { cfg: s, setCfg: u })
|
|
5700
5710
|
] });
|
|
5701
5711
|
}
|
|
5702
5712
|
function Fe({ on: e, children: t }) {
|
|
@@ -5747,13 +5757,13 @@ function le({
|
|
|
5747
5757
|
/* @__PURE__ */ o("div", { className: "input-wrap", children: /* @__PURE__ */ o("select", { value: t, onChange: (s) => a(s.target.value), "aria-label": e, children: r.map((s) => /* @__PURE__ */ o("option", { value: s.value, children: s.label }, s.value)) }) })
|
|
5748
5758
|
] });
|
|
5749
5759
|
}
|
|
5750
|
-
function
|
|
5760
|
+
function Ui({
|
|
5751
5761
|
cfg: e,
|
|
5752
5762
|
patch: t,
|
|
5753
5763
|
hostLocked: n,
|
|
5754
5764
|
getToken: a
|
|
5755
5765
|
}) {
|
|
5756
|
-
const r =
|
|
5766
|
+
const r = ua.includes(e.auth.strategy);
|
|
5757
5767
|
return /* @__PURE__ */ b("div", { className: "grid two", children: [
|
|
5758
5768
|
/* @__PURE__ */ o(Fe, { on: n("baseUrl"), children: /* @__PURE__ */ o(ne, { label: "Base URL", value: e.baseUrl, onChange: (s) => t({ baseUrl: s }), help: "Absolute origin + base path" }) }),
|
|
5759
5769
|
/* @__PURE__ */ o(
|
|
@@ -5806,7 +5816,7 @@ function Di({
|
|
|
5806
5816
|
)
|
|
5807
5817
|
] });
|
|
5808
5818
|
}
|
|
5809
|
-
function
|
|
5819
|
+
function Oi({ cfg: e, setCfg: t, locked: n }) {
|
|
5810
5820
|
const a = (r, s) => t((u) => ({ ...u, endpoints: { ...u.endpoints, [r]: { ...u.endpoints[r], ...s } } }));
|
|
5811
5821
|
return /* @__PURE__ */ o(Fe, { on: n, children: /* @__PURE__ */ o("div", { className: "int-table-wrap", children: /* @__PURE__ */ b("table", { className: "int-table", children: [
|
|
5812
5822
|
/* @__PURE__ */ o("thead", { children: /* @__PURE__ */ b("tr", { children: [
|
|
@@ -5829,10 +5839,10 @@ function Li({ cfg: e, setCfg: t, locked: n }) {
|
|
|
5829
5839
|
}) })
|
|
5830
5840
|
] }) }) });
|
|
5831
5841
|
}
|
|
5832
|
-
function
|
|
5842
|
+
function Bi({ upload: e, baseUrl: t, uploadUri: n, onChange: a, locked: r }) {
|
|
5833
5843
|
var m, d, i;
|
|
5834
5844
|
const s = (c) => a({ ...e, ...c }), u = X(
|
|
5835
|
-
() =>
|
|
5845
|
+
() => sa(e.filenameTemplate, { calculator: "loan.emi", kind: "pdf", inputsHash: Ue.inputsHash, filename: "x.pdf" }),
|
|
5836
5846
|
[e.filenameTemplate]
|
|
5837
5847
|
);
|
|
5838
5848
|
return /* @__PURE__ */ o(Fe, { on: r, children: /* @__PURE__ */ b("div", { className: "grid two", children: [
|
|
@@ -5884,14 +5894,14 @@ function Ui({ upload: e, baseUrl: t, uploadUri: n, onChange: a, locked: r }) {
|
|
|
5884
5894
|
] })
|
|
5885
5895
|
] }) });
|
|
5886
5896
|
}
|
|
5887
|
-
const
|
|
5888
|
-
function
|
|
5897
|
+
const _i = ["static", "input", "output", "setting", "context", "token", "callback"];
|
|
5898
|
+
function Hi(e) {
|
|
5889
5899
|
return e.kind === "static" ? String(e.value) : e.kind === "token" ? e.name : e.kind === "callback" ? "fn()" : e.path;
|
|
5890
5900
|
}
|
|
5891
|
-
function
|
|
5901
|
+
function qi(e, t) {
|
|
5892
5902
|
return e.kind === "static" ? { kind: "static", value: t } : e.kind === "token" ? { kind: "token", name: t } : e.kind === "callback" ? e : { kind: e.kind, path: t };
|
|
5893
5903
|
}
|
|
5894
|
-
function
|
|
5904
|
+
function Gi(e) {
|
|
5895
5905
|
switch (e) {
|
|
5896
5906
|
case "static":
|
|
5897
5907
|
return { kind: "static", value: "" };
|
|
@@ -5903,7 +5913,7 @@ function Hi(e) {
|
|
|
5903
5913
|
return { kind: e, path: "" };
|
|
5904
5914
|
}
|
|
5905
5915
|
}
|
|
5906
|
-
function
|
|
5916
|
+
function ji({
|
|
5907
5917
|
fields: e,
|
|
5908
5918
|
setFields: t,
|
|
5909
5919
|
envelope: n,
|
|
@@ -5912,7 +5922,7 @@ function qi({
|
|
|
5912
5922
|
}) {
|
|
5913
5923
|
const s = X(() => {
|
|
5914
5924
|
try {
|
|
5915
|
-
return JSON.stringify(
|
|
5925
|
+
return JSON.stringify(Ri(e, n, r), null, 2);
|
|
5916
5926
|
} catch (i) {
|
|
5917
5927
|
return `// ${i instanceof Error ? i.message : "preview failed"}`;
|
|
5918
5928
|
}
|
|
@@ -5953,13 +5963,13 @@ function qi({
|
|
|
5953
5963
|
] }) }),
|
|
5954
5964
|
/* @__PURE__ */ o("tbody", { children: e.map((i, c) => /* @__PURE__ */ b("tr", { children: [
|
|
5955
5965
|
/* @__PURE__ */ o("td", { children: /* @__PURE__ */ o("input", { value: i.key, onChange: (l) => u(c, { key: l.target.value }), "aria-label": "key", className: "int-cell-input" }) }),
|
|
5956
|
-
/* @__PURE__ */ o("td", { children: /* @__PURE__ */ o("select", { value: i.source.kind, onChange: (l) => u(c, { source:
|
|
5966
|
+
/* @__PURE__ */ o("td", { children: /* @__PURE__ */ o("select", { value: i.source.kind, onChange: (l) => u(c, { source: Gi(l.target.value) }), "aria-label": "source kind", children: _i.map((l) => /* @__PURE__ */ o("option", { children: l }, l)) }) }),
|
|
5957
5967
|
/* @__PURE__ */ o("td", { children: /* @__PURE__ */ o(
|
|
5958
5968
|
"input",
|
|
5959
5969
|
{
|
|
5960
|
-
value:
|
|
5970
|
+
value: Hi(i.source),
|
|
5961
5971
|
disabled: i.source.kind === "callback",
|
|
5962
|
-
onChange: (l) => u(c, { source:
|
|
5972
|
+
onChange: (l) => u(c, { source: qi(i.source, l.target.value) }),
|
|
5963
5973
|
"aria-label": "source value",
|
|
5964
5974
|
className: "int-cell-input"
|
|
5965
5975
|
}
|
|
@@ -5990,7 +6000,7 @@ function qi({
|
|
|
5990
6000
|
] })
|
|
5991
6001
|
] });
|
|
5992
6002
|
}
|
|
5993
|
-
function
|
|
6003
|
+
function Vi(e, t) {
|
|
5994
6004
|
const n = {};
|
|
5995
6005
|
for (const a of He) {
|
|
5996
6006
|
const r = e.endpoints[a];
|
|
@@ -6004,10 +6014,10 @@ function Gi(e, t) {
|
|
|
6004
6014
|
retry: e.retry,
|
|
6005
6015
|
upload: e.upload,
|
|
6006
6016
|
offlineQueue: { enabled: !0, storage: "memory", maxItems: 200, flushOn: "manual" },
|
|
6007
|
-
getAuth: t ? async () =>
|
|
6017
|
+
getAuth: t ? async () => ma(e.auth.strategy, e.auth.headerName, await t()) : void 0
|
|
6008
6018
|
};
|
|
6009
6019
|
}
|
|
6010
|
-
function
|
|
6020
|
+
function Yi({ cfg: e, getToken: t }) {
|
|
6011
6021
|
const [n, a] = M({ loading: !1 }), [r, s] = M("save");
|
|
6012
6022
|
return /* @__PURE__ */ b("div", { children: [
|
|
6013
6023
|
/* @__PURE__ */ b("div", { className: "grid two", children: [
|
|
@@ -6015,11 +6025,11 @@ function ji({ cfg: e, getToken: t }) {
|
|
|
6015
6025
|
/* @__PURE__ */ o("div", { className: "field", style: { display: "flex", alignItems: "flex-end" }, children: /* @__PURE__ */ o("button", { type: "button", className: "icon-btn", onClick: async () => {
|
|
6016
6026
|
a({ loading: !0 });
|
|
6017
6027
|
const m = e.endpoints[r], d = qe(e.baseUrl, m.path).replace(/:id\b/, "sample-id"), i = { "content-type": "application/json", "X-FinCalc-Test": "1" };
|
|
6018
|
-
t && Object.assign(i,
|
|
6028
|
+
t && Object.assign(i, ma(e.auth.strategy, e.auth.headerName, await t()));
|
|
6019
6029
|
const c = performance.now();
|
|
6020
6030
|
try {
|
|
6021
6031
|
const l = await fetch(d, { method: m.method, headers: i, credentials: e.credentials }), p = await l.text(), h = {};
|
|
6022
|
-
l.headers.forEach((f, y) => h[y] = f), a({ loading: !1, ok: l.ok, status: l.status, ms: Math.round(performance.now() - c), headers: h, body:
|
|
6032
|
+
l.headers.forEach((f, y) => h[y] = f), a({ loading: !1, ok: l.ok, status: l.status, ms: Math.round(performance.now() - c), headers: h, body: Ji(p), sent: { url: d, method: m.method, headers: $t(i) } });
|
|
6023
6033
|
} catch (l) {
|
|
6024
6034
|
a({ loading: !1, ok: !1, ms: Math.round(performance.now() - c), error: l instanceof Error ? l.message : "request failed", sent: { url: d, method: m.method, headers: $t(i) } });
|
|
6025
6035
|
}
|
|
@@ -6049,9 +6059,9 @@ ${JSON.stringify(n.sent.headers, null, 2)}` })
|
|
|
6049
6059
|
] })
|
|
6050
6060
|
] });
|
|
6051
6061
|
}
|
|
6052
|
-
function
|
|
6062
|
+
function Ki({ cfg: e }) {
|
|
6053
6063
|
const [t, n] = M(!1), [a, r] = M("save"), s = e.endpoints[a], u = qe(e.baseUrl, s.path).replace(/:id\b/, "sample-id"), m = { "content-type": "application/json" };
|
|
6054
|
-
|
|
6064
|
+
ua.includes(e.auth.strategy) && (m[e.auth.strategy === "apiKeyHeader" || e.auth.strategy === "custom" ? e.auth.headerName || "X-API-Key" : "Authorization"] = t ? "<token>" : "***");
|
|
6055
6065
|
const d = [`curl -X ${s.method} '${u}'`];
|
|
6056
6066
|
for (const [c, l] of Object.entries(m)) d.push(` -H '${c}: ${l}'`);
|
|
6057
6067
|
["POST", "PUT", "PATCH"].includes(s.method) && d.push(` -d '{"example":"body"}'`);
|
|
@@ -6072,8 +6082,8 @@ function Vi({ cfg: e }) {
|
|
|
6072
6082
|
}, children: "Copy" })
|
|
6073
6083
|
] });
|
|
6074
6084
|
}
|
|
6075
|
-
function
|
|
6076
|
-
const n = X(() =>
|
|
6085
|
+
function Wi({ cfg: e, getToken: t }) {
|
|
6086
|
+
const n = X(() => gi(Vi(e, t)), [e, t]), [a, r] = M(() => n.queue.list()), [s, u] = M(""), m = () => r(n.queue.list());
|
|
6077
6087
|
return /* @__PURE__ */ b("div", { children: [
|
|
6078
6088
|
/* @__PURE__ */ b("div", { className: "actions-row", style: { marginTop: 0 }, children: [
|
|
6079
6089
|
/* @__PURE__ */ o("button", { type: "button", className: "icon-btn", onClick: m, children: "Refresh" }),
|
|
@@ -6102,7 +6112,7 @@ function Yi({ cfg: e, getToken: t }) {
|
|
|
6102
6112
|
] }) })
|
|
6103
6113
|
] });
|
|
6104
6114
|
}
|
|
6105
|
-
function
|
|
6115
|
+
function zi({ cfg: e, setCfg: t }) {
|
|
6106
6116
|
const [n, a] = M(""), [r, s] = M("");
|
|
6107
6117
|
return /* @__PURE__ */ b("div", { className: "accordion", style: { marginTop: 20 }, children: [
|
|
6108
6118
|
/* @__PURE__ */ o("span", { className: "lbl", children: "Import / export config (JSON)" }),
|
|
@@ -6116,7 +6126,7 @@ function Ki({ cfg: e, setCfg: t }) {
|
|
|
6116
6126
|
const d = JSON.parse(n);
|
|
6117
6127
|
for (const i of ["token", "apiKey", "getAuth", "authorization"])
|
|
6118
6128
|
i in d && (delete d[i], s(`Refused to import "${i}" — the panel never persists a secret.`));
|
|
6119
|
-
t(() => ({ ...
|
|
6129
|
+
t(() => ({ ...da(), ...d })), r || s("Imported.");
|
|
6120
6130
|
} catch {
|
|
6121
6131
|
s("Invalid JSON.");
|
|
6122
6132
|
}
|
|
@@ -6125,16 +6135,16 @@ function Ki({ cfg: e, setCfg: t }) {
|
|
|
6125
6135
|
r && /* @__PURE__ */ o("div", { className: "int-note", children: r })
|
|
6126
6136
|
] });
|
|
6127
6137
|
}
|
|
6128
|
-
function
|
|
6138
|
+
function Ji(e) {
|
|
6129
6139
|
try {
|
|
6130
6140
|
return JSON.stringify(JSON.parse(e), null, 2);
|
|
6131
6141
|
} catch {
|
|
6132
6142
|
return e;
|
|
6133
6143
|
}
|
|
6134
6144
|
}
|
|
6135
|
-
const
|
|
6136
|
-
function
|
|
6137
|
-
const { settings: e, update: t, setRegion: n, reset: a, replace: r } = ue(), s = de(null), u = Sn(e).money(g(
|
|
6145
|
+
const Zi = "1234567.891";
|
|
6146
|
+
function Xi() {
|
|
6147
|
+
const { settings: e, update: t, setRegion: n, reset: a, replace: r } = ue(), s = de(null), u = Sn(e).money(g(Zi)), m = () => {
|
|
6138
6148
|
const i = new Blob([JSON.stringify(e, null, 2)], { type: "application/json" }), c = URL.createObjectURL(i), l = document.createElement("a");
|
|
6139
6149
|
l.href = c, l.download = "calcsuite-settings.json", l.click(), URL.revokeObjectURL(c);
|
|
6140
6150
|
}, d = (i) => {
|
|
@@ -6225,7 +6235,7 @@ function Ji() {
|
|
|
6225
6235
|
options: [["system", "System"], ["light", "Light"], ["dark", "Dark"], ["highContrast", "High contrast"]]
|
|
6226
6236
|
}
|
|
6227
6237
|
) }),
|
|
6228
|
-
/* @__PURE__ */ o(W, { label: "Accent colour", children: /* @__PURE__ */ o("div", { className: "swatches", children:
|
|
6238
|
+
/* @__PURE__ */ o(W, { label: "Accent colour", children: /* @__PURE__ */ o("div", { className: "swatches", children: Cn.map((i) => {
|
|
6229
6239
|
const c = e.ui.accent.toLowerCase() === i.main.toLowerCase();
|
|
6230
6240
|
return /* @__PURE__ */ o(
|
|
6231
6241
|
"button",
|
|
@@ -6246,7 +6256,7 @@ function Ji() {
|
|
|
6246
6256
|
{
|
|
6247
6257
|
value: e.ui.fontFamily,
|
|
6248
6258
|
onChange: (i) => t({ ui: { fontFamily: i } }),
|
|
6249
|
-
options:
|
|
6259
|
+
options: Pn.map((i) => [i.id, i.label])
|
|
6250
6260
|
}
|
|
6251
6261
|
) }),
|
|
6252
6262
|
/* @__PURE__ */ o(W, { label: "Density", children: /* @__PURE__ */ o(
|
|
@@ -6269,7 +6279,7 @@ function Ji() {
|
|
|
6269
6279
|
" — so exports (PDF/CSV/…) and saved calculations post directly to your own server. No secret is ever stored by the app."
|
|
6270
6280
|
] })
|
|
6271
6281
|
] }),
|
|
6272
|
-
e.features.integrationPanel && /* @__PURE__ */ o(
|
|
6282
|
+
e.features.integrationPanel && /* @__PURE__ */ o(pa, {}),
|
|
6273
6283
|
/* @__PURE__ */ b("div", { className: "actions-row", children: [
|
|
6274
6284
|
/* @__PURE__ */ o("button", { className: "icon-btn", onClick: m, children: "Export settings" }),
|
|
6275
6285
|
/* @__PURE__ */ o("button", { className: "icon-btn", onClick: () => {
|
|
@@ -6302,7 +6312,7 @@ function he({ value: e, onChange: t, options: n }) {
|
|
|
6302
6312
|
function Le({ on: e, onClick: t }) {
|
|
6303
6313
|
return /* @__PURE__ */ o("button", { type: "button", role: "switch", "aria-checked": e, className: `toggle ${e ? "on" : ""}`, onClick: t, children: /* @__PURE__ */ o("span", { className: "knob" }) });
|
|
6304
6314
|
}
|
|
6305
|
-
function
|
|
6315
|
+
function Qi({
|
|
6306
6316
|
items: e,
|
|
6307
6317
|
onRestore: t,
|
|
6308
6318
|
onClear: n
|
|
@@ -6331,7 +6341,7 @@ function wn(e, t) {
|
|
|
6331
6341
|
for (let s = 0; s < n.length && r < e.length; s++) n[s] === e[r] && r++;
|
|
6332
6342
|
return r === e.length ? 10 : -1;
|
|
6333
6343
|
}
|
|
6334
|
-
function
|
|
6344
|
+
function es({
|
|
6335
6345
|
calculators: e,
|
|
6336
6346
|
actions: t,
|
|
6337
6347
|
onPick: n,
|
|
@@ -6341,7 +6351,7 @@ function Xi({
|
|
|
6341
6351
|
Q(() => {
|
|
6342
6352
|
var l;
|
|
6343
6353
|
return (l = d.current) == null ? void 0 : l.focus();
|
|
6344
|
-
}, []), Q(() => (
|
|
6354
|
+
}, []), Q(() => (Pa(), () => Ta()), []);
|
|
6345
6355
|
const i = X(() => {
|
|
6346
6356
|
const l = e.map((y) => ({
|
|
6347
6357
|
key: `calc:${y.id}`,
|
|
@@ -6391,7 +6401,7 @@ function Xi({
|
|
|
6391
6401
|
] })
|
|
6392
6402
|
] }) });
|
|
6393
6403
|
}
|
|
6394
|
-
const
|
|
6404
|
+
const Ge = (e) => ({
|
|
6395
6405
|
width: e,
|
|
6396
6406
|
height: e,
|
|
6397
6407
|
viewBox: "0 0 24 24",
|
|
@@ -6402,31 +6412,44 @@ const dt = (e) => ({
|
|
|
6402
6412
|
strokeLinejoin: "round",
|
|
6403
6413
|
"aria-hidden": !0
|
|
6404
6414
|
});
|
|
6405
|
-
function
|
|
6406
|
-
return /* @__PURE__ */ b("svg", { ...
|
|
6415
|
+
function ts({ size: e = 17 }) {
|
|
6416
|
+
return /* @__PURE__ */ b("svg", { ...Ge(e), children: [
|
|
6407
6417
|
/* @__PURE__ */ o("circle", { cx: "12", cy: "12", r: "3" }),
|
|
6408
6418
|
/* @__PURE__ */ o("path", { d: "M19.4 15a1.65 1.65 0 0 0 .33 1.82l.06.06a2 2 0 1 1-2.83 2.83l-.06-.06a1.65 1.65 0 0 0-1.82-.33 1.65 1.65 0 0 0-1 1.51V21a2 2 0 0 1-4 0v-.09A1.65 1.65 0 0 0 9 19.4a1.65 1.65 0 0 0-1.82.33l-.06.06a2 2 0 1 1-2.83-2.83l.06-.06a1.65 1.65 0 0 0 .33-1.82 1.65 1.65 0 0 0-1.51-1H3a2 2 0 0 1 0-4h.09A1.65 1.65 0 0 0 4.6 9a1.65 1.65 0 0 0-.33-1.82l-.06-.06a2 2 0 1 1 2.83-2.83l.06.06a1.65 1.65 0 0 0 1.82.33H9a1.65 1.65 0 0 0 1-1.51V3a2 2 0 0 1 4 0v.09a1.65 1.65 0 0 0 1 1.51 1.65 1.65 0 0 0 1.82-.33l.06-.06a2 2 0 1 1 2.83 2.83l-.06.06a1.65 1.65 0 0 0-.33 1.82V9a1.65 1.65 0 0 0 1.51 1H21a2 2 0 0 1 0 4h-.09a1.65 1.65 0 0 0-1.51 1Z" })
|
|
6409
6419
|
] });
|
|
6410
6420
|
}
|
|
6411
|
-
function
|
|
6412
|
-
return /* @__PURE__ */ b("svg", { ...
|
|
6421
|
+
function ns({ size: e = 17 }) {
|
|
6422
|
+
return /* @__PURE__ */ b("svg", { ...Ge(e), children: [
|
|
6413
6423
|
/* @__PURE__ */ o("circle", { cx: "12", cy: "12", r: "4" }),
|
|
6414
6424
|
/* @__PURE__ */ o("path", { d: "M12 2v2M12 20v2M4.93 4.93l1.41 1.41M17.66 17.66l1.41 1.41M2 12h2M20 12h2M6.34 17.66l-1.41 1.41M19.07 4.93l-1.41 1.41" })
|
|
6415
6425
|
] });
|
|
6416
6426
|
}
|
|
6417
|
-
function
|
|
6418
|
-
return /* @__PURE__ */ o("svg", { ...
|
|
6427
|
+
function as({ size: e = 17 }) {
|
|
6428
|
+
return /* @__PURE__ */ o("svg", { ...Ge(e), children: /* @__PURE__ */ o("path", { d: "M12 3a6 6 0 0 0 9 9 9 9 0 1 1-9-9Z" }) });
|
|
6429
|
+
}
|
|
6430
|
+
function ha({ size: e = 17 }) {
|
|
6431
|
+
return /* @__PURE__ */ b("svg", { ...Ge(e), children: [
|
|
6432
|
+
/* @__PURE__ */ o("rect", { x: "4", y: "2", width: "16", height: "20", rx: "2" }),
|
|
6433
|
+
/* @__PURE__ */ o("line", { x1: "8", y1: "6", x2: "16", y2: "6" }),
|
|
6434
|
+
/* @__PURE__ */ o("line", { x1: "8", y1: "10", x2: "8", y2: "10" }),
|
|
6435
|
+
/* @__PURE__ */ o("line", { x1: "12", y1: "10", x2: "12", y2: "10" }),
|
|
6436
|
+
/* @__PURE__ */ o("line", { x1: "16", y1: "10", x2: "16", y2: "10" }),
|
|
6437
|
+
/* @__PURE__ */ o("line", { x1: "8", y1: "14", x2: "8", y2: "14" }),
|
|
6438
|
+
/* @__PURE__ */ o("line", { x1: "12", y1: "14", x2: "12", y2: "14" }),
|
|
6439
|
+
/* @__PURE__ */ o("line", { x1: "16", y1: "14", x2: "16", y2: "14" }),
|
|
6440
|
+
/* @__PURE__ */ o("line", { x1: "8", y1: "18", x2: "12", y2: "18" })
|
|
6441
|
+
] });
|
|
6419
6442
|
}
|
|
6420
|
-
function
|
|
6421
|
-
return /* @__PURE__ */ b("svg", { ...
|
|
6443
|
+
function rs({ size: e = 17 }) {
|
|
6444
|
+
return /* @__PURE__ */ b("svg", { ...Ge(e), children: [
|
|
6422
6445
|
/* @__PURE__ */ o("path", { d: "M3 3v5h5" }),
|
|
6423
6446
|
/* @__PURE__ */ o("path", { d: "M3.05 13A9 9 0 1 0 6 5.3L3 8" }),
|
|
6424
6447
|
/* @__PURE__ */ o("path", { d: "M12 7v5l4 2" })
|
|
6425
6448
|
] });
|
|
6426
6449
|
}
|
|
6427
|
-
const
|
|
6428
|
-
function
|
|
6429
|
-
const { settings: t, setRegion: n, update: a, resolvedTheme: r } = ue(), s = t.region, u = X(() =>
|
|
6450
|
+
const os = { "loan.emi": Jn, scientific: Xn, currency: oa };
|
|
6451
|
+
function is({ onClose: e }) {
|
|
6452
|
+
const { settings: t, setRegion: n, update: a, resolvedTheme: r } = ue(), s = t.region, u = X(() => Xr(s), [s]), [m, d] = M("loan.emi"), [i, c] = M("calc"), [l, p] = M(void 0), [h, f] = M(!1), { items: y, clear: w } = Uo();
|
|
6430
6453
|
Q(() => {
|
|
6431
6454
|
const x = () => {
|
|
6432
6455
|
const T = new URLSearchParams(location.hash.replace(/^#/, "") || location.search), $ = T.get("fincalc");
|
|
@@ -6469,8 +6492,11 @@ function rs({ onClose: e }) {
|
|
|
6469
6492
|
return /* @__PURE__ */ b("div", { className: "fc-shell", onKeyDown: k, children: [
|
|
6470
6493
|
/* @__PURE__ */ b("header", { className: "fc-topbar", children: [
|
|
6471
6494
|
/* @__PURE__ */ b("div", { className: "brand fc-brand", children: [
|
|
6472
|
-
/* @__PURE__ */ o("
|
|
6473
|
-
/* @__PURE__ */
|
|
6495
|
+
/* @__PURE__ */ o("span", { className: "fc-brand-mark", "aria-hidden": "true", children: /* @__PURE__ */ o(ha, { size: 22 }) }),
|
|
6496
|
+
/* @__PURE__ */ b("div", { className: "fc-brand-text", children: [
|
|
6497
|
+
/* @__PURE__ */ o("strong", { children: "CalcSuite" }),
|
|
6498
|
+
/* @__PURE__ */ o("a", { className: "fc-brand-sub", href: "https://acecbm.com", target: "_blank", rel: "noopener noreferrer", children: "an AceCBM product ↗" })
|
|
6499
|
+
] })
|
|
6474
6500
|
] }),
|
|
6475
6501
|
/* @__PURE__ */ b("div", { className: "fc-top-actions", children: [
|
|
6476
6502
|
/* @__PURE__ */ o("button", { className: "icon-btn", onClick: () => f(!0), "aria-label": "Search", children: "⌘K Search" }),
|
|
@@ -6478,17 +6504,17 @@ function rs({ onClose: e }) {
|
|
|
6478
6504
|
/* @__PURE__ */ o("button", { "aria-pressed": s === "IN", onClick: () => n("IN"), children: "🇮🇳" }),
|
|
6479
6505
|
/* @__PURE__ */ o("button", { "aria-pressed": s === "US", onClick: () => n("US"), children: "🇺🇸" })
|
|
6480
6506
|
] }),
|
|
6481
|
-
/* @__PURE__ */ o("button", { className: "icon-btn icon-only", onClick: () => a({ ui: { theme: r === "dark" ? "light" : "dark" } }), "aria-label": r === "dark" ? "Switch to light mode" : "Switch to dark mode", children: r === "dark" ? /* @__PURE__ */ o(
|
|
6507
|
+
/* @__PURE__ */ o("button", { className: "icon-btn icon-only", onClick: () => a({ ui: { theme: r === "dark" ? "light" : "dark" } }), "aria-label": r === "dark" ? "Switch to light mode" : "Switch to dark mode", children: r === "dark" ? /* @__PURE__ */ o(ns, {}) : /* @__PURE__ */ o(as, {}) }),
|
|
6482
6508
|
/* @__PURE__ */ b("button", { className: "icon-btn", "aria-label": "History", onClick: () => c("history"), children: [
|
|
6483
|
-
/* @__PURE__ */ o(
|
|
6509
|
+
/* @__PURE__ */ o(rs, {}),
|
|
6484
6510
|
" History"
|
|
6485
6511
|
] }),
|
|
6486
|
-
/* @__PURE__ */ o("button", { className: "icon-btn icon-only", "aria-label": "Settings", onClick: () => c("settings"), children: /* @__PURE__ */ o(
|
|
6512
|
+
/* @__PURE__ */ o("button", { className: "icon-btn icon-only", "aria-label": "Settings", onClick: () => c("settings"), children: /* @__PURE__ */ o(ts, {}) }),
|
|
6487
6513
|
e && /* @__PURE__ */ o("button", { className: "icon-btn icon-only", "aria-label": "Close", onClick: e, children: "✕" })
|
|
6488
6514
|
] })
|
|
6489
6515
|
] }),
|
|
6490
6516
|
/* @__PURE__ */ b("div", { className: "fc-body", children: [
|
|
6491
|
-
/* @__PURE__ */ o("nav", { className: "fc-rail", "aria-label": "Calculators", children:
|
|
6517
|
+
/* @__PURE__ */ o("nav", { className: "fc-rail", "aria-label": "Calculators", children: Qr.map((x) => {
|
|
6492
6518
|
const T = u.filter(($) => $.group === x.id);
|
|
6493
6519
|
return T.length === 0 ? null : /* @__PURE__ */ b("div", { className: "rail-group", children: [
|
|
6494
6520
|
/* @__PURE__ */ o("div", { className: "rail-group-label", children: x.label }),
|
|
@@ -6504,24 +6530,24 @@ function rs({ onClose: e }) {
|
|
|
6504
6530
|
] }, x.id);
|
|
6505
6531
|
}) }),
|
|
6506
6532
|
/* @__PURE__ */ o("main", { className: "fc-main", children: /* @__PURE__ */ b("div", { className: "fc-anim-in", children: [
|
|
6507
|
-
i === "settings" && /* @__PURE__ */ o(
|
|
6508
|
-
i === "history" && /* @__PURE__ */ o(
|
|
6509
|
-
i === "integration" && /* @__PURE__ */ o(
|
|
6533
|
+
i === "settings" && /* @__PURE__ */ o(Xi, {}),
|
|
6534
|
+
i === "history" && /* @__PURE__ */ o(Qi, { items: y, onRestore: P, onClear: w }),
|
|
6535
|
+
i === "integration" && /* @__PURE__ */ o(pa, {}),
|
|
6510
6536
|
i === "calc" && /* @__PURE__ */ o(
|
|
6511
|
-
|
|
6537
|
+
di,
|
|
6512
6538
|
{
|
|
6513
6539
|
def: F,
|
|
6514
6540
|
seed: l,
|
|
6515
|
-
customRegistry:
|
|
6541
|
+
customRegistry: os,
|
|
6516
6542
|
actions: (x, T) => x ? /* @__PURE__ */ b(re, { children: [
|
|
6517
6543
|
/* @__PURE__ */ o(
|
|
6518
|
-
|
|
6544
|
+
zn,
|
|
6519
6545
|
{
|
|
6520
6546
|
item: { id: F.id, title: `${F.title} — ${x.primary.value}`, primary: x.primary.value, values: T }
|
|
6521
6547
|
}
|
|
6522
6548
|
),
|
|
6523
6549
|
/* @__PURE__ */ o(
|
|
6524
|
-
|
|
6550
|
+
Vn,
|
|
6525
6551
|
{
|
|
6526
6552
|
payload: {
|
|
6527
6553
|
calculatorId: F.id,
|
|
@@ -6538,37 +6564,11 @@ function rs({ onClose: e }) {
|
|
|
6538
6564
|
)
|
|
6539
6565
|
] }, i === "calc" ? `calc:${F.id}` : i) })
|
|
6540
6566
|
] }),
|
|
6541
|
-
h && /* @__PURE__ */ o(
|
|
6567
|
+
h && /* @__PURE__ */ o(es, { calculators: u, actions: N, onPick: S, onClose: () => f(!1) })
|
|
6542
6568
|
] });
|
|
6543
6569
|
}
|
|
6544
|
-
|
|
6545
|
-
|
|
6546
|
-
"svg",
|
|
6547
|
-
{
|
|
6548
|
-
width: e,
|
|
6549
|
-
height: e,
|
|
6550
|
-
viewBox: "0 0 24 24",
|
|
6551
|
-
fill: "none",
|
|
6552
|
-
stroke: "currentColor",
|
|
6553
|
-
strokeWidth: 2,
|
|
6554
|
-
strokeLinecap: "round",
|
|
6555
|
-
strokeLinejoin: "round",
|
|
6556
|
-
"aria-hidden": "true",
|
|
6557
|
-
children: [
|
|
6558
|
-
/* @__PURE__ */ o("rect", { x: "4", y: "2", width: "16", height: "20", rx: "2" }),
|
|
6559
|
-
/* @__PURE__ */ o("line", { x1: "8", y1: "6", x2: "16", y2: "6" }),
|
|
6560
|
-
/* @__PURE__ */ o("line", { x1: "8", y1: "10", x2: "8", y2: "10" }),
|
|
6561
|
-
/* @__PURE__ */ o("line", { x1: "12", y1: "10", x2: "12", y2: "10" }),
|
|
6562
|
-
/* @__PURE__ */ o("line", { x1: "16", y1: "10", x2: "16", y2: "10" }),
|
|
6563
|
-
/* @__PURE__ */ o("line", { x1: "8", y1: "14", x2: "8", y2: "14" }),
|
|
6564
|
-
/* @__PURE__ */ o("line", { x1: "12", y1: "14", x2: "12", y2: "14" }),
|
|
6565
|
-
/* @__PURE__ */ o("line", { x1: "16", y1: "14", x2: "16", y2: "14" }),
|
|
6566
|
-
/* @__PURE__ */ o("line", { x1: "8", y1: "18", x2: "12", y2: "18" })
|
|
6567
|
-
]
|
|
6568
|
-
}
|
|
6569
|
-
);
|
|
6570
|
-
}
|
|
6571
|
-
function vs({
|
|
6570
|
+
const Nn = ({ size: e = 22 }) => /* @__PURE__ */ o(ha, { size: e });
|
|
6571
|
+
function ws({
|
|
6572
6572
|
variant: e = "fab",
|
|
6573
6573
|
position: t = "bottom-right",
|
|
6574
6574
|
hotkey: n = "mod+shift+k",
|
|
@@ -6605,12 +6605,12 @@ function vs({
|
|
|
6605
6605
|
/* @__PURE__ */ o("span", { "aria-hidden": !0, style: { marginRight: 6, display: "inline-flex", alignItems: "center" }, children: m ?? /* @__PURE__ */ o(Nn, { size: 16 }) }),
|
|
6606
6606
|
u
|
|
6607
6607
|
] }),
|
|
6608
|
-
/* @__PURE__ */ o(
|
|
6608
|
+
/* @__PURE__ */ o(Ra, { open: k, onClose: F.close, title: h, size: p, children: /* @__PURE__ */ o(is, { onClose: F.close }) })
|
|
6609
6609
|
] });
|
|
6610
6610
|
}
|
|
6611
|
-
const
|
|
6612
|
-
function
|
|
6613
|
-
const n = t.ttlMs ??
|
|
6611
|
+
const ss = 60 * 60 * 1e3, Nt = (e, t) => `${e}|${[...t].sort().join(",")}`;
|
|
6612
|
+
function Ns(e, t = {}) {
|
|
6613
|
+
const n = t.ttlMs ?? ss, a = t.now ?? Date.now, r = /* @__PURE__ */ new Map();
|
|
6614
6614
|
let s = null;
|
|
6615
6615
|
function u(i) {
|
|
6616
6616
|
var l;
|
|
@@ -6656,71 +6656,71 @@ function ks(e, t = {}) {
|
|
|
6656
6656
|
clear: () => r.clear()
|
|
6657
6657
|
};
|
|
6658
6658
|
}
|
|
6659
|
-
const
|
|
6659
|
+
const xs = { solve: Ie, REGIONS: me };
|
|
6660
6660
|
export {
|
|
6661
|
-
|
|
6662
|
-
|
|
6663
|
-
|
|
6664
|
-
|
|
6661
|
+
di as CalculatorPanel,
|
|
6662
|
+
lo as Chart,
|
|
6663
|
+
es as CommandPalette,
|
|
6664
|
+
oa as CurrencyConverter,
|
|
6665
6665
|
g as D,
|
|
6666
|
-
|
|
6667
|
-
|
|
6666
|
+
vs as DEFAULT_ENVELOPE,
|
|
6667
|
+
Qe as DEFAULT_SETTINGS,
|
|
6668
6668
|
H as Decimal,
|
|
6669
|
-
|
|
6670
|
-
|
|
6671
|
-
|
|
6672
|
-
|
|
6673
|
-
|
|
6669
|
+
Ra as Dialog,
|
|
6670
|
+
co as EXPORT_FORMATS,
|
|
6671
|
+
Vn as ExportMenu,
|
|
6672
|
+
to as Field,
|
|
6673
|
+
Ra as FinCalcDialog,
|
|
6674
6674
|
se as FinCalcError,
|
|
6675
|
-
|
|
6676
|
-
|
|
6677
|
-
|
|
6678
|
-
|
|
6679
|
-
|
|
6680
|
-
|
|
6681
|
-
|
|
6682
|
-
|
|
6683
|
-
|
|
6684
|
-
|
|
6685
|
-
|
|
6686
|
-
|
|
6687
|
-
|
|
6688
|
-
|
|
6689
|
-
|
|
6690
|
-
|
|
6691
|
-
|
|
6675
|
+
ws as FinCalcLauncher,
|
|
6676
|
+
fs as FinCalcProvider,
|
|
6677
|
+
is as FinCalcRoot,
|
|
6678
|
+
Qr as GROUPS,
|
|
6679
|
+
Qi as HistoryPanel,
|
|
6680
|
+
pa as IntegrationPanel,
|
|
6681
|
+
ws as Launcher,
|
|
6682
|
+
Jn as LoanEmiPanel,
|
|
6683
|
+
ka as POLICY_DEFAULT,
|
|
6684
|
+
ro as ResultCard,
|
|
6685
|
+
zn as SaveButton,
|
|
6686
|
+
so as ScheduleTable,
|
|
6687
|
+
Xn as SciCalculator,
|
|
6688
|
+
Xi as SettingsPanel,
|
|
6689
|
+
fs as SettingsProvider,
|
|
6690
|
+
is as Shell,
|
|
6691
|
+
Un as allCalculators,
|
|
6692
6692
|
ye as boolval,
|
|
6693
|
-
|
|
6694
|
-
|
|
6695
|
-
|
|
6693
|
+
sa as buildFilename,
|
|
6694
|
+
Ri as buildPayload,
|
|
6695
|
+
ks as buildSavePayload,
|
|
6696
6696
|
Rt as calculatorById,
|
|
6697
|
-
|
|
6698
|
-
|
|
6699
|
-
|
|
6700
|
-
|
|
6701
|
-
|
|
6702
|
-
|
|
6697
|
+
Xr as calculatorsForRegion,
|
|
6698
|
+
Lo as clearHistory,
|
|
6699
|
+
Mo as createExporter,
|
|
6700
|
+
Ns as createFxCache,
|
|
6701
|
+
gi as createTransport,
|
|
6702
|
+
gs as currency,
|
|
6703
6703
|
D as dmoney,
|
|
6704
|
-
|
|
6704
|
+
ms as eq,
|
|
6705
6705
|
on as evalExpression,
|
|
6706
|
-
|
|
6707
|
-
|
|
6708
|
-
|
|
6709
|
-
|
|
6706
|
+
ni as evaluateExpression,
|
|
6707
|
+
ii as fetchLiveRate,
|
|
6708
|
+
ys as finance,
|
|
6709
|
+
ps as gt,
|
|
6710
6710
|
ce as isZeroish,
|
|
6711
|
-
|
|
6712
|
-
|
|
6711
|
+
xs as loan,
|
|
6712
|
+
hs as lt,
|
|
6713
6713
|
Sn as makeFormatter,
|
|
6714
6714
|
v as metric,
|
|
6715
6715
|
C as numval,
|
|
6716
|
-
|
|
6716
|
+
Jo as parseExpression,
|
|
6717
6717
|
xt as regionDefaults,
|
|
6718
|
-
|
|
6719
|
-
|
|
6720
|
-
|
|
6718
|
+
bs as registerCalculator,
|
|
6719
|
+
yi as sanitizeFilename,
|
|
6720
|
+
Wn as saveHistory,
|
|
6721
6721
|
Ie as solveLoan,
|
|
6722
6722
|
_ as strval,
|
|
6723
6723
|
ue as useFinCalc,
|
|
6724
|
-
|
|
6724
|
+
Uo as useHistory,
|
|
6725
6725
|
ue as useSettings
|
|
6726
6726
|
};
|