calcsuite-react 1.0.0 → 1.1.1

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/dist/calcsuite.js CHANGED
@@ -1,10 +1,10 @@
1
- var da = Object.defineProperty;
2
- var ma = (e, t, n) => t in e ? da(e, t, { enumerable: !0, configurable: !0, writable: !0, value: n }) : e[t] = n;
3
- var ge = (e, t, n) => ma(e, typeof t != "symbol" ? t + "" : t, n);
1
+ var ma = Object.defineProperty;
2
+ var pa = (e, t, n) => t in e ? ma(e, t, { enumerable: !0, configurable: !0, writable: !0, value: n }) : e[t] = n;
3
+ var ge = (e, t, n) => pa(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 ne, useContext as pa, createContext as ha, useRef as de, useEffect as X, Fragment as xn, useSyncExternalStore as fa } from "react";
6
- import ut from "decimal.js";
7
- const ya = {
5
+ import { useState as M, useCallback as ke, useMemo as ne, useContext as ha, createContext as fa, useRef as de, useEffect as X, Fragment as xn, useSyncExternalStore as ya } from "react";
6
+ import dt from "decimal.js";
7
+ const ba = {
8
8
  money: 2,
9
9
  rate: 6,
10
10
  period: 4,
@@ -13,7 +13,7 @@ const ya = {
13
13
  instalment: "none",
14
14
  residualAbsorption: "last"
15
15
  }, qt = {
16
- rounding: ya,
16
+ rounding: ba,
17
17
  ui: {
18
18
  theme: "system",
19
19
  accent: "#078DEE",
@@ -29,7 +29,7 @@ const ya = {
29
29
  persistence: { driver: "localStorage", namespace: "calcsuite", historyLimit: 100 },
30
30
  features: { integrationPanel: !1, beta: !1 }
31
31
  };
32
- function Nt(e) {
32
+ function xt(e) {
33
33
  return e === "US" ? {
34
34
  ...qt,
35
35
  region: "US",
@@ -68,13 +68,13 @@ function Nt(e) {
68
68
  defaults: { tenureUnit: "both", rateType: "floating", maxRatePercent: 50, sipReturnPercent: "12", inflationPercent: "6" }
69
69
  };
70
70
  }
71
- const Ze = Nt("IN"), H = ut.clone({
71
+ const Ze = xt("IN"), H = dt.clone({
72
72
  precision: 40,
73
- rounding: ut.ROUND_HALF_UP,
73
+ rounding: dt.ROUND_HALF_UP,
74
74
  toExpPos: 60,
75
75
  toExpNeg: -60,
76
- modulo: ut.ROUND_DOWN
77
- }), g = (e) => new H(e), cs = (e, t) => g(e).eq(t), us = (e, t) => g(e).gt(t), ds = (e, t) => g(e).lt(t), ce = (e, t = "1e-9") => e.abs().lt(t), ba = {
76
+ modulo: dt.ROUND_DOWN
77
+ }), g = (e) => new H(e), cs = (e, t) => g(e).eq(t), us = (e, t) => g(e).gt(t), ds = (e, t) => g(e).lt(t), ce = (e, t = "1e-9") => e.abs().lt(t), ga = {
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 Ze = Nt("IN"), H = ut.clone({
83
83
  CEIL: H.ROUND_CEIL,
84
84
  FLOOR: H.ROUND_FLOOR
85
85
  };
86
- function ga(e) {
86
+ function va(e) {
87
87
  switch (e.numberFormat.grouping) {
88
88
  case "indian":
89
89
  return "en-IN";
@@ -98,7 +98,7 @@ function ga(e) {
98
98
  }
99
99
  }
100
100
  function Sn(e) {
101
- const t = ba[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(ga(e), {
101
+ const t = ga[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(va(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) => {
@@ -122,67 +122,71 @@ function Sn(e) {
122
122
  };
123
123
  return { settings: e, money: m, moneyParts: d, num: i, pct: (l, p = e.numberFormat.percentPlaces) => `${i(l, p)}%`, compact: u, round: n };
124
124
  }
125
- function dt(e) {
125
+ function mt(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 Cn = ha(null), Pn = "calcsuite:settings";
130
- function $t(e, t) {
129
+ const Cn = fa(null), Pn = "calcsuite:settings";
130
+ function Xe(e, t) {
131
131
  if (t == null) return e;
132
132
  const n = Array.isArray(e) ? [...e] : { ...e };
133
133
  for (const a of Object.keys(t)) {
134
134
  const r = t[a], s = e[a];
135
- n[a] = r && typeof r == "object" && !Array.isArray(r) && s && typeof s == "object" ? $t(s, r) : r;
135
+ n[a] = r && typeof r == "object" && !Array.isArray(r) && s && typeof s == "object" ? Xe(s, r) : r;
136
136
  }
137
137
  return n;
138
138
  }
139
- function va() {
139
+ function ka(e) {
140
+ const t = e ? Xe(Ze, e) : Ze;
140
141
  try {
141
- const e = localStorage.getItem(Pn);
142
- if (e) return $t(Ze, JSON.parse(e));
142
+ const n = localStorage.getItem(Pn);
143
+ if (n) return Xe(t, JSON.parse(n));
143
144
  } catch {
144
145
  }
145
- return Ze;
146
+ return t;
146
147
  }
147
- function mt(e) {
148
+ function pt(e) {
148
149
  try {
149
150
  e.persistence.driver === "localStorage" && localStorage.setItem(Pn, JSON.stringify(e));
150
151
  } catch {
151
152
  }
152
153
  }
153
- function ms({ children: e }) {
154
- const [t, n] = M(va), a = ke((l) => {
155
- n(l), mt(l);
156
- }, []), r = ke((l) => n((p) => {
157
- const h = $t(p, l);
158
- return mt(h), h;
159
- }), []), s = ke((l) => {
160
- n((p) => {
161
- const f = { ...Nt(l), ui: p.ui, compliance: p.compliance, persistence: p.persistence, features: p.features };
162
- return mt(f), f;
154
+ function ms({
155
+ children: e,
156
+ settings: t
157
+ }) {
158
+ const [n, a] = M(() => ka(t)), r = ke((p) => {
159
+ a(p), pt(p);
160
+ }, []), s = ke((p) => a((h) => {
161
+ const f = Xe(h, p);
162
+ return pt(f), f;
163
+ }), []), u = ke((p) => {
164
+ a((h) => {
165
+ const y = { ...xt(p), ui: h.ui, compliance: h.compliance, persistence: h.persistence, features: h.features };
166
+ return pt(y), y;
163
167
  });
164
- }, []), u = ke(() => a(Nt(t.region)), [a, t.region]), m = ke((l) => a(l), [a]), d = ne(() => Sn(t), [t]), i = ne(() => {
165
- var p;
166
- const l = t.ui.theme;
167
- return l === "system" ? (p = window.matchMedia) != null && p.call(window, "(prefers-color-scheme: dark)").matches ? "dark" : "light" : l;
168
- }, [t.ui.theme]), c = ne(
169
- () => ({ settings: t, fmt: d, update: r, setRegion: s, reset: u, replace: m, resolvedTheme: i }),
170
- [t, d, r, s, u, m, i]
168
+ }, []), m = ke(() => r(xt(n.region)), [r, n.region]), d = ke((p) => r(p), [r]), i = ne(() => Sn(n), [n]), c = ne(() => {
169
+ var h;
170
+ const p = n.ui.theme;
171
+ return p === "system" ? (h = window.matchMedia) != null && h.call(window, "(prefers-color-scheme: dark)").matches ? "dark" : "light" : p;
172
+ }, [n.ui.theme]), l = ne(
173
+ () => ({ settings: n, fmt: i, update: s, setRegion: u, reset: m, replace: d, resolvedTheme: c }),
174
+ [n, i, s, u, m, d, c]
171
175
  );
172
- return /* @__PURE__ */ o(Cn.Provider, { value: c, children: e });
176
+ return /* @__PURE__ */ o(Cn.Provider, { value: l, children: e });
173
177
  }
174
178
  function ue() {
175
- const e = pa(Cn);
179
+ const e = ha(Cn);
176
180
  if (!e) throw new Error("useSettings must be used within SettingsProvider");
177
181
  return e;
178
182
  }
179
- let Xe = 0;
180
- const ka = () => {
181
- Xe += 1;
182
- }, wa = () => {
183
- Xe = Math.max(0, Xe - 1);
184
- }, Na = () => Xe > 0, xa = 'a[href],button:not([disabled]),textarea:not([disabled]),input:not([disabled]),select:not([disabled]),[tabindex]:not([tabindex="-1"])';
185
- function Sa({
183
+ let Qe = 0;
184
+ const wa = () => {
185
+ Qe += 1;
186
+ }, Na = () => {
187
+ Qe = Math.max(0, Qe - 1);
188
+ }, xa = () => Qe > 0, Sa = 'a[href],button:not([disabled]),textarea:not([disabled]),input:not([disabled]),select:not([disabled]),[tabindex]:not([tabindex="-1"])';
189
+ function Ca({
186
190
  open: e,
187
191
  onClose: t,
188
192
  children: n,
@@ -191,7 +195,7 @@ function Sa({
191
195
  }) {
192
196
  const s = de(null), u = de(null), m = ke(() => {
193
197
  const h = s.current;
194
- return h ? Array.from(h.querySelectorAll(xa)).filter(
198
+ return h ? Array.from(h.querySelectorAll(Sa)).filter(
195
199
  (f) => !f.hasAttribute("disabled") && f.getAttribute("aria-hidden") !== "true"
196
200
  ) : [];
197
201
  }, []), [d, i] = M(e), [c, l] = M(!1);
@@ -215,7 +219,7 @@ function Sa({
215
219
  document.body.style.overflow = "hidden";
216
220
  const w = (k) => {
217
221
  if (k.key === "Escape") {
218
- if (Na()) return;
222
+ if (xa()) return;
219
223
  k.preventDefault(), k.stopImmediatePropagation(), t();
220
224
  return;
221
225
  }
@@ -261,7 +265,7 @@ function be(e, t, n, a = !1) {
261
265
  let m = s.times(u.minus(1)).div(r);
262
266
  return a && (m = m.times(r.plus(1))), m;
263
267
  }
264
- function Qe(e, t, n) {
268
+ function et(e, t, n) {
265
269
  return g(e).times(g(t).plus(1).pow(n));
266
270
  }
267
271
  function Tn(e, t, n, a = !1) {
@@ -271,7 +275,7 @@ function Tn(e, t, n, a = !1) {
271
275
  let m = s.times(g(1).minus(u.pow(-1))).div(r);
272
276
  return a && (m = m.times(r.plus(1))), m;
273
277
  }
274
- function Ca(e, t, n) {
278
+ function Pa(e, t, n) {
275
279
  return g(e).div(g(t).plus(1).pow(n));
276
280
  }
277
281
  function we(e, t, n, a = 0, r = !1) {
@@ -281,11 +285,11 @@ function we(e, t, n, a = 0, r = !1) {
281
285
  let m = g(e).times(u).plus(a).times(s).div(u.minus(1));
282
286
  return r && (m = m.div(s.plus(1))), m;
283
287
  }
284
- function Pa(e, t, n) {
288
+ function Ta(e, t, n) {
285
289
  const a = g(n), r = g(e), s = g(t);
286
290
  return ce(a) ? r.div(s) : H.ln(s.div(s.minus(r.times(a)))).div(H.ln(a.plus(1)));
287
291
  }
288
- function at(e, t = -0.9999, n = 100, a = 200) {
292
+ function rt(e, t = -0.9999, n = 100, a = 200) {
289
293
  let r = g(t), s = g(n), u = e(r), m = e(s);
290
294
  if (u.times(m).gt(0)) return null;
291
295
  for (let d = 0; d < a; d++) {
@@ -303,40 +307,40 @@ function At(e, t) {
303
307
  return a;
304
308
  }
305
309
  function Fn(e) {
306
- return at((t) => At(t, e));
310
+ return rt((t) => At(t, e));
307
311
  }
308
- const Ta = (e, t) => (Date.parse(t) - Date.parse(e)) / 864e5;
312
+ const Fa = (e, t) => (Date.parse(t) - Date.parse(e)) / 864e5;
309
313
  function In(e, t) {
310
314
  const n = g(e), a = t[0].date;
311
315
  let r = g(0);
312
316
  for (const s of t) {
313
- const u = g(Ta(a, s.date)).div(365);
317
+ const u = g(Fa(a, s.date)).div(365);
314
318
  r = r.plus(g(s.amount).div(n.plus(1).pow(u)));
315
319
  }
316
320
  return r;
317
321
  }
318
- function En(e) {
322
+ function Rn(e) {
319
323
  if (e.length < 2) return null;
320
324
  const t = [...e].sort((n, a) => Date.parse(n.date) - Date.parse(a.date));
321
- return at((n) => In(n, t), -0.9999, 100);
325
+ return rt((n) => In(n, t), -0.9999, 100);
322
326
  }
323
- function rt(e, t, n) {
327
+ function ot(e, t, n) {
324
328
  return g(t).div(e).pow(g(1).div(n)).minus(1);
325
329
  }
326
330
  const ps = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
327
331
  __proto__: null,
328
- bisectRate: at,
329
- cagr: rt,
332
+ bisectRate: rt,
333
+ cagr: ot,
330
334
  fvAnnuity: be,
331
- fvLump: Qe,
335
+ fvLump: et,
332
336
  irr: Fn,
333
- nper: Pa,
337
+ nper: Ta,
334
338
  npv: At,
335
339
  periodic: J,
336
340
  pmt: we,
337
341
  pvAnnuity: Tn,
338
- pvLump: Ca,
339
- xirr: En,
342
+ pvLump: Pa,
343
+ xirr: Rn,
340
344
  xnpv: In
341
345
  }, Symbol.toStringTag, { value: "Module" })), me = {
342
346
  IN: {
@@ -374,13 +378,13 @@ class se extends Error {
374
378
  this.name = "FinCalcError", this.code = n, this.field = r;
375
379
  }
376
380
  }
377
- const Fa = 2, ee = (e) => e.toDecimalPlaces(Fa, H.ROUND_HALF_UP), xt = (e) => e.div(100).div(12);
378
- function St(e, t, n) {
381
+ const Ia = 2, ee = (e) => e.toDecimalPlaces(Ia, H.ROUND_HALF_UP), St = (e) => e.div(100).div(12);
382
+ function Ct(e, t, n) {
379
383
  if (ce(t)) return e.div(n);
380
384
  const a = t.plus(1).pow(n);
381
385
  return e.times(t).times(a).div(a.minus(1));
382
386
  }
383
- function Ia(e, t, n) {
387
+ function Ra(e, t, n) {
384
388
  if (ce(t)) return e.times(n);
385
389
  const a = t.plus(1).pow(n);
386
390
  return e.times(a.minus(1)).div(t.times(a));
@@ -402,7 +406,7 @@ function Gt(e, t, n, a) {
402
406
  throw new se("RATE_OUT_OF_RANGE", "Payment is too low to repay this amount.", "payment");
403
407
  let r = g(0), s = g(a);
404
408
  for (let m = 0; m < 200; m++) {
405
- const d = r.plus(s).div(2), i = St(e, xt(d), t);
409
+ const d = r.plus(s).div(2), i = Ct(e, St(d), t);
406
410
  if (ce(i.minus(n), "1e-8")) return d;
407
411
  i.lt(n) ? r = d : s = d;
408
412
  }
@@ -411,7 +415,7 @@ function Gt(e, t, n, a) {
411
415
  throw new se("SOLVER_DID_NOT_CONVERGE", "Could not find a rate within the allowed range.", "rate");
412
416
  return u;
413
417
  }
414
- function Ra(e, t, n, a) {
418
+ function Ma(e, t, n, a) {
415
419
  const r = [];
416
420
  let s = e, u = g(0);
417
421
  for (let m = 1; m <= n; m++) {
@@ -429,7 +433,7 @@ function Ra(e, t, n, a) {
429
433
  }
430
434
  return r;
431
435
  }
432
- function Ma(e) {
436
+ function $a(e) {
433
437
  const t = [];
434
438
  for (const n of e) {
435
439
  const a = Math.ceil(n.month / 12);
@@ -466,13 +470,13 @@ function Ie(e) {
466
470
  else throw s === "tenure" ? new se("MISSING_SOLVE_TARGET", "Flat-rate loans need an explicit tenure.", "tenureMonths") : new se("MISSING_SOLVE_TARGET", "Flat-rate loans need an explicit rate.", "annualRatePct");
467
471
  c = Gt(u, d, i, t.maxRatePct), l = "Flat: interest = P × rate × years; EMI = (P + interest) / n";
468
472
  } else {
469
- const k = () => xt(m);
473
+ const k = () => St(m);
470
474
  switch (s) {
471
475
  case "payment":
472
- i = ee(St(u, k(), d)), l = "PMT = P·r·(1+r)^n / ((1+r)^n − 1)";
476
+ i = ee(Ct(u, k(), d)), l = "PMT = P·r·(1+r)^n / ((1+r)^n − 1)";
473
477
  break;
474
478
  case "principal":
475
- u = Ia(i, k(), d), l = "P = PMT·((1+r)^n − 1) / (r·(1+r)^n)";
479
+ u = Ra(i, k(), d), l = "P = PMT·((1+r)^n − 1) / (r·(1+r)^n)";
476
480
  break;
477
481
  case "tenure":
478
482
  d = Ea(u, k(), i), l = "n = ln(PMT / (PMT − P·r)) / ln(1 + r)";
@@ -482,7 +486,7 @@ function Ie(e) {
482
486
  break;
483
487
  }
484
488
  }
485
- const p = xt(m), h = n === "flat" ? i : ee(St(u, p, d)), f = Ra(u, p, d, h);
489
+ const p = St(m), h = n === "flat" ? i : ee(Ct(u, p, d)), f = Ma(u, p, d, h);
486
490
  d = f.length;
487
491
  const y = f.reduce((k, S) => k.plus(S.interest), g(0)), w = f.reduce((k, S) => k.plus(S.payment), g(0));
488
492
  return {
@@ -496,7 +500,7 @@ function Ie(e) {
496
500
  totalInterest: ee(y),
497
501
  totalPayment: ee(w),
498
502
  schedule: f,
499
- byYear: Ma(f),
503
+ byYear: $a(f),
500
504
  chart: {
501
505
  balance: f.map((k) => k.closingBalance),
502
506
  cumulativeInterest: f.map((k) => k.cumulativeInterest)
@@ -518,7 +522,7 @@ const C = (e, t = 0) => {
518
522
  tone: n,
519
523
  sub: a
520
524
  }), U = (e) => e.toDecimalPlaces(2, H.ROUND_HALF_UP);
521
- function Rn(e, t) {
525
+ function En(e, t) {
522
526
  const n = /* @__PURE__ */ new Map();
523
527
  for (const r of e) {
524
528
  const s = Math.ceil(r.month / 12), u = n.get(s);
@@ -553,7 +557,7 @@ for (let e = 1; e <= 5; e++) {
553
557
  { key: `t${e}`, label: `Loan ${e} tenure`, kind: "tenure", default: 240, optional: !t, showIf: n, labelByRegion: { US: `Loan ${e} term` } }
554
558
  );
555
559
  }
556
- const $a = {
560
+ const Aa = {
557
561
  id: "loan.compare",
558
562
  group: "loans",
559
563
  title: "Compare loans",
@@ -597,7 +601,7 @@ const $a = {
597
601
  raw: i
598
602
  };
599
603
  }
600
- }, Aa = {
604
+ }, Da = {
601
605
  id: "loan.prepay",
602
606
  group: "loans",
603
607
  title: "Prepayment impact",
@@ -633,16 +637,16 @@ const $a = {
633
637
  const A = U(k.times(l));
634
638
  let I = h.minus(A);
635
639
  I.gt(k) && (I = k), k = U(k.minus(I)), S = S.plus(A);
636
- let E = g(0);
640
+ let R = g(0);
637
641
  if (k.gt(0) && N >= m && (d || N === m)) {
638
- E = u.gt(k) ? k : u;
639
- const j = U(E.times(c).div(100));
640
- if (F = F.plus(j), k = U(k.minus(E)), i) {
642
+ R = u.gt(k) ? k : u;
643
+ const j = U(R.times(c).div(100));
644
+ if (F = F.plus(j), k = U(k.minus(R)), i) {
641
645
  const Y = f - N;
642
646
  h = Y > 0 && k.gt(0) ? U(we(k, l, Y)) : h;
643
647
  }
644
648
  }
645
- w.push({ month: N, cells: [U(I), A, U(E), k] });
649
+ w.push({ month: N, cells: [U(I), A, U(R), k] });
646
650
  }
647
651
  const x = w.length, T = f - x, $ = U(y.minus(S)), L = U($.minus(F)), B = [];
648
652
  t.region === "IN" && B.push("RBI bars foreclosure/prepayment charges on floating-rate loans to individuals — penalty defaults to 0. Set it only for a fixed-rate loan."), B.push(i ? "EMI recomputed on the reduced balance; the original end date is kept." : "EMI kept the same; the loan simply finishes earlier.");
@@ -666,7 +670,7 @@ const $a = {
666
670
  schedule: {
667
671
  title: "New amortisation",
668
672
  columns: ["Month", "Principal", "Interest", "Prepay", "Balance"],
669
- groups: Rn(w, t),
673
+ groups: En(w, t),
670
674
  toneCols: { 1: "principal", 2: "interest" }
671
675
  },
672
676
  notes: B,
@@ -681,7 +685,7 @@ const $a = {
681
685
  }
682
686
  };
683
687
  }
684
- }, Da = {
688
+ }, La = {
685
689
  id: "loan.transfer",
686
690
  group: "loans",
687
691
  title: "Balance transfer",
@@ -725,7 +729,7 @@ const $a = {
725
729
  }
726
730
  };
727
731
  }
728
- }, La = {
732
+ }, Ua = {
729
733
  id: "loan.eligibility",
730
734
  group: "loans",
731
735
  title: "Loan eligibility",
@@ -777,7 +781,7 @@ const $a = {
777
781
  }
778
782
  };
779
783
  }
780
- }, Ua = {
784
+ }, Oa = {
781
785
  id: "loan.stepEmi",
782
786
  group: "loans",
783
787
  title: "Step-up / step-down EMI",
@@ -794,7 +798,7 @@ const $a = {
794
798
  let S = a;
795
799
  for (let F = 1; F <= s; F++) S = S.plus(S.times(m)).minus(k.times(d(F)));
796
800
  return S;
797
- }, c = U(at((k) => i(k), 0, a.toNumber(), 200) ?? we(a, m, s)), l = [];
801
+ }, c = U(rt((k) => i(k), 0, a.toNumber(), 200) ?? we(a, m, s)), l = [];
798
802
  let p = a, h = g(0), f = c;
799
803
  for (let k = 1; k <= s && p.gt("0.005"); k++) {
800
804
  const S = U(p.times(m));
@@ -814,7 +818,7 @@ const $a = {
814
818
  schedule: {
815
819
  title: "Amortisation",
816
820
  columns: ["Month", "Principal", "Interest", n.paymentLabel, "Balance"],
817
- groups: Rn(l, t),
821
+ groups: En(l, t),
818
822
  toneCols: { 1: "principal", 2: "interest" }
819
823
  },
820
824
  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.`],
@@ -828,7 +832,7 @@ const $a = {
828
832
  }
829
833
  };
830
834
  }
831
- }, Oa = {
835
+ }, Ba = {
832
836
  id: "loan.moratorium",
833
837
  group: "loans",
834
838
  title: "Moratorium / EMI holiday",
@@ -883,7 +887,7 @@ const $a = {
883
887
  }
884
888
  };
885
889
  }
886
- }, Ba = {
890
+ }, _a = {
887
891
  id: "loan.overdraft",
888
892
  group: "loans",
889
893
  title: "Overdraft / flexi loan",
@@ -913,7 +917,7 @@ const $a = {
913
917
  }
914
918
  };
915
919
  }
916
- }, _a = {
920
+ }, Ha = {
917
921
  id: "loan.refinance",
918
922
  group: "loans",
919
923
  title: "Refinance",
@@ -960,16 +964,16 @@ const $a = {
960
964
  }
961
965
  };
962
966
  }
963
- }, Ha = [
964
- $a,
967
+ }, qa = [
965
968
  Aa,
966
969
  Da,
967
970
  La,
968
971
  Ua,
969
972
  Oa,
970
973
  Ba,
971
- _a
972
- ], ot = Ze.defaults.sipReturnPercent, qa = Ze.defaults.inflationPercent, it = (e, t) => ({
974
+ _a,
975
+ Ha
976
+ ], it = Ze.defaults.sipReturnPercent, Ga = Ze.defaults.inflationPercent, st = (e, t) => ({
973
977
  labels: e,
974
978
  series: [{ name: "Value", tone: "accent", points: t, area: !0 }]
975
979
  }), Dt = (e) => ({
@@ -979,7 +983,7 @@ const $a = {
979
983
  }), Lt = (e, t) => [
980
984
  { label: "Invested", value: Number(e), tone: "principal" },
981
985
  { label: "Gains", value: Number(t), tone: "interest" }
982
- ], Ga = {
986
+ ], ja = {
983
987
  id: "invest.sip",
984
988
  group: "invest",
985
989
  title: "SIP Calculator",
@@ -987,7 +991,7 @@ const $a = {
987
991
  keywords: ["sip", "systematic investment plan", "mutual fund", "monthly investment", "future value"],
988
992
  inputs: [
989
993
  { key: "monthlyAmount", label: "Monthly investment", kind: "money", prefix: "currency", default: "10000" },
990
- { key: "expectedReturnPct", label: "Expected return", kind: "percent", suffix: "% p.a.", default: ot },
994
+ { key: "expectedReturnPct", label: "Expected return", kind: "percent", suffix: "% p.a.", default: it },
991
995
  { key: "tenure", label: "Investment period", kind: "tenure", default: 120 }
992
996
  ],
993
997
  compute(e, t) {
@@ -1005,7 +1009,7 @@ const $a = {
1005
1009
  ],
1006
1010
  split: Lt(i.toFixed(2), c.toFixed(2)),
1007
1011
  schedule: Dt(p),
1008
- chart: it(p.map((f) => f.label), h),
1012
+ chart: st(p.map((f) => f.label), h),
1009
1013
  formula: "FV = P·[((1+i)^n − 1) / i]·(1+i), i = r/12 (invested at the start of each month)",
1010
1014
  notes: ["Returns are assumed constant; actual market returns vary year to year."],
1011
1015
  raw: {
@@ -1016,7 +1020,7 @@ const $a = {
1016
1020
  }
1017
1021
  };
1018
1022
  }
1019
- }, ja = {
1023
+ }, Va = {
1020
1024
  id: "invest.stepupSip",
1021
1025
  group: "invest",
1022
1026
  title: "Step-up SIP Calculator",
@@ -1025,7 +1029,7 @@ const $a = {
1025
1029
  inputs: [
1026
1030
  { key: "monthlyAmount", label: "Initial monthly investment", kind: "money", prefix: "currency", default: "10000" },
1027
1031
  { key: "annualStepPct", label: "Annual step-up", kind: "percent", suffix: "%", default: "10" },
1028
- { key: "returnPct", label: "Expected return", kind: "percent", suffix: "% p.a.", default: ot },
1032
+ { key: "returnPct", label: "Expected return", kind: "percent", suffix: "% p.a.", default: it },
1029
1033
  { key: "tenure", label: "Investment period", kind: "tenure", default: 120 }
1030
1034
  ],
1031
1035
  compute(e, t) {
@@ -1044,13 +1048,13 @@ const $a = {
1044
1048
  ],
1045
1049
  split: Lt(c.toFixed(2), f.toFixed(2)),
1046
1050
  schedule: Dt(p),
1047
- chart: it(p.map((y) => y.label), h),
1051
+ chart: st(p.map((y) => y.label), h),
1048
1052
  formula: "Monthly simulation; the SIP amount is increased by the step-up % every 12 months",
1049
1053
  notes: ["The monthly amount steps up on each yearly anniversary; returns are assumed constant."],
1050
1054
  raw: { maturity: i.toFixed(2), invested: c.toFixed(2), gains: f.toFixed(2), finalMonthly: l.toFixed(2) }
1051
1055
  };
1052
1056
  }
1053
- }, Va = { annual: 1, semiannual: 2, quarterly: 4, monthly: 12 }, Ya = {
1057
+ }, Ya = { annual: 1, semiannual: 2, quarterly: 4, monthly: 12 }, Ka = {
1054
1058
  id: "invest.lumpsum",
1055
1059
  group: "invest",
1056
1060
  title: "Lump Sum Calculator",
@@ -1058,7 +1062,7 @@ const $a = {
1058
1062
  keywords: ["lump sum", "lumpsum", "one time investment", "compound interest", "maturity"],
1059
1063
  inputs: [
1060
1064
  { key: "principal", label: "Investment amount", kind: "money", prefix: "currency", default: "100000" },
1061
- { key: "ratePct", label: "Expected return", kind: "percent", suffix: "% p.a.", default: ot },
1065
+ { key: "ratePct", label: "Expected return", kind: "percent", suffix: "% p.a.", default: it },
1062
1066
  { key: "years", label: "Investment period", kind: "years", suffix: "years", default: 10 },
1063
1067
  {
1064
1068
  key: "compounding",
@@ -1074,7 +1078,7 @@ const $a = {
1074
1078
  }
1075
1079
  ],
1076
1080
  compute(e, t) {
1077
- 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 = Va[_(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) : rt(r, i, u), p = [], h = [];
1081
+ 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 = Ya[_(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) : ot(r, i, u), p = [], h = [];
1078
1082
  for (let f = 1; f <= u; f++) {
1079
1083
  const y = r.times(d.plus(1).pow(m * f));
1080
1084
  p.push({ label: String(f), cells: [a.money(r), a.money(y.minus(r)), a.money(y)] }), h.push(Number(y.toFixed(2)));
@@ -1088,13 +1092,13 @@ const $a = {
1088
1092
  ],
1089
1093
  split: Lt(r.toFixed(2), c.toFixed(2)),
1090
1094
  schedule: Dt(p),
1091
- chart: it(p.map((f) => f.label), h),
1095
+ chart: st(p.map((f) => f.label), h),
1092
1096
  formula: "A = P·(1 + r/f)^(f·t)",
1093
1097
  notes: ["Returns are assumed constant across the whole period."],
1094
1098
  raw: { maturity: i.toFixed(2), invested: r.toFixed(2), gains: c.toFixed(2), cagr: l.times(100).toFixed(4) }
1095
1099
  };
1096
1100
  }
1097
- }, Ka = 1200, Wa = {
1101
+ }, Wa = 1200, za = {
1098
1102
  id: "invest.swp",
1099
1103
  group: "invest",
1100
1104
  title: "SWP Calculator",
@@ -1107,7 +1111,7 @@ const $a = {
1107
1111
  { key: "tenureMonths", label: "Withdrawal period", kind: "tenure", default: 120, optional: !0 }
1108
1112
  ],
1109
1113
  compute(e, t) {
1110
- 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) : Ka;
1114
+ 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) : Wa;
1111
1115
  let c = r, l = n(0), p = 0;
1112
1116
  const h = [], f = [];
1113
1117
  let y = r, w = n(0);
@@ -1133,7 +1137,7 @@ const $a = {
1133
1137
  rows: h,
1134
1138
  toneCols: { 2: "interest", 3: "principal" }
1135
1139
  },
1136
- chart: it(h.map((N) => N.label), f),
1140
+ chart: st(h.map((N) => N.label), f),
1137
1141
  formula: "Each month: balance = balance·(1 + r/12) − withdrawal",
1138
1142
  notes: [
1139
1143
  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.",
@@ -1146,7 +1150,7 @@ const $a = {
1146
1150
  }
1147
1151
  };
1148
1152
  }
1149
- }, za = {
1153
+ }, Ja = {
1150
1154
  id: "invest.goal",
1151
1155
  group: "invest",
1152
1156
  title: "Goal SIP Planner",
@@ -1155,12 +1159,12 @@ const $a = {
1155
1159
  inputs: [
1156
1160
  { key: "targetCorpus", label: "Today's cost of goal", kind: "money", prefix: "currency", default: "10000000" },
1157
1161
  { key: "years", label: "Years to goal", kind: "years", suffix: "years", default: 15 },
1158
- { key: "expectedReturnPct", label: "Expected return", kind: "percent", suffix: "% p.a.", default: ot },
1159
- { key: "inflationPct", label: "Inflation", kind: "percent", suffix: "% p.a.", default: qa },
1162
+ { key: "expectedReturnPct", label: "Expected return", kind: "percent", suffix: "% p.a.", default: it },
1163
+ { key: "inflationPct", label: "Inflation", kind: "percent", suffix: "% p.a.", default: Ga },
1160
1164
  { key: "existingSavings", label: "Existing savings", kind: "money", prefix: "currency", default: "0", optional: !0 }
1161
1165
  ],
1162
1166
  compute(e, t) {
1163
- 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 = Qe(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 = [
1167
+ 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 = et(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 = [
1164
1168
  `Target grows with ${a.pct(m.times(100))} inflation to ${a.money(l)} in ${s} years.`
1165
1169
  ];
1166
1170
  d.gt(0) && S.push(`Existing savings grow to ${a.money(p)}, reducing what the SIP must fund.`);
@@ -1184,14 +1188,14 @@ const $a = {
1184
1188
  }
1185
1189
  };
1186
1190
  }
1187
- }, Ja = [Ga, ja, Ya, Wa, za], $n = "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) => ({
1191
+ }, Za = [ja, Va, Ka, za, Ja], $n = "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) => ({
1188
1192
  labels: e,
1189
1193
  series: [{ name: n, tone: "accent", points: t, area: !0 }]
1190
1194
  }), Be = (e, t, n) => ({
1191
1195
  columns: e,
1192
1196
  rows: t,
1193
1197
  toneCols: { [n]: "interest" }
1194
- }), Za = {
1198
+ }), Xa = {
1195
1199
  id: "invest.fd",
1196
1200
  group: "invest",
1197
1201
  title: "Fixed Deposit (FD)",
@@ -1263,7 +1267,7 @@ const $a = {
1263
1267
  }
1264
1268
  };
1265
1269
  }
1266
- }, Xa = {
1270
+ }, Qa = {
1267
1271
  id: "invest.rd",
1268
1272
  group: "invest",
1269
1273
  title: "Recurring Deposit (RD)",
@@ -1309,7 +1313,7 @@ const $a = {
1309
1313
  raw: { maturity: i.toFixed(2), invested: c.toFixed(2), interest: l.toFixed(2) }
1310
1314
  };
1311
1315
  }
1312
- }, Qa = {
1316
+ }, er = {
1313
1317
  id: "invest.ppf",
1314
1318
  group: "invest",
1315
1319
  title: "Public Provident Fund (PPF)",
@@ -1366,7 +1370,7 @@ const $a = {
1366
1370
  raw: { maturity: i.toFixed(2), invested: p.toFixed(2), interest: h.toFixed(2) }
1367
1371
  };
1368
1372
  }
1369
- }, er = {
1373
+ }, tr = {
1370
1374
  id: "invest.nps",
1371
1375
  group: "invest",
1372
1376
  title: "National Pension System (NPS)",
@@ -1410,7 +1414,7 @@ const $a = {
1410
1414
  }
1411
1415
  };
1412
1416
  }
1413
- }, tr = {
1417
+ }, nr = {
1414
1418
  id: "invest.epf",
1415
1419
  group: "invest",
1416
1420
  title: "Employees’ Provident Fund (EPF)",
@@ -1459,7 +1463,7 @@ const $a = {
1459
1463
  raw: { corpus: h.toFixed(2), contributions: f.toFixed(2), interest: k.toFixed(2) }
1460
1464
  };
1461
1465
  }
1462
- }, nr = {
1466
+ }, ar = {
1463
1467
  id: "invest.ssy",
1464
1468
  group: "invest",
1465
1469
  title: "Sukanya Samriddhi Yojana (SSY)",
@@ -1502,7 +1506,7 @@ const $a = {
1502
1506
  raw: { maturity: l.toFixed(2), invested: f.toFixed(2), interest: y.toFixed(2) }
1503
1507
  };
1504
1508
  }
1505
- }, ar = [Za, Xa, Qa, er, tr, nr], rr = {
1509
+ }, rr = [Xa, Qa, er, tr, nr, ar], or = {
1506
1510
  id: "invest.401k",
1507
1511
  group: "invest",
1508
1512
  title: "401(k) with Employer Match",
@@ -1566,7 +1570,7 @@ const $a = {
1566
1570
  }
1567
1571
  };
1568
1572
  }
1569
- }, or = {
1573
+ }, ir = {
1570
1574
  id: "invest.iraCompare",
1571
1575
  group: "invest",
1572
1576
  title: "Roth vs Traditional IRA",
@@ -1620,7 +1624,7 @@ const $a = {
1620
1624
  }
1621
1625
  };
1622
1626
  }
1623
- }, ir = {
1627
+ }, sr = {
1624
1628
  id: "invest.529",
1625
1629
  group: "invest",
1626
1630
  title: "529 College Savings",
@@ -1636,7 +1640,7 @@ const $a = {
1636
1640
  { key: "collegeCostInflationPct", label: "College cost inflation", kind: "percent", suffix: "%", default: 5, advanced: !0 }
1637
1641
  ],
1638
1642
  compute(e, t) {
1639
- 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 = Qe(a, m, u), i = be(r, m, u), c = d.plus(i), l = a.plus(r.times(u)), p = c.minus(l), h = [
1643
+ 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 = et(a, m, u), i = be(r, m, u), c = d.plus(i), l = a.plus(r.times(u)), p = c.minus(l), h = [
1640
1644
  v("Total invested", n.money(l), "principal"),
1641
1645
  v("Investment growth", n.money(p), "interest")
1642
1646
  ], f = {
@@ -1650,7 +1654,7 @@ const $a = {
1650
1654
  const k = g(C(e.currentAnnualCost)), S = g(C(e.collegeCostInflationPct)).div(100);
1651
1655
  let F = g(0);
1652
1656
  for (let x = 0; x < 4; x++)
1653
- F = F.plus(Qe(k, S, s + x));
1657
+ F = F.plus(et(k, S, s + x));
1654
1658
  const N = c.minus(F), P = N.gte(0);
1655
1659
  h.push(v("4-year college cost", n.money(F), "default", "inflation-adjusted")), h.push(
1656
1660
  v(
@@ -1675,7 +1679,7 @@ const $a = {
1675
1679
  raw: f
1676
1680
  };
1677
1681
  }
1678
- }, sr = [rr, or, ir], lr = (e) => e === "annual" ? 1 : e === "semiannual" ? 2 : e === "quarterly" ? 4 : 12, st = (e) => _(e).split(/[, ]+/).map((t) => t.trim()).filter(Boolean).map(Number).filter((t) => Number.isFinite(t)), cr = {
1682
+ }, lr = [or, ir, sr], cr = (e) => e === "annual" ? 1 : e === "semiannual" ? 2 : e === "quarterly" ? 4 : 12, lt = (e) => _(e).split(/[, ]+/).map((t) => t.trim()).filter(Boolean).map(Number).filter((t) => Number.isFinite(t)), ur = {
1679
1683
  id: "returns.tvm",
1680
1684
  group: "returns",
1681
1685
  title: "Time value of money (TVM)",
@@ -1706,7 +1710,7 @@ const $a = {
1706
1710
  ] }
1707
1711
  ],
1708
1712
  compute(e) {
1709
- const t = _(e.solveFor, "FV"), n = lr(_(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);
1713
+ const t = _(e.solveFor, "FV"), n = cr(_(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);
1710
1714
  let l = "Future value", p = g(0), h = "PV·(1+i)^n + PMT·[((1+i)^n − 1)/i]·timing + FV = 0";
1711
1715
  if (t === "FV")
1712
1716
  p = u.times(c(a, r)).plus(m.times(i(a, r))).neg(), l = "Future value";
@@ -1743,7 +1747,7 @@ const $a = {
1743
1747
  }
1744
1748
  return { primary: v(l, p.toDecimalPlaces(2).toString(), "accent"), formula: h, raw: { value: p.toNumber() } };
1745
1749
  }
1746
- }, ur = {
1750
+ }, dr = {
1747
1751
  id: "returns.cagr",
1748
1752
  group: "returns",
1749
1753
  title: "CAGR",
@@ -1755,7 +1759,7 @@ const $a = {
1755
1759
  { key: "years", label: "Period", kind: "years", default: "10" }
1756
1760
  ],
1757
1761
  compute(e, t) {
1758
- const n = t.D(C(e.begin)), a = t.D(C(e.end)), r = C(e.years) || 1, s = rt(n, a, r).times(100), u = a.minus(n).div(n).times(100);
1762
+ const n = t.D(C(e.begin)), a = t.D(C(e.end)), r = C(e.years) || 1, s = ot(n, a, r).times(100), u = a.minus(n).div(n).times(100);
1759
1763
  return {
1760
1764
  primary: v("CAGR", `${t.fmt.num(s, 2)}%`, "accent"),
1761
1765
  secondary: [
@@ -1766,7 +1770,7 @@ const $a = {
1766
1770
  raw: { cagr: s.toNumber(), absolute: u.toNumber() }
1767
1771
  };
1768
1772
  }
1769
- }, dr = {
1773
+ }, mr = {
1770
1774
  id: "returns.absolute",
1771
1775
  group: "returns",
1772
1776
  title: "Absolute return",
@@ -1779,14 +1783,14 @@ const $a = {
1779
1783
  ],
1780
1784
  compute(e, t) {
1781
1785
  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")];
1782
- return s > 0 && u.push(v("Annualised (CAGR)", `${t.fmt.num(rt(n, a, s).times(100), 2)}%`)), {
1786
+ return s > 0 && u.push(v("Annualised (CAGR)", `${t.fmt.num(ot(n, a, s).times(100), 2)}%`)), {
1783
1787
  primary: v("Absolute return", `${t.fmt.num(r, 2)}%`, "accent"),
1784
1788
  secondary: u,
1785
1789
  formula: "Absolute return = (Current − Invested) / Invested",
1786
1790
  raw: { absolute: r.toNumber() }
1787
1791
  };
1788
1792
  }
1789
- }, mr = {
1793
+ }, pr = {
1790
1794
  id: "returns.xirr",
1791
1795
  group: "returns",
1792
1796
  title: "XIRR",
@@ -1802,7 +1806,7 @@ const $a = {
1802
1806
  compute(e, t) {
1803
1807
  const a = (e.flows ?? []).filter((u) => u.date && u.amount !== "").map((u) => ({ date: u.date, amount: u.amount }));
1804
1808
  if (a.length < 2) return { primary: v("XIRR", "—"), warnings: ["Enter at least two dated cashflows."] };
1805
- const r = En(a);
1809
+ const r = Rn(a);
1806
1810
  if (!r) return { primary: v("XIRR", "—"), warnings: ["Need at least one negative and one positive cashflow."] };
1807
1811
  const s = r.times(100);
1808
1812
  return {
@@ -1811,7 +1815,7 @@ const $a = {
1811
1815
  raw: { xirr: s.toNumber() }
1812
1816
  };
1813
1817
  }
1814
- }, pr = {
1818
+ }, hr = {
1815
1819
  id: "returns.irr",
1816
1820
  group: "returns",
1817
1821
  title: "IRR",
@@ -1819,12 +1823,12 @@ const $a = {
1819
1823
  keywords: ["irr", "internal rate of return"],
1820
1824
  inputs: [{ key: "series", label: "Cashflows (comma-separated, period 0 first)", kind: "text", default: "-100000, 30000, 40000, 50000, 40000", help: "-100000, 30000, ..." }],
1821
1825
  compute(e, t) {
1822
- const n = st(_(e.series));
1826
+ const n = lt(_(e.series));
1823
1827
  if (n.length < 2) return { primary: v("IRR", "—"), warnings: ["Enter at least two cashflows."] };
1824
1828
  const a = Fn(n);
1825
1829
  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."] };
1826
1830
  }
1827
- }, hr = {
1831
+ }, fr = {
1828
1832
  id: "returns.npv",
1829
1833
  group: "returns",
1830
1834
  title: "NPV",
@@ -1835,7 +1839,7 @@ const $a = {
1835
1839
  { key: "series", label: "Cashflows (comma-separated, period 0 first)", kind: "text", default: "-100000, 30000, 40000, 50000, 40000" }
1836
1840
  ],
1837
1841
  compute(e, t) {
1838
- const n = st(_(e.series)), a = At(g(C(e.ratePct)).div(100), n);
1842
+ const n = lt(_(e.series)), a = At(g(C(e.ratePct)).div(100), n);
1839
1843
  return {
1840
1844
  primary: v("NPV", t.fmt.money(a), a.gte(0) ? "positive" : "negative"),
1841
1845
  secondary: [v(a.gte(0) ? "Value-creating" : "Value-destroying", a.gte(0) ? "NPV ≥ 0" : "NPV < 0")],
@@ -1843,7 +1847,7 @@ const $a = {
1843
1847
  raw: { npv: a.toNumber() }
1844
1848
  };
1845
1849
  }
1846
- }, fr = {
1850
+ }, yr = {
1847
1851
  id: "returns.mirr",
1848
1852
  group: "returns",
1849
1853
  title: "MIRR",
@@ -1855,7 +1859,7 @@ const $a = {
1855
1859
  { key: "reinvestPct", label: "Reinvestment rate", kind: "percent", default: "12" }
1856
1860
  ],
1857
1861
  compute(e, t) {
1858
- const n = st(_(e.series)), a = n.length - 1;
1862
+ const n = lt(_(e.series)), a = n.length - 1;
1859
1863
  if (a < 1) return { primary: v("MIRR", "—"), warnings: ["Enter at least two cashflows."] };
1860
1864
  const r = g(C(e.financePct)).div(100), s = g(C(e.reinvestPct)).div(100);
1861
1865
  let u = g(0), m = g(0);
@@ -1865,7 +1869,7 @@ const $a = {
1865
1869
  const d = u.div(m.neg()).pow(g(1).div(a)).minus(1).times(100);
1866
1870
  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() } };
1867
1871
  }
1868
- }, yr = {
1872
+ }, br = {
1869
1873
  id: "returns.payback",
1870
1874
  group: "returns",
1871
1875
  title: "Payback period",
@@ -1877,7 +1881,7 @@ const $a = {
1877
1881
  { key: "discountPct", label: "Discount rate (for discounted payback)", kind: "percent", default: "0", optional: !0, advanced: !0 }
1878
1882
  ],
1879
1883
  compute(e, t) {
1880
- const n = t.D(C(e.investment)), a = st(_(e.series)), r = g(C(e.discountPct)).div(100), s = r.gt(0);
1884
+ const n = t.D(C(e.investment)), a = lt(_(e.series)), r = g(C(e.discountPct)).div(100), s = r.gt(0);
1881
1885
  let u = g(0), m = 0, d = null;
1882
1886
  for (let i = 0; i < a.length; i++) {
1883
1887
  const c = s ? g(a[i]).div(r.plus(1).pow(i + 1)) : g(a[i]), l = u;
@@ -1894,7 +1898,7 @@ const $a = {
1894
1898
  raw: { payback: d }
1895
1899
  };
1896
1900
  }
1897
- }, br = {
1901
+ }, gr = {
1898
1902
  id: "returns.realReturn",
1899
1903
  group: "returns",
1900
1904
  title: "Real (inflation-adjusted) return",
@@ -1913,7 +1917,7 @@ const $a = {
1913
1917
  raw: { real: r.toNumber() }
1914
1918
  };
1915
1919
  }
1916
- }, gr = {
1920
+ }, vr = {
1917
1921
  id: "returns.rule72",
1918
1922
  group: "returns",
1919
1923
  title: "Rule of 72",
@@ -1934,8 +1938,7 @@ const $a = {
1934
1938
  raw: { approx: a.toNumber(), exact: r.toNumber() }
1935
1939
  };
1936
1940
  }
1937
- }, vr = [
1938
- cr,
1941
+ }, kr = [
1939
1942
  ur,
1940
1943
  dr,
1941
1944
  mr,
@@ -1944,7 +1947,8 @@ const $a = {
1944
1947
  fr,
1945
1948
  yr,
1946
1949
  br,
1947
- gr
1950
+ gr,
1951
+ vr
1948
1952
  ], Ne = "Estimate for planning only — not tax advice. Verify against current law and your own situation.";
1949
1953
  function Ut(e, t, n) {
1950
1954
  let a = g(0), r = 0;
@@ -1962,7 +1966,7 @@ function Ut(e, t, n) {
1962
1966
  }
1963
1967
  return { tax: a, rows: s };
1964
1968
  }
1965
- const kr = (e, t) => Ut(e, t, wr).tax, wr = { money: (e) => String(e) }, jt = (e, t) => e.gt(t) ? g(t) : e, lt = (e, t) => v(e, t, "positive"), Nr = {
1969
+ const wr = (e, t) => Ut(e, t, Nr).tax, Nr = { money: (e) => String(e) }, jt = (e, t) => e.gt(t) ? g(t) : e, ct = (e, t) => v(e, t, "positive"), xr = {
1966
1970
  id: "tax.gst",
1967
1971
  group: "tax",
1968
1972
  title: "GST Calculator",
@@ -2043,7 +2047,7 @@ const kr = (e, t) => Ut(e, t, wr).tax, wr = { money: (e) => String(e) }, jt = (e
2043
2047
  }
2044
2048
  };
2045
2049
  }
2046
- }, xr = {
2050
+ }, Sr = {
2047
2051
  id: "tax.tds",
2048
2052
  group: "tax",
2049
2053
  title: "TDS on Interest",
@@ -2077,7 +2081,7 @@ const kr = (e, t) => Ut(e, t, wr).tax, wr = { money: (e) => String(e) }, jt = (e
2077
2081
  ), {
2078
2082
  primary: v("TDS deducted", n.money(p), p.gt(0) ? "negative" : "positive"),
2079
2083
  secondary: [
2080
- lt("Net interest received", n.money(h)),
2084
+ ct("Net interest received", n.money(h)),
2081
2085
  v("Effective TDS rate", n.pct(f), "accent"),
2082
2086
  v("Applicable threshold", n.money(d), "default")
2083
2087
  ],
@@ -2090,7 +2094,7 @@ const kr = (e, t) => Ut(e, t, wr).tax, wr = { money: (e) => String(e) }, jt = (e
2090
2094
  "<60": [{ to: 25e4, rate: 0 }, { to: 5e5, rate: 5 }, { to: 1e6, rate: 20 }, { to: 1 / 0, rate: 30 }],
2091
2095
  "60-80": [{ to: 3e5, rate: 0 }, { to: 5e5, rate: 5 }, { to: 1e6, rate: 20 }, { to: 1 / 0, rate: 30 }],
2092
2096
  "80+": [{ to: 5e5, rate: 0 }, { to: 1e6, rate: 20 }, { to: 1 / 0, rate: 30 }]
2093
- }, Sr = [
2097
+ }, Cr = [
2094
2098
  { to: 3e5, rate: 0 },
2095
2099
  { to: 7e5, rate: 5 },
2096
2100
  { to: 1e6, rate: 10 },
@@ -2098,7 +2102,7 @@ const kr = (e, t) => Ut(e, t, wr).tax, wr = { money: (e) => String(e) }, jt = (e
2098
2102
  { to: 15e5, rate: 20 },
2099
2103
  { to: 1 / 0, rate: 30 }
2100
2104
  ];
2101
- function Cr(e, t, n) {
2105
+ function Pr(e, t, n) {
2102
2106
  const r = [
2103
2107
  { threshold: 5e7, rate: 25, prev: 20 },
2104
2108
  { threshold: 2e7, rate: 20, prev: 15 },
@@ -2110,10 +2114,10 @@ function Cr(e, t, n) {
2110
2114
  return i.gt(0) ? s.minus(i) : s;
2111
2115
  }
2112
2116
  function Yt(e, t, n, a, r) {
2113
- 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 = Cr(e, d, (p) => kr(g(p), t)), c = d.plus(i).times("0.04"), l = d.plus(i).plus(c);
2117
+ 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 = Pr(e, d, (p) => wr(g(p), t)), c = d.plus(i).times("0.04"), l = d.plus(i).plus(c);
2114
2118
  return { taxable: e, base: s, rebate: m, surcharge: i, cess: c, total: l, rows: u };
2115
2119
  }
2116
- const Pr = {
2120
+ const Tr = {
2117
2121
  id: "tax.incomeIN",
2118
2122
  group: "tax",
2119
2123
  title: "Income Tax (Old vs New)",
@@ -2139,7 +2143,7 @@ const Pr = {
2139
2143
  { key: "homeLoanInterest", label: "Home loan interest (24b)", kind: "money", prefix: "currency", default: "0", help: "max ₹2L", optional: !0 }
2140
2144
  ],
2141
2145
  compute(e, t) {
2142
- 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, Sr, 7e5, 25e3, n), w = !y.total.gt(p.total), k = w ? y : p, S = p.total.minus(y.total).abs();
2146
+ 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, Cr, 7e5, 25e3, n), w = !y.total.gt(p.total), k = w ? y : p, S = p.total.minus(y.total).abs();
2143
2147
  return {
2144
2148
  primary: v(
2145
2149
  `${w ? "New" : "Old"} regime is cheaper`,
@@ -2175,7 +2179,7 @@ const Pr = {
2175
2179
  }
2176
2180
  };
2177
2181
  }
2178
- }, Tr = {
2182
+ }, Fr = {
2179
2183
  id: "tax.capitalGains",
2180
2184
  group: "tax",
2181
2185
  title: "Capital Gains Tax",
@@ -2224,7 +2228,7 @@ const Pr = {
2224
2228
  raw: { gain: d.toFixed(2), tax: h ? null : l.toFixed(2), type: p, isLong: c ? 1 : 0 }
2225
2229
  };
2226
2230
  }
2227
- }, Fr = {
2231
+ }, Ir = {
2228
2232
  id: "tax.hra",
2229
2233
  group: "tax",
2230
2234
  title: "HRA Exemption",
@@ -2244,7 +2248,7 @@ const Pr = {
2244
2248
  l.lt(h) && (h = l), p.lt(h) && (h = p);
2245
2249
  const f = s.minus(h);
2246
2250
  return {
2247
- primary: lt("HRA exempt", n.money(h)),
2251
+ primary: ct("HRA exempt", n.money(h)),
2248
2252
  secondary: [
2249
2253
  v("Taxable HRA", n.money(f), "negative"),
2250
2254
  v("HRA received", n.money(s), "principal"),
@@ -2259,7 +2263,7 @@ const Pr = {
2259
2263
  raw: { exempt: h.toFixed(2), taxable: f.toFixed(2), limitRent: l.toFixed(2), limitPct: p.toFixed(2) }
2260
2264
  };
2261
2265
  }
2262
- }, Ir = {
2266
+ }, Rr = {
2263
2267
  id: "tax.advanceTax",
2264
2268
  group: "tax",
2265
2269
  title: "Advance Tax Instalments",
@@ -2358,7 +2362,7 @@ const Pr = {
2358
2362
  { to: 609350, rate: 35 },
2359
2363
  { to: 1 / 0, rate: 37 }
2360
2364
  ]
2361
- }, Rr = { single: 14600, marriedJoint: 29200, headOfHousehold: 21900 }, Mr = {
2365
+ }, Mr = { single: 14600, marriedJoint: 29200, headOfHousehold: 21900 }, $r = {
2362
2366
  id: "tax.incomeUS",
2363
2367
  group: "tax",
2364
2368
  title: "Federal Income Tax",
@@ -2398,14 +2402,14 @@ const Pr = {
2398
2402
  }
2399
2403
  ],
2400
2404
  compute(e, t) {
2401
- 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(Rr[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);
2405
+ 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(Mr[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);
2402
2406
  return {
2403
2407
  primary: v("Federal income tax", n.money(c), "negative"),
2404
2408
  secondary: [
2405
2409
  v("Taxable income", n.money(i), "principal", `after ${n.money(m)} deduction`),
2406
2410
  v("Effective rate", n.pct(p), "accent"),
2407
2411
  v("Marginal rate", `${f}%`, "default"),
2408
- lt("After-tax income", n.money(y))
2412
+ ct("After-tax income", n.money(y))
2409
2413
  ],
2410
2414
  schedule: {
2411
2415
  title: "Bracket breakdown",
@@ -2427,7 +2431,7 @@ const Pr = {
2427
2431
  }
2428
2432
  };
2429
2433
  }
2430
- }, $r = {
2434
+ }, Ar = {
2431
2435
  id: "tax.mortgageDeductionUS",
2432
2436
  group: "tax",
2433
2437
  title: "Mortgage Interest Deduction",
@@ -2445,7 +2449,7 @@ const Pr = {
2445
2449
  "Acquisition-debt limit is $750,000 ($375,000 if married filing separately) for loans after 15 Dec 2017. " + Ne
2446
2450
  ];
2447
2451
  return s.gt(u) && i.unshift(`Loan balance exceeds $750k: only ${n.pct(g(u).div(s).times(100))} of the interest is deductible.`), {
2448
- primary: lt("Estimated tax savings", n.money(d)),
2452
+ primary: ct("Estimated tax savings", n.money(d)),
2449
2453
  secondary: [
2450
2454
  v("Deductible interest", n.money(m), "principal"),
2451
2455
  v("Marginal tax rate", n.pct(g(C(e.marginalTaxRatePct, 24))), "accent")
@@ -2455,22 +2459,22 @@ const Pr = {
2455
2459
  raw: { savings: d.toFixed(2), deductibleInterest: m.toFixed(2) }
2456
2460
  };
2457
2461
  }
2458
- }, Ar = [
2459
- Nr,
2462
+ }, Dr = [
2460
2463
  xr,
2461
- Pr,
2464
+ Sr,
2462
2465
  Tr,
2463
2466
  Fr,
2464
2467
  Ir,
2468
+ Rr,
2465
2469
  Er,
2466
- Mr,
2467
- $r
2470
+ $r,
2471
+ Ar
2468
2472
  ], $e = {
2469
2473
  length: { m: 1, km: 1e3, cm: 0.01, mm: 1e-3, mi: 1609.344, yd: 0.9144, ft: 0.3048, in: 0.0254 },
2470
2474
  area: { sqm: 1, sqft: 0.092903, sqyd: 0.836127, acre: 4046.8564224, hectare: 1e4, bigha: 1337.8, gunta: 101.17, cent: 40.4686 },
2471
2475
  weight: { kg: 1, g: 1e-3, mg: 1e-6, lb: 0.45359237, oz: 0.0283495, tonne: 1e3, quintal: 100 },
2472
2476
  volume: { l: 1, ml: 1e-3, m3: 1e3, gal_us: 3.785411784, gal_uk: 4.54609, cup: 0.24, pint: 0.473176 }
2473
- }, Ct = {
2477
+ }, Pt = {
2474
2478
  m: "Meters (m)",
2475
2479
  km: "Kilometers (km)",
2476
2480
  cm: "Centimeters (cm)",
@@ -2504,10 +2508,10 @@ const Pr = {
2504
2508
  C: "Celsius (°C)",
2505
2509
  F: "Fahrenheit (°F)",
2506
2510
  K: "Kelvin (K)"
2507
- }, Dr = ["C", "F", "K"], Wt = (e) => e.map((t) => ({ value: t, label: Ct[t] ?? t })), Ae = (e, t, n, a) => [
2511
+ }, Lr = ["C", "F", "K"], Wt = (e) => e.map((t) => ({ value: t, label: Pt[t] ?? t })), Ae = (e, t, n, a) => [
2508
2512
  { key: `${e}From`, label: "From", kind: "select", default: n, options: Wt(t), showIf: (r) => r.category === e },
2509
2513
  { key: `${e}To`, label: "To", kind: "select", default: a, options: Wt(t), showIf: (r) => r.category === e }
2510
- ], Lr = {
2514
+ ], Ur = {
2511
2515
  id: "tools.units",
2512
2516
  group: "tools",
2513
2517
  title: "Unit Converter",
@@ -2532,7 +2536,7 @@ const Pr = {
2532
2536
  ...Ae("area", Object.keys($e.area), "acre", "sqm"),
2533
2537
  ...Ae("weight", Object.keys($e.weight), "kg", "lb"),
2534
2538
  ...Ae("volume", Object.keys($e.volume), "l", "gal_us"),
2535
- ...Ae("temperature", Dr, "C", "F")
2539
+ ...Ae("temperature", Lr, "C", "F")
2536
2540
  ],
2537
2541
  compute(e, t) {
2538
2542
  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 = [];
@@ -2544,21 +2548,21 @@ const Pr = {
2544
2548
  const p = $e[s];
2545
2549
  i = r.times(p[u] ?? 1).div(p[m] ?? 1), (u === "bigha" || m === "bigha") && d.push("Bigha is not standardised — its size varies by state; this uses a common ~1337.8 m² value.");
2546
2550
  }
2547
- const c = Ct[u] ?? u, l = Ct[m] ?? m;
2551
+ const c = Pt[u] ?? u, l = Pt[m] ?? m;
2548
2552
  return {
2549
2553
  primary: v(`${r.toString()} ${c} =`, `${a.num(i, 4)} ${l}`, "accent"),
2550
2554
  notes: d,
2551
2555
  raw: { result: i.toFixed(6), from: u, to: m, category: s }
2552
2556
  };
2553
2557
  }
2554
- }, je = 864e5, pt = (e) => {
2558
+ }, je = 864e5, ht = (e) => {
2555
2559
  if (!e) {
2556
2560
  const r = /* @__PURE__ */ new Date();
2557
2561
  return new Date(Date.UTC(r.getUTCFullYear(), r.getUTCMonth(), r.getUTCDate()));
2558
2562
  }
2559
2563
  const [t, n, a] = e.split("-").map(Number);
2560
2564
  return new Date(Date.UTC(t, (n || 1) - 1, a || 1));
2561
- }, ht = (e, t) => new Date(Date.UTC(e, t, 0)).getUTCDate(), Ve = (e) => e.toISOString().slice(0, 10), Ur = {
2565
+ }, ft = (e, t) => new Date(Date.UTC(e, t, 0)).getUTCDate(), Ve = (e) => e.toISOString().slice(0, 10), Or = {
2562
2566
  id: "tools.dateCalc",
2563
2567
  group: "tools",
2564
2568
  title: "Date Calculator",
@@ -2605,15 +2609,15 @@ const Pr = {
2605
2609
  ],
2606
2610
  compute(e) {
2607
2611
  if (_(e.mode, "difference") === "addSubtract") {
2608
- const l = pt(_(e.startDate, "")), p = Math.round(C(e.count, 0)), h = _(e.unit, "days"), f = _(e.direction, "add") === "subtract" ? -1 : 1, y = f * p;
2612
+ const l = ht(_(e.startDate, "")), p = Math.round(C(e.count, 0)), h = _(e.unit, "days"), f = _(e.direction, "add") === "subtract" ? -1 : 1, y = f * p;
2609
2613
  let w;
2610
2614
  if (h === "days" || h === "weeks")
2611
2615
  w = new Date(l.getTime() + y * (h === "weeks" ? 7 : 1) * je);
2612
2616
  else if (h === "months") {
2613
- const S = l.getUTCMonth() + y, F = l.getUTCFullYear() + Math.floor(S / 12), N = (S % 12 + 12) % 12, P = Math.min(l.getUTCDate(), ht(F, N + 1));
2617
+ const S = l.getUTCMonth() + y, F = l.getUTCFullYear() + Math.floor(S / 12), N = (S % 12 + 12) % 12, P = Math.min(l.getUTCDate(), ft(F, N + 1));
2614
2618
  w = new Date(Date.UTC(F, N, P));
2615
2619
  } else {
2616
- const S = l.getUTCFullYear() + y, F = Math.min(l.getUTCDate(), ht(S, l.getUTCMonth() + 1));
2620
+ const S = l.getUTCFullYear() + y, F = Math.min(l.getUTCDate(), ft(S, l.getUTCMonth() + 1));
2617
2621
  w = new Date(Date.UTC(S, l.getUTCMonth(), F));
2618
2622
  }
2619
2623
  const k = ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"][w.getUTCDay()];
@@ -2623,10 +2627,10 @@ const Pr = {
2623
2627
  raw: { resultDate: Ve(w), weekday: k, from: Ve(l) }
2624
2628
  };
2625
2629
  }
2626
- let n = pt(_(e.startDate, "")), a = pt(_(e.endDate, "")), r = !1;
2630
+ let n = ht(_(e.startDate, "")), a = ht(_(e.endDate, "")), r = !1;
2627
2631
  a.getTime() < n.getTime() && ([n, a] = [a, n], r = !0);
2628
2632
  let s = a.getUTCFullYear() - n.getUTCFullYear(), u = a.getUTCMonth() - n.getUTCMonth(), m = a.getUTCDate() - n.getUTCDate();
2629
- m < 0 && (u -= 1, m += ht(a.getUTCFullYear(), a.getUTCMonth())), u < 0 && (s -= 1, u += 12);
2633
+ m < 0 && (u -= 1, m += ft(a.getUTCFullYear(), a.getUTCMonth())), u < 0 && (s -= 1, u += 12);
2630
2634
  const d = Math.round((a.getTime() - n.getTime()) / je);
2631
2635
  let i = 0;
2632
2636
  for (let l = n.getTime() + je; l <= a.getTime(); l += je) {
@@ -2645,23 +2649,23 @@ const Pr = {
2645
2649
  raw: { years: s, months: u, days: m, totalDays: d, weeks: Number((d / 7).toFixed(2)), businessDays: i }
2646
2650
  };
2647
2651
  }
2648
- }, Pt = ["Zero", "One", "Two", "Three", "Four", "Five", "Six", "Seven", "Eight", "Nine", "Ten", "Eleven", "Twelve", "Thirteen", "Fourteen", "Fifteen", "Sixteen", "Seventeen", "Eighteen", "Nineteen"], Or = ["", "", "Twenty", "Thirty", "Forty", "Fifty", "Sixty", "Seventy", "Eighty", "Ninety"], et = (e) => e < 20 ? Pt[e] : Or[Math.floor(e / 10)] + (e % 10 ? " " + Pt[e % 10] : ""), Tt = (e) => {
2652
+ }, Tt = ["Zero", "One", "Two", "Three", "Four", "Five", "Six", "Seven", "Eight", "Nine", "Ten", "Eleven", "Twelve", "Thirteen", "Fourteen", "Fifteen", "Sixteen", "Seventeen", "Eighteen", "Nineteen"], Br = ["", "", "Twenty", "Thirty", "Forty", "Fifty", "Sixty", "Seventy", "Eighty", "Ninety"], tt = (e) => e < 20 ? Tt[e] : Br[Math.floor(e / 10)] + (e % 10 ? " " + Tt[e % 10] : ""), Ft = (e) => {
2649
2653
  const t = Math.floor(e / 100), n = e % 100, a = [];
2650
- return t && a.push(Pt[t] + " Hundred"), n && a.push(et(n)), a.join(" ");
2654
+ return t && a.push(Tt[t] + " Hundred"), n && a.push(tt(n)), a.join(" ");
2651
2655
  }, An = (e) => {
2652
2656
  if (e === 0) return "Zero";
2653
2657
  const t = ["", " Thousand", " Million", " Billion", " Trillion"], n = [];
2654
2658
  let a = 0;
2655
2659
  for (; e > 0 && a < t.length; ) {
2656
2660
  const r = e % 1e3;
2657
- r && n.unshift(Tt(r) + t[a]), e = Math.floor(e / 1e3), a++;
2661
+ r && n.unshift(Ft(r) + t[a]), e = Math.floor(e / 1e3), a++;
2658
2662
  }
2659
2663
  return n.length ? n.join(" ") : "Zero";
2660
- }, Br = (e) => {
2664
+ }, _r = (e) => {
2661
2665
  if (e === 0) return "Zero";
2662
2666
  const t = Math.floor(e / 1e7), n = Math.floor(e / 1e5) % 100, a = Math.floor(e / 1e3) % 100, r = e % 1e3, s = [];
2663
- return t && s.push((t <= 999 ? Tt(t) : An(t)) + " Crore"), n && s.push(et(n) + " Lakh"), a && s.push(et(a) + " Thousand"), r && s.push(Tt(r)), s.join(" ");
2664
- }, _r = {
2667
+ return t && s.push((t <= 999 ? Ft(t) : An(t)) + " Crore"), n && s.push(tt(n) + " Lakh"), a && s.push(tt(a) + " Thousand"), r && s.push(Ft(r)), s.join(" ");
2668
+ }, Hr = {
2665
2669
  id: "tools.numToWords",
2666
2670
  group: "tools",
2667
2671
  title: "Number to Words",
@@ -2683,15 +2687,15 @@ const Pr = {
2683
2687
  ],
2684
2688
  compute(e, t) {
2685
2689
  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";
2686
- let y = r === "western" ? An(l) : Br(l);
2687
- return c > 0 && (y += ` and ${et(c)} ${f}`), s && (y = `${h} ${y} Only`), m && (y = `Minus ${y}`), {
2690
+ let y = r === "western" ? An(l) : _r(l);
2691
+ return c > 0 && (y += ` and ${tt(c)} ${f}`), s && (y = `${h} ${y} Only`), m && (y = `Minus ${y}`), {
2688
2692
  primary: v("In words", y, "accent"),
2689
2693
  secondary: [v("In figures", a.num(u, c > 0 ? 2 : 0))],
2690
2694
  notes: ['Words are Title Case with the chosen number scale; the cheque format adds the currency name and "Only".'],
2691
2695
  raw: { words: y, integer: l, fraction: c }
2692
2696
  };
2693
2697
  }
2694
- }, Hr = [Lr, Ur, _r], qr = [
2698
+ }, qr = [Ur, Or, Hr], Gr = [
2695
2699
  {
2696
2700
  id: "tools.scientific",
2697
2701
  group: "tools",
@@ -2702,7 +2706,7 @@ const Pr = {
2702
2706
  compute: () => ({ primary: { label: "Scientific calculator", value: "" } }),
2703
2707
  custom: "scientific"
2704
2708
  }
2705
- ], Gr = {
2709
+ ], jr = {
2706
2710
  id: "loan.emi",
2707
2711
  group: "loans",
2708
2712
  title: "EMI / Loan",
@@ -2711,7 +2715,7 @@ const Pr = {
2711
2715
  inputs: [],
2712
2716
  compute: () => ({ primary: { label: "", value: "" } }),
2713
2717
  custom: "loan.emi"
2714
- }, jr = {
2718
+ }, Vr = {
2715
2719
  id: "tools.currency",
2716
2720
  group: "tools",
2717
2721
  title: "Currency converter",
@@ -2720,49 +2724,49 @@ const Pr = {
2720
2724
  inputs: [],
2721
2725
  compute: () => ({ primary: { label: "", value: "" } }),
2722
2726
  custom: "currency"
2723
- }, Vr = [
2724
- Gr,
2727
+ }, Yr = [
2725
2728
  jr,
2726
- ...Ha,
2727
- ...Ja,
2728
- ...ar,
2729
- ...sr,
2730
- ...vr,
2731
- ...Ar,
2732
- ...Hr,
2733
- ...qr
2734
- ], Ft = [];
2729
+ Vr,
2730
+ ...qa,
2731
+ ...Za,
2732
+ ...rr,
2733
+ ...lr,
2734
+ ...kr,
2735
+ ...Dr,
2736
+ ...qr,
2737
+ ...Gr
2738
+ ], It = [];
2735
2739
  function hs(e) {
2736
- Ft.some((t) => t.id === e.id) || Ft.push(e);
2740
+ It.some((t) => t.id === e.id) || It.push(e);
2737
2741
  }
2738
2742
  function Dn() {
2739
- return [...Vr, ...Ft];
2743
+ return [...Yr, ...It];
2740
2744
  }
2741
- function Yr(e) {
2745
+ function Kr(e) {
2742
2746
  return Dn().filter((t) => !t.regions || t.regions.includes(e));
2743
2747
  }
2744
- function It(e) {
2748
+ function Rt(e) {
2745
2749
  return Dn().find((t) => t.id === e);
2746
2750
  }
2747
- const Kr = [
2751
+ const Wr = [
2748
2752
  { id: "loans", label: "Loans" },
2749
2753
  { id: "invest", label: "Invest" },
2750
2754
  { id: "returns", label: "Returns" },
2751
2755
  { id: "tax", label: "Tax" },
2752
2756
  { id: "tools", label: "Tools" }
2753
2757
  ];
2754
- function Wr(e, t) {
2758
+ function zr(e, t) {
2755
2759
  var n;
2756
2760
  return ((n = e.labelByRegion) == null ? void 0 : n[t]) ?? e.label;
2757
2761
  }
2758
- function zr({
2762
+ function Jr({
2759
2763
  f: e,
2760
2764
  value: t,
2761
2765
  onChange: n,
2762
2766
  values: a
2763
2767
  }) {
2764
2768
  var i, c;
2765
- const { settings: r } = ue(), s = r.region, u = Wr(e, s), m = r.currency.symbol, d = t == null ? "" : String(t);
2769
+ const { settings: r } = ue(), s = r.region, u = zr(e, s), m = r.currency.symbol, d = t == null ? "" : String(t);
2766
2770
  switch (e.kind) {
2767
2771
  case "money":
2768
2772
  case "number":
@@ -2800,7 +2804,7 @@ function zr({
2800
2804
  ] })
2801
2805
  ] });
2802
2806
  case "tenure":
2803
- return /* @__PURE__ */ o(Jr, { f: e, label: u, months: Number(t) || 0, onChange: n });
2807
+ return /* @__PURE__ */ o(Zr, { f: e, label: u, months: Number(t) || 0, onChange: n });
2804
2808
  case "select":
2805
2809
  return /* @__PURE__ */ b("label", { className: "field", children: [
2806
2810
  /* @__PURE__ */ o("span", { className: "lbl", children: u }),
@@ -2838,12 +2842,12 @@ function zr({
2838
2842
  /* @__PURE__ */ o("div", { className: "input-wrap", children: /* @__PURE__ */ o("input", { value: d, placeholder: e.help, onChange: (l) => n(l.target.value), "aria-label": u }) })
2839
2843
  ] });
2840
2844
  case "cashflows":
2841
- return /* @__PURE__ */ o(Zr, { f: e, label: u, value: t ?? [], onChange: n });
2845
+ return /* @__PURE__ */ o(Xr, { f: e, label: u, value: t ?? [], onChange: n });
2842
2846
  default:
2843
2847
  return null;
2844
2848
  }
2845
2849
  }
2846
- function Jr({
2850
+ function Zr({
2847
2851
  f: e,
2848
2852
  label: t,
2849
2853
  months: n,
@@ -2883,7 +2887,7 @@ function Jr({
2883
2887
  e.suffix && /* @__PURE__ */ o("div", { className: "solved-note", children: e.suffix })
2884
2888
  ] });
2885
2889
  }
2886
- function Zr({
2890
+ function Xr({
2887
2891
  label: e,
2888
2892
  value: t,
2889
2893
  onChange: n
@@ -2914,7 +2918,7 @@ const Ln = {
2914
2918
  negative: "neg-txt",
2915
2919
  default: ""
2916
2920
  };
2917
- function Xr({ view: e }) {
2921
+ function Qr({ view: e }) {
2918
2922
  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);
2919
2923
  return /* @__PURE__ */ b("div", { className: "result", "aria-live": "polite", children: [
2920
2924
  /* @__PURE__ */ o("div", { className: "label", children: e.primary.label }),
@@ -2927,18 +2931,18 @@ function Xr({ view: e }) {
2927
2931
  ] })
2928
2932
  ] }),
2929
2933
  e.primary.sub && /* @__PURE__ */ o("div", { className: "per", children: e.primary.sub }),
2930
- e.split && e.split.length > 0 && /* @__PURE__ */ o(eo, { split: e.split }),
2931
- e.secondary && e.secondary.length > 0 && /* @__PURE__ */ o("div", { className: "secondary", children: e.secondary.map((m, d) => /* @__PURE__ */ o(Qr, { m }, d)) })
2934
+ e.split && e.split.length > 0 && /* @__PURE__ */ o(to, { split: e.split }),
2935
+ e.secondary && e.secondary.length > 0 && /* @__PURE__ */ o("div", { className: "secondary", children: e.secondary.map((m, d) => /* @__PURE__ */ o(eo, { m }, d)) })
2932
2936
  ] });
2933
2937
  }
2934
- function Qr({ m: e }) {
2938
+ function eo({ m: e }) {
2935
2939
  return /* @__PURE__ */ b("div", { className: "kv", children: [
2936
2940
  /* @__PURE__ */ o("div", { className: "k", children: e.label }),
2937
2941
  /* @__PURE__ */ o("div", { className: `v num ${Ln[e.tone ?? "default"]}`, children: e.value }),
2938
2942
  e.sub && /* @__PURE__ */ o("div", { className: "k", children: e.sub })
2939
2943
  ] });
2940
2944
  }
2941
- function eo({ split: e }) {
2945
+ function to({ split: e }) {
2942
2946
  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));
2943
2947
  return /* @__PURE__ */ b(re, { children: [
2944
2948
  /* @__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)) }),
@@ -2951,7 +2955,7 @@ function eo({ split: e }) {
2951
2955
  ] }, r)) })
2952
2956
  ] });
2953
2957
  }
2954
- function to({ schedule: e }) {
2958
+ function no({ schedule: e }) {
2955
2959
  var u;
2956
2960
  const [t, n] = M(/* @__PURE__ */ new Set([0])), a = (m) => {
2957
2961
  var d;
@@ -2993,7 +2997,7 @@ const zt = {
2993
2997
  interest: "var(--fc-interest)",
2994
2998
  accent: "var(--fc-accent)"
2995
2999
  };
2996
- function no({ chart: e }) {
3000
+ function ao({ chart: e }) {
2997
3001
  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`;
2998
3002
  return /* @__PURE__ */ b("div", { className: "chart", children: [
2999
3003
  /* @__PURE__ */ b("svg", { viewBox: "0 0 720 260", role: "img", "aria-label": "Projection chart", children: [
@@ -3009,7 +3013,7 @@ function no({ chart: e }) {
3009
3013
  ] }, f)) })
3010
3014
  ] });
3011
3015
  }
3012
- const Un = 1, ao = [
3016
+ const Un = 1, ro = [
3013
3017
  { id: "csv", label: "CSV (.csv)" },
3014
3018
  { id: "tsv", label: "TSV (.tsv)" },
3015
3019
  { id: "json", label: "JSON (.json)" },
@@ -3021,7 +3025,7 @@ const Un = 1, ao = [
3021
3025
  { id: "xlsx", label: "Excel (.xlsx)" },
3022
3026
  { id: "qr", label: "QR / share link" }
3023
3027
  ], Ot = () => typeof document < "u";
3024
- function Ee(e) {
3028
+ function Re(e) {
3025
3029
  const t = e.result, n = [[t.primary.label, t.primary.value]];
3026
3030
  t.primary.sub && n.push([`${t.primary.label} (note)`, t.primary.sub]);
3027
3031
  for (const a of t.secondary ?? []) n.push([a.label, a.value]);
@@ -3038,7 +3042,7 @@ function _e(e) {
3038
3042
  for (const n of e.rows) t.push([n.label, ...n.cells]);
3039
3043
  return { header: e.columns, rows: t };
3040
3044
  }
3041
- function ro(e) {
3045
+ function oo(e) {
3042
3046
  var t;
3043
3047
  return e ? e.groups ? e.groups.reduce((n, a) => n + a.rows.length, 0) : ((t = e.rows) == null ? void 0 : t.length) ?? 0 : 0;
3044
3048
  }
@@ -3058,32 +3062,32 @@ function Se(e, t, n = "application/octet-stream") {
3058
3062
  URL.revokeObjectURL(r), s.remove();
3059
3063
  }, 0);
3060
3064
  }
3061
- function oo(e, t) {
3065
+ function io(e, t) {
3062
3066
  let n = e == null ? "" : String(e);
3063
3067
  return /^[=+\-@\t\r]/.test(n) && (n = `'${n}`), (n.includes(t) || n.includes('"') || n.includes(`
3064
3068
  `) || n.includes("\r")) && (n = `"${n.replace(/"/g, '""')}"`), n;
3065
3069
  }
3066
- function io(e) {
3070
+ function so(e) {
3067
3071
  var t;
3068
3072
  return ((t = e == null ? void 0 : e.numberFormat) == null ? void 0 : t.grouping) === "european" ? ";" : ",";
3069
3073
  }
3070
3074
  function On(e, t) {
3071
3075
  const n = [["ArthaGanaka export"], ["Calculator", e.title]];
3072
- for (const a of Ee(e)) n.push(a);
3076
+ for (const a of Re(e)) n.push(a);
3073
3077
  if (n.push([]), e.result.schedule) {
3074
3078
  const a = _e(e.result.schedule);
3075
3079
  n.push(a.header, ...a.rows);
3076
3080
  }
3077
- return n.map((a) => a.map((r) => oo(r, t)).join(t)).join(`\r
3081
+ return n.map((a) => a.map((r) => io(r, t)).join(t)).join(`\r
3078
3082
  `);
3079
3083
  }
3080
- function so(e) {
3081
- return On(e, io(e.settingsSnapshot));
3082
- }
3083
3084
  function lo(e) {
3085
+ return On(e, so(e.settingsSnapshot));
3086
+ }
3087
+ function co(e) {
3084
3088
  return On(e, " ");
3085
3089
  }
3086
- function co(e, t = Un) {
3090
+ function uo(e, t = Un) {
3087
3091
  return JSON.stringify(
3088
3092
  {
3089
3093
  schemaVersion: t,
@@ -3103,7 +3107,7 @@ function co(e, t = Un) {
3103
3107
  2
3104
3108
  );
3105
3109
  }
3106
- function uo(e) {
3110
+ function mo(e) {
3107
3111
  const t = new TextEncoder().encode(e);
3108
3112
  if (typeof btoa == "function") {
3109
3113
  let n = "";
@@ -3112,16 +3116,16 @@ function uo(e) {
3112
3116
  }
3113
3117
  return globalThis.Buffer.from(t).toString("base64");
3114
3118
  }
3115
- const mo = (e) => uo(e).replace(/\+/g, "-").replace(/\//g, "_").replace(/=+$/, "");
3119
+ const po = (e) => mo(e).replace(/\+/g, "-").replace(/\//g, "_").replace(/=+$/, "");
3116
3120
  function Bn(e, t) {
3117
- const n = mo(JSON.stringify({ id: e, values: t }));
3121
+ const n = po(JSON.stringify({ id: e, values: t }));
3118
3122
  return `#fincalc=${encodeURIComponent(e)}&s=${n}`;
3119
3123
  }
3120
3124
  const Ye = (e) => String(e ?? "").replace(/\|/g, "\\|").replace(/\n/g, " ");
3121
3125
  function Jt(e) {
3122
3126
  const t = [`# ${e.title}`, ""];
3123
3127
  t.push("| Metric | Value |", "| --- | --- |");
3124
- for (const [n, a] of Ee(e)) t.push(`| ${Ye(n)} | ${Ye(a)} |`);
3128
+ for (const [n, a] of Re(e)) t.push(`| ${Ye(n)} | ${Ye(a)} |`);
3125
3129
  if (e.result.schedule) {
3126
3130
  const n = _e(e.result.schedule);
3127
3131
  t.push("", `## ${e.result.schedule.title ?? "Schedule"}`, ""), t.push(`| ${n.header.map(Ye).join(" | ")} |`), t.push(`| ${n.header.map(() => "---").join(" | ")} |`);
@@ -3131,22 +3135,22 @@ function Jt(e) {
3131
3135
  `);
3132
3136
  }
3133
3137
  const Pe = (e) => String(e ?? "").replace(/[&<>"]/g, (t) => ({ "&": "&amp;", "<": "&lt;", ">": "&gt;", '"': "&quot;" })[t]);
3134
- function po(e) {
3135
- return `<table><tbody>${Ee(e).map(([n, a]) => `<tr><th>${Pe(n)}</th><td>${Pe(a)}</td></tr>`).join("")}</tbody></table>`;
3136
- }
3137
3138
  function ho(e) {
3139
+ return `<table><tbody>${Re(e).map(([n, a]) => `<tr><th>${Pe(n)}</th><td>${Pe(a)}</td></tr>`).join("")}</tbody></table>`;
3140
+ }
3141
+ function fo(e) {
3138
3142
  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("");
3139
3143
  return `<table><thead>${n}</thead><tbody>${a}</tbody></table>`;
3140
3144
  }
3141
3145
  function _n(e) {
3142
- const t = e.result.schedule ? `<h2>${Pe(e.result.schedule.title ?? "Schedule")}</h2>${ho(e.result.schedule)}` : "";
3143
- return `<h1>${Pe(e.title)}</h1>${po(e)}${t}<p class="fc-print-foot">Generated by ArthaGanaka · ${Pe(e.meta.computedAt)}</p>`;
3146
+ const t = e.result.schedule ? `<h2>${Pe(e.result.schedule.title ?? "Schedule")}</h2>${fo(e.result.schedule)}` : "";
3147
+ return `<h1>${Pe(e.title)}</h1>${ho(e)}${t}<p class="fc-print-foot">Generated by ArthaGanaka · ${Pe(e.meta.computedAt)}</p>`;
3144
3148
  }
3145
- 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")}`, fo = (e) => new Date(e || Date.now()).toISOString().replace(/[-:]/g, "").replace(/\.\d{3}Z$/, "Z"), yo = (e, t) => {
3149
+ 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")}`, yo = (e) => new Date(e || Date.now()).toISOString().replace(/[-:]/g, "").replace(/\.\d{3}Z$/, "Z"), bo = (e, t) => {
3146
3150
  const n = new Date(e);
3147
3151
  return n.setMonth(n.getMonth() + t), n;
3148
3152
  };
3149
- function bo(e) {
3153
+ function go(e) {
3150
3154
  for (const t of Object.values(e))
3151
3155
  if (typeof t == "string" && /^\d{4}-\d{2}-\d{2}/.test(t)) {
3152
3156
  const n = new Date(t);
@@ -3154,12 +3158,12 @@ function bo(e) {
3154
3158
  }
3155
3159
  return /* @__PURE__ */ new Date();
3156
3160
  }
3157
- function go(e) {
3158
- const t = ro(e.result.schedule);
3161
+ function vo(e) {
3162
+ const t = oo(e.result.schedule);
3159
3163
  if (!t) throw new Error("This calculator has no instalment schedule to put on a calendar.");
3160
- const n = bo(e.values), a = t <= 60, r = a ? t : Math.ceil(t / 12), s = fo(e.meta.computedAt), u = ["BEGIN:VCALENDAR", "VERSION:2.0", "PRODID:-//ArthaGanaka//Export//EN", "CALSCALE:GREGORIAN"];
3164
+ const n = go(e.values), a = t <= 60, r = a ? t : Math.ceil(t / 12), s = yo(e.meta.computedAt), u = ["BEGIN:VCALENDAR", "VERSION:2.0", "PRODID:-//ArthaGanaka//Export//EN", "CALSCALE:GREGORIAN"];
3161
3165
  for (let m = 0; m < r; m++) {
3162
- const d = yo(n, a ? m + 1 : (m + 1) * 12), i = a ? `instalment ${m + 1}` : `year ${m + 1}`;
3166
+ const d = bo(n, a ? m + 1 : (m + 1) * 12), i = a ? `instalment ${m + 1}` : `year ${m + 1}`;
3163
3167
  u.push(
3164
3168
  "BEGIN:VEVENT",
3165
3169
  `UID:${Zt(e.calculatorId)}-${m + 1}-${Xt(d)}@arthaganaka`,
@@ -3178,7 +3182,7 @@ async function Hn(e) {
3178
3182
  if ((n = t == null ? void 0 : t.clipboard) != null && n.writeText) return t.clipboard.writeText(e);
3179
3183
  throw new Error("Clipboard is not available in this browser.");
3180
3184
  }
3181
- async function vo(e, t) {
3185
+ async function ko(e, t) {
3182
3186
  var a;
3183
3187
  const n = typeof navigator < "u" ? navigator : void 0;
3184
3188
  if ((a = n == null ? void 0 : n.clipboard) != null && a.write && typeof ClipboardItem < "u" && typeof Blob < "u")
@@ -3194,7 +3198,7 @@ async function vo(e, t) {
3194
3198
  }
3195
3199
  await Hn(t);
3196
3200
  }
3197
- function ko(e) {
3201
+ function wo(e) {
3198
3202
  if (!Ot() || typeof window > "u") throw new Error("Print is only available in the browser.");
3199
3203
  const t = document.createElement("div");
3200
3204
  t.className = "fc-print-root", t.innerHTML = _n(e), document.body.appendChild(t), document.body.classList.add("fc-printing");
@@ -3203,9 +3207,9 @@ function ko(e) {
3203
3207
  };
3204
3208
  window.addEventListener("afterprint", n), window.print(), setTimeout(n, 1500);
3205
3209
  }
3206
- function wo(e, t = 2) {
3210
+ function No(e, t = 2) {
3207
3211
  if (!Ot()) return Promise.reject(new Error("PNG export is only available in the browser."));
3208
- const n = Ee(e), a = 620, r = 120 + n.length * 30 + 30, s = document.createElement("canvas");
3212
+ const n = Re(e), a = 620, r = 120 + n.length * 30 + 30, s = document.createElement("canvas");
3209
3213
  s.width = a * t, s.height = r * t;
3210
3214
  const u = s.getContext("2d");
3211
3215
  if (!u) return Promise.reject(new Error("Canvas is not available."));
@@ -3220,7 +3224,7 @@ function wo(e, t = 2) {
3220
3224
  (i, c) => s.toBlob((l) => l ? i(l) : c(new Error("Could not render PNG.")), "image/png")
3221
3225
  );
3222
3226
  }
3223
- async function No(e) {
3227
+ async function xo(e) {
3224
3228
  let t;
3225
3229
  try {
3226
3230
  t = await import(
@@ -3235,7 +3239,7 @@ async function No(e) {
3235
3239
  const a = new n({ unit: "pt", format: "a4" });
3236
3240
  let r = 48;
3237
3241
  a.setFontSize(18), a.text(e.title, 48, r), r += 26, a.setFontSize(11);
3238
- for (const [u, m] of Ee(e))
3242
+ for (const [u, m] of Re(e))
3239
3243
  a.text(`${u}: ${m}`, 48, r), r += 18;
3240
3244
  if (e.result.schedule) {
3241
3245
  const u = _e(e.result.schedule);
@@ -3246,7 +3250,7 @@ async function No(e) {
3246
3250
  const s = ve(e, "pdf");
3247
3251
  return a.save(s), { ok: !0, filename: s };
3248
3252
  }
3249
- async function xo(e) {
3253
+ async function So(e) {
3250
3254
  var i, c;
3251
3255
  let t;
3252
3256
  try {
@@ -3259,7 +3263,7 @@ async function xo(e) {
3259
3263
  }
3260
3264
  const n = t.utils ?? ((i = t.default) == null ? void 0 : i.utils), a = t.write ?? ((c = t.default) == null ? void 0 : c.write);
3261
3265
  if (!n || !a) throw new Error('Excel export needs the optional "xlsx" package.');
3262
- const r = [["Calculator", e.title], ...Ee(e), []];
3266
+ const r = [["Calculator", e.title], ...Re(e), []];
3263
3267
  if (e.result.schedule) {
3264
3268
  const l = _e(e.result.schedule);
3265
3269
  r.push(l.header, ...l.rows);
@@ -3273,7 +3277,7 @@ function qn(e) {
3273
3277
  const t = Bn(e.calculatorId, e.values);
3274
3278
  return (typeof location < "u" ? location.origin + location.pathname : "") + t;
3275
3279
  }
3276
- async function So(e) {
3280
+ async function Co(e) {
3277
3281
  const t = Bn(e.calculatorId, e.values), n = qn(e);
3278
3282
  if (typeof location < "u")
3279
3283
  try {
@@ -3287,26 +3291,26 @@ async function So(e) {
3287
3291
  return { ok: !0, data: n, note: `${a}Link is in the address bar — copy it from there.` };
3288
3292
  }
3289
3293
  }
3290
- function Co(e) {
3294
+ function Po(e) {
3291
3295
  return {
3292
3296
  ok: !0,
3293
3297
  data: qn(e),
3294
3298
  note: "A QR image needs an optional QR library — share this link instead."
3295
3299
  };
3296
3300
  }
3297
- function Po(e = {}) {
3301
+ function To(e = {}) {
3298
3302
  const t = e.schemaVersion ?? Un, n = {
3299
3303
  csv: (a) => {
3300
3304
  const r = ve(a, "csv");
3301
- return Se(r, so(a), "text/csv;charset=utf-8"), { ok: !0, filename: r };
3305
+ return Se(r, lo(a), "text/csv;charset=utf-8"), { ok: !0, filename: r };
3302
3306
  },
3303
3307
  tsv: (a) => {
3304
3308
  const r = ve(a, "tsv");
3305
- return Se(r, lo(a), "text/tab-separated-values;charset=utf-8"), { ok: !0, filename: r };
3309
+ return Se(r, co(a), "text/tab-separated-values;charset=utf-8"), { ok: !0, filename: r };
3306
3310
  },
3307
3311
  json: (a) => {
3308
3312
  const r = ve(a, "json");
3309
- return Se(r, co(a, t), "application/json"), { ok: !0, filename: r };
3313
+ return Se(r, uo(a, t), "application/json"), { ok: !0, filename: r };
3310
3314
  },
3311
3315
  markdown: (a) => {
3312
3316
  const r = ve(a, "md");
@@ -3314,18 +3318,18 @@ function Po(e = {}) {
3314
3318
  },
3315
3319
  ics: (a) => {
3316
3320
  const r = ve(a, "ics");
3317
- return Se(r, go(a), "text/calendar;charset=utf-8"), { ok: !0, filename: r };
3321
+ return Se(r, vo(a), "text/calendar;charset=utf-8"), { ok: !0, filename: r };
3318
3322
  },
3319
- clipboard: async (a) => (await vo(_n(a), Jt(a)), { ok: !0, note: "Copied table to clipboard." }),
3320
- print: (a) => (ko(a), { ok: !0 }),
3321
- url: (a) => So(a),
3322
- qr: (a) => Co(a),
3323
+ clipboard: async (a) => (await ko(_n(a), Jt(a)), { ok: !0, note: "Copied table to clipboard." }),
3324
+ print: (a) => (wo(a), { ok: !0 }),
3325
+ url: (a) => Co(a),
3326
+ qr: (a) => Po(a),
3323
3327
  png: async (a, r) => {
3324
3328
  const s = ve(a, "png");
3325
- return Se(s, await wo(a, r.scale ?? 2)), { ok: !0, filename: s };
3329
+ return Se(s, await No(a, r.scale ?? 2)), { ok: !0, filename: s };
3326
3330
  },
3327
- pdf: (a) => No(a),
3328
- xlsx: (a) => xo(a)
3331
+ pdf: (a) => xo(a),
3332
+ xlsx: (a) => So(a)
3329
3333
  };
3330
3334
  return {
3331
3335
  formats: Object.keys(n),
@@ -3336,7 +3340,7 @@ function Po(e = {}) {
3336
3340
  };
3337
3341
  }
3338
3342
  function Gn({ payload: e }) {
3339
- const t = ne(() => Po(), []), [n, a] = M(!1), [r, s] = M(null), u = de(null), m = de(null), d = de([]);
3343
+ const t = ne(() => To(), []), [n, a] = M(!1), [r, s] = M(null), u = de(null), m = de(null), d = de([]);
3340
3344
  X(() => {
3341
3345
  if (!r) return;
3342
3346
  const p = setTimeout(() => s(null), 4500);
@@ -3404,7 +3408,7 @@ function Gn({ payload: e }) {
3404
3408
  }
3405
3409
  )
3406
3410
  ] }),
3407
- n && /* @__PURE__ */ o("div", { ref: m, className: "menu-list", role: "menu", "aria-label": "Export as", children: ao.map((p, h) => /* @__PURE__ */ o(
3411
+ n && /* @__PURE__ */ o("div", { ref: m, className: "menu-list", role: "menu", "aria-label": "Export as", children: ro.map((p, h) => /* @__PURE__ */ o(
3408
3412
  "button",
3409
3413
  {
3410
3414
  type: "button",
@@ -3421,7 +3425,7 @@ function Gn({ payload: e }) {
3421
3425
  r && /* @__PURE__ */ o("div", { className: `export-toast ${r.kind}`, role: "status", "aria-live": "polite", children: r.msg })
3422
3426
  ] });
3423
3427
  }
3424
- const Bt = "calcsuite:history", To = 100, Fo = [];
3428
+ const Bt = "calcsuite:history", Fo = 100, Io = [];
3425
3429
  let Ce = null;
3426
3430
  const ze = /* @__PURE__ */ new Set();
3427
3431
  function jn() {
@@ -3442,19 +3446,19 @@ function Vn(e) {
3442
3446
  ze.forEach((t) => t());
3443
3447
  }
3444
3448
  let Qt = !1;
3445
- function Io(e) {
3449
+ function Ro(e) {
3446
3450
  return ze.add(e), !Qt && typeof window < "u" && (Qt = !0, window.addEventListener("storage", (t) => {
3447
3451
  t.key === Bt && (Ce = null, ze.forEach((n) => n()));
3448
3452
  })), () => ze.delete(e);
3449
3453
  }
3450
3454
  function Yn(e) {
3451
- Vn([{ ...e, at: Date.now() }, ...jn()].slice(0, To));
3455
+ Vn([{ ...e, at: Date.now() }, ...jn()].slice(0, Fo));
3452
3456
  }
3453
3457
  function Eo() {
3454
3458
  Vn([]);
3455
3459
  }
3456
- function Ro() {
3457
- const e = fa(Io, jn, () => Fo), t = ke((a) => Yn(a), []), n = ke(() => Eo(), []);
3460
+ function Mo() {
3461
+ const e = ya(Ro, jn, () => Io), t = ke((a) => Yn(a), []), n = ke(() => Eo(), []);
3458
3462
  return { items: e, save: t, clear: n };
3459
3463
  }
3460
3464
  function Kn({ item: e }) {
@@ -3463,9 +3467,9 @@ function Kn({ item: e }) {
3463
3467
  Yn(e), n(!0), clearTimeout(a.current), a.current = setTimeout(() => n(!1), 1500);
3464
3468
  }, "aria-live": "polite", children: t ? "Saved ✓" : "Save" });
3465
3469
  }
3466
- const Mo = { payment: "Payment", principal: "Amount", rate: "Rate", tenure: "Term" };
3470
+ const $o = { payment: "Payment", principal: "Amount", rate: "Rate", tenure: "Term" };
3467
3471
  function Wn() {
3468
- 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 = (E) => E.replace(/[, ]/g, "").trim(), { result: T, error: $ } = ne(() => {
3472
+ 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: $ } = ne(() => {
3469
3473
  try {
3470
3474
  return { result: Ie({
3471
3475
  region: n,
@@ -3475,14 +3479,14 @@ function Wn() {
3475
3479
  tenureMonths: r === "tenure" ? void 0 : P || void 0,
3476
3480
  payment: r === "payment" ? void 0 : x(w) || void 0
3477
3481
  }), error: null };
3478
- } catch (E) {
3479
- return { result: null, error: E instanceof se ? E.message : "Could not calculate." };
3482
+ } catch (R) {
3483
+ return { result: null, error: R instanceof se ? R.message : "Could not calculate." };
3480
3484
  }
3481
- }, [n, u, r, d, c, p, f, w, P]), L = (E) => r === E, B = {
3485
+ }, [n, u, r, d, c, p, f, w, P]), L = (R) => r === R, B = {
3482
3486
  payment: T ? t.money(T.payment) : "—",
3483
3487
  principal: T ? t.money(T.principal) : "—",
3484
3488
  rate: T ? `${t.num(T.annualRatePct, 3)} %` : "—",
3485
- tenure: T ? dt(T.tenureMonths) : "—"
3489
+ tenure: T ? mt(T.tenureMonths) : "—"
3486
3490
  }, G = T ? t.moneyParts(T.payment) : { symbol: "", digits: "—" }, q = e.currency.symbol, A = {
3487
3491
  region: n,
3488
3492
  basis: u,
@@ -3491,10 +3495,10 @@ function Wn() {
3491
3495
  tenureMonths: String(P),
3492
3496
  payment: x(w),
3493
3497
  solveFor: r
3494
- }, I = (E) => {
3498
+ }, I = (R) => {
3495
3499
  const j = {
3496
3500
  columns: ["Period", "Opening", "Payment", "Principal", "Interest", "Balance"],
3497
- groups: E.byYear.map((Y) => ({
3501
+ groups: R.byYear.map((Y) => ({
3498
3502
  label: `Year ${Y.year}`,
3499
3503
  summary: [
3500
3504
  t.money(Y.months[0].openingBalance),
@@ -3517,22 +3521,22 @@ function Wn() {
3517
3521
  toneCols: { 3: "principal", 4: "interest" }
3518
3522
  };
3519
3523
  return {
3520
- primary: { label: a.paymentLabel, value: t.money(E.payment) },
3524
+ primary: { label: a.paymentLabel, value: t.money(R.payment) },
3521
3525
  primaryPer: "/month",
3522
3526
  secondary: [
3523
- { label: "Principal", value: t.money(E.principal) },
3524
- { label: "Total interest", value: t.money(E.totalInterest), tone: "interest" },
3525
- { label: "Total payment", value: t.money(E.totalPayment) },
3526
- { label: a.tenureWord, value: dt(E.tenureMonths) }
3527
+ { label: "Principal", value: t.money(R.principal) },
3528
+ { label: "Total interest", value: t.money(R.totalInterest), tone: "interest" },
3529
+ { label: "Total payment", value: t.money(R.totalPayment) },
3530
+ { label: a.tenureWord, value: mt(R.tenureMonths) }
3527
3531
  ],
3528
3532
  schedule: j,
3529
- formula: E.formula,
3533
+ formula: R.formula,
3530
3534
  raw: {
3531
- payment: E.payment.toString(),
3532
- principal: E.principal.toString(),
3533
- totalInterest: E.totalInterest.toString(),
3534
- totalPayment: E.totalPayment.toString(),
3535
- tenureMonths: E.tenureMonths
3535
+ payment: R.payment.toString(),
3536
+ principal: R.principal.toString(),
3537
+ totalInterest: R.totalInterest.toString(),
3538
+ totalPayment: R.totalPayment.toString(),
3539
+ tenureMonths: R.tenureMonths
3536
3540
  }
3537
3541
  };
3538
3542
  };
@@ -3540,7 +3544,7 @@ function Wn() {
3540
3544
  /* @__PURE__ */ b("section", { className: "card", children: [
3541
3545
  /* @__PURE__ */ b("div", { className: "solve-row", children: [
3542
3546
  /* @__PURE__ */ o("span", { className: "lbl", children: "Solve for" }),
3543
- /* @__PURE__ */ o("div", { className: "seg", role: "group", "aria-label": "Solve for", children: N.map((E) => /* @__PURE__ */ o("button", { "aria-pressed": r === E, onClick: () => s(E), children: Mo[E] }, E)) })
3547
+ /* @__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: $o[R] }, R)) })
3544
3548
  ] }),
3545
3549
  /* @__PURE__ */ b("div", { className: "field", style: { marginBottom: "calc(var(--fc-space) * 2)" }, children: [
3546
3550
  /* @__PURE__ */ o("span", { className: "lbl", children: "Interest basis" }),
@@ -3559,8 +3563,8 @@ function Wn() {
3559
3563
  ] })
3560
3564
  ] }),
3561
3565
  /* @__PURE__ */ b("div", { className: "grid two", children: [
3562
- /* @__PURE__ */ o(ft, { label: "Loan amount", solved: L("principal"), solvedText: B.principal, affix: q, children: /* @__PURE__ */ o("input", { className: "num", inputMode: "decimal", value: d, onChange: (E) => i(E.target.value), "aria-label": "Loan amount" }) }),
3563
- /* @__PURE__ */ o(ft, { label: "Interest rate", solved: L("rate"), solvedText: B.rate, suffix: "% p.a.", children: /* @__PURE__ */ o("input", { className: "num", inputMode: "decimal", value: c, onChange: (E) => l(E.target.value), "aria-label": "Interest rate" }) }),
3566
+ /* @__PURE__ */ o(yt, { label: "Loan amount", solved: L("principal"), solvedText: B.principal, affix: q, children: /* @__PURE__ */ o("input", { className: "num", inputMode: "decimal", value: d, onChange: (R) => i(R.target.value), "aria-label": "Loan amount" }) }),
3567
+ /* @__PURE__ */ o(yt, { label: "Interest rate", solved: L("rate"), solvedText: B.rate, suffix: "% p.a.", children: /* @__PURE__ */ o("input", { className: "num", inputMode: "decimal", value: c, onChange: (R) => l(R.target.value), "aria-label": "Interest rate" }) }),
3564
3568
  /* @__PURE__ */ b("div", { className: "field", children: [
3565
3569
  /* @__PURE__ */ o("span", { className: "lbl", children: a.tenureWord }),
3566
3570
  L("tenure") ? /* @__PURE__ */ b(re, { children: [
@@ -3568,16 +3572,16 @@ function Wn() {
3568
3572
  /* @__PURE__ */ o("div", { className: "solved-note", children: "solved" })
3569
3573
  ] }) : /* @__PURE__ */ b("div", { className: "tenure-pair", children: [
3570
3574
  /* @__PURE__ */ b("div", { className: "input-wrap", children: [
3571
- /* @__PURE__ */ o("input", { className: "num", inputMode: "numeric", value: p, onChange: (E) => h(E.target.value), "aria-label": "Years" }),
3575
+ /* @__PURE__ */ o("input", { className: "num", inputMode: "numeric", value: p, onChange: (R) => h(R.target.value), "aria-label": "Years" }),
3572
3576
  /* @__PURE__ */ o("span", { className: "affix", children: "yr" })
3573
3577
  ] }),
3574
3578
  /* @__PURE__ */ b("div", { className: "input-wrap", children: [
3575
- /* @__PURE__ */ o("input", { className: "num", inputMode: "numeric", value: f, onChange: (E) => y(E.target.value), "aria-label": "Months" }),
3579
+ /* @__PURE__ */ o("input", { className: "num", inputMode: "numeric", value: f, onChange: (R) => y(R.target.value), "aria-label": "Months" }),
3576
3580
  /* @__PURE__ */ o("span", { className: "affix", children: "mo" })
3577
3581
  ] })
3578
3582
  ] })
3579
3583
  ] }),
3580
- /* @__PURE__ */ o(ft, { label: a.paymentLabel, solved: L("payment"), solvedText: B.payment, affix: q, children: /* @__PURE__ */ o("input", { className: "num", inputMode: "decimal", value: w, onChange: (E) => k(E.target.value), "aria-label": a.paymentLabel }) })
3584
+ /* @__PURE__ */ o(yt, { label: a.paymentLabel, solved: L("payment"), solvedText: B.payment, affix: q, children: /* @__PURE__ */ o("input", { className: "num", inputMode: "decimal", value: w, onChange: (R) => k(R.target.value), "aria-label": a.paymentLabel }) })
3581
3585
  ] }),
3582
3586
  $ && /* @__PURE__ */ o("div", { className: "error", role: "alert", style: { marginTop: 16 }, children: $ })
3583
3587
  ] }),
@@ -3594,7 +3598,7 @@ function Wn() {
3594
3598
  /* @__PURE__ */ o("span", { className: "per", children: " /month" })
3595
3599
  ] })
3596
3600
  ] }),
3597
- /* @__PURE__ */ o($o, { result: T }),
3601
+ /* @__PURE__ */ o(Ao, { result: T }),
3598
3602
  /* @__PURE__ */ b("div", { className: "secondary", children: [
3599
3603
  /* @__PURE__ */ b("div", { className: "kv", children: [
3600
3604
  /* @__PURE__ */ o("div", { className: "k", children: "Principal" }),
@@ -3610,7 +3614,7 @@ function Wn() {
3610
3614
  ] }),
3611
3615
  /* @__PURE__ */ b("div", { className: "kv", children: [
3612
3616
  /* @__PURE__ */ o("div", { className: "k", children: a.tenureWord }),
3613
- /* @__PURE__ */ o("div", { className: "v num", children: dt(T.tenureMonths) })
3617
+ /* @__PURE__ */ o("div", { className: "v num", children: mt(T.tenureMonths) })
3614
3618
  ] })
3615
3619
  ] }),
3616
3620
  /* @__PURE__ */ b("div", { className: "actions-row", children: [
@@ -3653,8 +3657,8 @@ function Wn() {
3653
3657
  e.ui.showFormulas && /* @__PURE__ */ o("button", { role: "tab", "aria-selected": S === "formula", onClick: () => F("formula"), children: "Formula" })
3654
3658
  ] }),
3655
3659
  /* @__PURE__ */ b("div", { className: "tab-anim", children: [
3656
- S === "schedule" && /* @__PURE__ */ o(Ao, { result: T }),
3657
- S === "chart" && /* @__PURE__ */ o(Do, { result: T }),
3660
+ S === "schedule" && /* @__PURE__ */ o(Do, { result: T }),
3661
+ S === "chart" && /* @__PURE__ */ o(Lo, { result: T }),
3658
3662
  S === "formula" && e.ui.showFormulas && /* @__PURE__ */ b("div", { className: "formula", children: [
3659
3663
  /* @__PURE__ */ o("code", { children: T.formula }),
3660
3664
  /* @__PURE__ */ b("div", { className: "assumptions", children: [
@@ -3679,7 +3683,7 @@ function Wn() {
3679
3683
  ] })
3680
3684
  ] });
3681
3685
  }
3682
- function ft({
3686
+ function yt({
3683
3687
  label: e,
3684
3688
  solved: t,
3685
3689
  solvedText: n,
@@ -3699,7 +3703,7 @@ function ft({
3699
3703
  ] })
3700
3704
  ] });
3701
3705
  }
3702
- function $o({ result: e }) {
3706
+ function Ao({ result: e }) {
3703
3707
  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);
3704
3708
  return /* @__PURE__ */ b(re, { children: [
3705
3709
  /* @__PURE__ */ b("div", { className: "splitbar", role: "img", "aria-label": `Principal ${s}%, interest ${100 - s}%`, children: [
@@ -3724,7 +3728,7 @@ function $o({ result: e }) {
3724
3728
  ] })
3725
3729
  ] });
3726
3730
  }
3727
- function Ao({ result: e }) {
3731
+ function Do({ result: e }) {
3728
3732
  const { fmt: t } = ue(), [n, a] = M("yearly"), [r, s] = M(/* @__PURE__ */ new Set([1])), u = (d) => s((i) => {
3729
3733
  const c = new Set(i);
3730
3734
  return c.has(d) ? c.delete(d) : c.add(d), c;
@@ -3786,7 +3790,7 @@ function Ao({ result: e }) {
3786
3790
  ] }) })
3787
3791
  ] });
3788
3792
  }
3789
- function Do({ result: e }) {
3793
+ function Lo({ result: e }) {
3790
3794
  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`;
3791
3795
  return /* @__PURE__ */ b("div", { className: "chart", children: [
3792
3796
  /* @__PURE__ */ b("svg", { viewBox: `0 0 ${s} ${u}`, role: "img", "aria-label": "Balance and cumulative interest over the term", children: [
@@ -3809,7 +3813,7 @@ function Do({ result: e }) {
3809
3813
  ] })
3810
3814
  ] });
3811
3815
  }
3812
- const Lo = /* @__PURE__ */ new Set([
3816
+ const Uo = /* @__PURE__ */ new Set([
3813
3817
  "sin",
3814
3818
  "cos",
3815
3819
  "tan",
@@ -3846,7 +3850,7 @@ const Lo = /* @__PURE__ */ new Set([
3846
3850
  "sq",
3847
3851
  "cube",
3848
3852
  "recip"
3849
- ]), Uo = {
3853
+ ]), Oo = {
3850
3854
  arcsin: "asin",
3851
3855
  arccos: "acos",
3852
3856
  arctan: "atan",
@@ -3854,14 +3858,14 @@ const Lo = /* @__PURE__ */ new Set([
3854
3858
  log10: "log",
3855
3859
  ncr: "ncr",
3856
3860
  npr: "npr"
3857
- }, Oo = (e) => e === " " || e === " " || e === `
3858
- ` || 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"]), Bo = /* @__PURE__ */ new Set(["num", "const", "var", "rparen", "postfix"]);
3859
- function _o(e) {
3861
+ }, Bo = (e) => e === " " || e === " " || e === `
3862
+ ` || 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"]), _o = /* @__PURE__ */ new Set(["num", "const", "var", "rparen", "postfix"]);
3863
+ function Ho(e) {
3860
3864
  return e === "HEX" ? zn : e === "OCT" ? (t) => t >= "0" && t <= "7" : e === "BIN" ? (t) => t === "0" || t === "1" : fe;
3861
3865
  }
3862
- function Ho(e) {
3863
- const t = e.toLowerCase(), n = Uo[t] ?? t;
3864
- if (Lo.has(n)) return { type: "func", value: n };
3866
+ function qo(e) {
3867
+ const t = e.toLowerCase(), n = Oo[t] ?? t;
3868
+ if (Uo.has(n)) return { type: "func", value: n };
3865
3869
  if (t === "mod") return { type: "op", value: "mod" };
3866
3870
  if (t === "and") return { type: "op", value: "and" };
3867
3871
  if (t === "or") return { type: "op", value: "or" };
@@ -3878,12 +3882,12 @@ function Ho(e) {
3878
3882
  }
3879
3883
  throw new Error(`Unknown name: ${e}`);
3880
3884
  }
3881
- function qo(e, t = {}) {
3885
+ function Go(e, t = {}) {
3882
3886
  const n = t.base ?? "DEC", a = e, r = [];
3883
3887
  let s = 0;
3884
3888
  for (; s < a.length; ) {
3885
3889
  const d = a[s];
3886
- if (Oo(d)) {
3890
+ if (Bo(d)) {
3887
3891
  s++;
3888
3892
  continue;
3889
3893
  }
@@ -3898,7 +3902,7 @@ function qo(e, t = {}) {
3898
3902
  continue;
3899
3903
  }
3900
3904
  if (n !== "DEC") {
3901
- const l = _o(n);
3905
+ const l = Ho(n);
3902
3906
  let p = s;
3903
3907
  for (; p < a.length && l(a[p]); ) p++;
3904
3908
  const h = a.slice(s, p), f = n === "HEX" ? "0x" : n === "OCT" ? "0o" : "0b";
@@ -3922,7 +3926,7 @@ function qo(e, t = {}) {
3922
3926
  if (en(d) || d === "_") {
3923
3927
  let c = s;
3924
3928
  for (; c < a.length && (en(a[c]) || fe(a[c]) || a[c] === "_"); ) c++;
3925
- r.push(Ho(a.slice(s, c))), s = c;
3929
+ r.push(qo(a.slice(s, c))), s = c;
3926
3930
  continue;
3927
3931
  }
3928
3932
  const i = a.slice(s, s + 2);
@@ -4002,11 +4006,11 @@ function qo(e, t = {}) {
4002
4006
  }), m = [];
4003
4007
  for (let d = 0; d < u.length; d++) {
4004
4008
  const i = u[d], c = m[m.length - 1];
4005
- c && Bo.has(c.type) && tn.has(i.type) && m.push({ type: "op", value: "*", implicit: !0 }), m.push(i);
4009
+ c && _o.has(c.type) && tn.has(i.type) && m.push({ type: "op", value: "*", implicit: !0 }), m.push(i);
4006
4010
  }
4007
4011
  return m;
4008
4012
  }
4009
- const Go = {
4013
+ const jo = {
4010
4014
  or: { prec: 1 },
4011
4015
  xor: { prec: 2 },
4012
4016
  and: { prec: 3 },
@@ -4020,7 +4024,7 @@ const Go = {
4020
4024
  "%": { prec: 6 },
4021
4025
  "^": { prec: 8, right: !0 }
4022
4026
  }, nn = { neg: 7, bnot: 7, sqrt: 10, cbrt: 10, qdrt: 10 }, De = Symbol("arg");
4023
- function jo(e) {
4027
+ function Vo(e) {
4024
4028
  const t = [], n = [];
4025
4029
  let a = !0;
4026
4030
  const r = () => {
@@ -4071,7 +4075,7 @@ function jo(e) {
4071
4075
  else if (d.value !== "+") throw new Error(`Unexpected operator: ${d.value}`);
4072
4076
  a = !0;
4073
4077
  } else {
4074
- const i = Go[d.value];
4078
+ const i = jo[d.value];
4075
4079
  if (!i) throw new Error(`Unknown operator: ${d.value}`);
4076
4080
  for (; n.length; ) {
4077
4081
  const c = n[n.length - 1];
@@ -4112,11 +4116,11 @@ function jo(e) {
4112
4116
  if (m === De) throw new Error("Malformed expression");
4113
4117
  return m;
4114
4118
  }
4115
- const Vo = new H("3.141592653589793238462643383279502884197"), Yo = new H("2.718281828459045235360287471352662497757"), Ko = new H("1.618033988749894848204586834365638117720");
4116
- function yt(e, t) {
4119
+ const Yo = new H("3.141592653589793238462643383279502884197"), Ko = new H("2.718281828459045235360287471352662497757"), Wo = new H("1.618033988749894848204586834365638117720");
4120
+ function bt(e, t) {
4117
4121
  return t === "deg" ? e * Math.PI / 180 : t === "grad" ? e * Math.PI / 200 : e;
4118
4122
  }
4119
- function bt(e, t) {
4123
+ function gt(e, t) {
4120
4124
  return t === "deg" ? e * 180 / Math.PI : t === "grad" ? e * 200 / Math.PI : e;
4121
4125
  }
4122
4126
  function an(e) {
@@ -4126,13 +4130,13 @@ function an(e) {
4126
4130
  for (let n = 2; n <= e.toNumber(); n++) t = t.times(n);
4127
4131
  return t;
4128
4132
  }
4129
- function Wo(e, t) {
4133
+ function zo(e, t) {
4130
4134
  if (!e.isInteger() || !t.isInteger() || t.isNegative() || t.gt(e)) throw new Error("nPr domain");
4131
4135
  let n = g(1);
4132
4136
  for (let a = 0; a < t.toNumber(); a++) n = n.times(e.minus(a));
4133
4137
  return n;
4134
4138
  }
4135
- function zo(e, t) {
4139
+ function Jo(e, t) {
4136
4140
  if (!e.isInteger() || !t.isInteger() || t.isNegative() || t.gt(e)) throw new Error("nCr domain");
4137
4141
  const n = H.min(t, e.minus(t));
4138
4142
  let a = g(1);
@@ -4147,7 +4151,7 @@ function rn(e, t) {
4147
4151
  }
4148
4152
  return n;
4149
4153
  }
4150
- function gt(e, t) {
4154
+ function vt(e, t) {
4151
4155
  if (e.isNegative()) {
4152
4156
  if (t.isInteger() && !t.mod(2).isZero()) return e.abs().pow(g(1).div(t)).neg();
4153
4157
  throw new Error("root of negative");
@@ -4155,7 +4159,7 @@ function gt(e, t) {
4155
4159
  return e.pow(g(1).div(t));
4156
4160
  }
4157
4161
  const ie = (e) => BigInt(e.trunc().toFixed(0));
4158
- function Jo(e, t = {}) {
4162
+ function Zo(e, t = {}) {
4159
4163
  const n = t.angleMode ?? "deg", a = t.percentMode ?? "of", r = (i) => {
4160
4164
  var l;
4161
4165
  if (i === "ans") return g(t.ans ?? 0);
@@ -4167,22 +4171,22 @@ function Jo(e, t = {}) {
4167
4171
  let p;
4168
4172
  switch (i) {
4169
4173
  case "sin":
4170
- p = Math.sin(yt(l, n));
4174
+ p = Math.sin(bt(l, n));
4171
4175
  break;
4172
4176
  case "cos":
4173
- p = Math.cos(yt(l, n));
4177
+ p = Math.cos(bt(l, n));
4174
4178
  break;
4175
4179
  case "tan":
4176
- p = Math.tan(yt(l, n));
4180
+ p = Math.tan(bt(l, n));
4177
4181
  break;
4178
4182
  case "asin":
4179
- p = bt(Math.asin(l), n);
4183
+ p = gt(Math.asin(l), n);
4180
4184
  break;
4181
4185
  case "acos":
4182
- p = bt(Math.acos(l), n);
4186
+ p = gt(Math.acos(l), n);
4183
4187
  break;
4184
4188
  case "atan":
4185
- p = bt(Math.atan(l), n);
4189
+ p = gt(Math.atan(l), n);
4186
4190
  break;
4187
4191
  case "sinh":
4188
4192
  p = Math.sinh(l);
@@ -4216,11 +4220,11 @@ function Jo(e, t = {}) {
4216
4220
  case "sqrt":
4217
4221
  return p(1), l.sqrt();
4218
4222
  case "cbrt":
4219
- return p(1), gt(l, g(3));
4223
+ return p(1), vt(l, g(3));
4220
4224
  case "qdrt":
4221
- return p(1), gt(l, g(4));
4225
+ return p(1), vt(l, g(4));
4222
4226
  case "root":
4223
- return p(2), gt(l, c[1]);
4227
+ return p(2), vt(l, c[1]);
4224
4228
  case "pow":
4225
4229
  return p(2), l.pow(c[1]);
4226
4230
  case "ln":
@@ -4237,9 +4241,9 @@ function Jo(e, t = {}) {
4237
4241
  case "tenpow":
4238
4242
  return p(1), g(10).pow(l);
4239
4243
  case "ncr":
4240
- return p(2), zo(l, c[1]);
4244
+ return p(2), Jo(l, c[1]);
4241
4245
  case "npr":
4242
- return p(2), Wo(l, c[1]);
4246
+ return p(2), zo(l, c[1]);
4243
4247
  case "gcd":
4244
4248
  return p(2), rn(l, c[1]);
4245
4249
  case "lcm":
@@ -4305,7 +4309,7 @@ function Jo(e, t = {}) {
4305
4309
  case "num":
4306
4310
  return g(i.value);
4307
4311
  case "const":
4308
- return i.name === "PI" ? Vo : i.name === "E" ? Yo : Ko;
4312
+ return i.name === "PI" ? Yo : i.name === "E" ? Ko : Wo;
4309
4313
  case "var":
4310
4314
  return r(i.name);
4311
4315
  case "percent":
@@ -4332,13 +4336,13 @@ function Jo(e, t = {}) {
4332
4336
  function on(e, t = {}) {
4333
4337
  if (e == null || e.trim() === "") return { value: new H(0) };
4334
4338
  try {
4335
- const n = qo(e, { base: t.base }), a = jo(n), r = Jo(a, t);
4339
+ const n = Go(e, { base: t.base }), a = Vo(n), r = Zo(a, t);
4336
4340
  return r.isNaN() ? { value: r, error: "Not a number" } : { value: r };
4337
4341
  } catch (n) {
4338
4342
  return { value: new H(NaN), error: n instanceof Error ? n.message : String(n) };
4339
4343
  }
4340
4344
  }
4341
- const R = (e, t, n, a = "fn", r) => ({ t: e, aria: t, ins: n, cls: a, alt: r });
4345
+ const E = (e, t, n, a = "fn", r) => ({ t: e, aria: t, ins: n, cls: a, alt: r });
4342
4346
  function sn(e, t) {
4343
4347
  if (e.isNaN() || !e.isFinite()) return "";
4344
4348
  if (t !== "DEC") {
@@ -4352,24 +4356,24 @@ function Jn({ def: e }) {
4352
4356
  () => on(a, { angleMode: s, percentMode: n, base: m, ans: h, memory: l }),
4353
4357
  [a, s, n, m, h, l]
4354
4358
  ), F = a.trim() ? S.error ? "" : sn(S.value, m) : "", N = (I) => requestAnimationFrame(() => {
4355
- const E = k.current;
4356
- E && (E.focus(), E.setSelectionRange(I, I));
4359
+ const R = k.current;
4360
+ R && (R.focus(), R.setSelectionRange(I, I));
4357
4361
  }), P = (I) => {
4358
- const E = k.current, j = (E == null ? void 0 : E.selectionStart) ?? a.length, Y = (E == null ? void 0 : E.selectionEnd) ?? a.length;
4362
+ const R = k.current, j = (R == null ? void 0 : R.selectionStart) ?? a.length, Y = (R == null ? void 0 : R.selectionEnd) ?? a.length;
4359
4363
  r(a.slice(0, j) + I + a.slice(Y)), N(j + I.length);
4360
4364
  }, x = () => {
4361
- const I = k.current, E = (I == null ? void 0 : I.selectionStart) ?? a.length, j = (I == null ? void 0 : I.selectionEnd) ?? a.length;
4362
- if (E !== j) {
4363
- r(a.slice(0, E) + a.slice(j)), N(E);
4365
+ const I = k.current, R = (I == null ? void 0 : I.selectionStart) ?? a.length, j = (I == null ? void 0 : I.selectionEnd) ?? a.length;
4366
+ if (R !== j) {
4367
+ r(a.slice(0, R) + a.slice(j)), N(R);
4364
4368
  return;
4365
4369
  }
4366
- E !== 0 && (r(a.slice(0, E - 1) + a.slice(E)), N(E - 1));
4370
+ R !== 0 && (r(a.slice(0, R - 1) + a.slice(R)), N(R - 1));
4367
4371
  }, T = () => {
4368
4372
  if (!a.trim()) return;
4369
4373
  const I = on(a, { angleMode: s, percentMode: n, base: m, ans: h, memory: l });
4370
4374
  if (I.error) return;
4371
- const E = sn(I.value, m);
4372
- w((j) => [{ expr: a, result: E }, ...j].slice(0, 50)), f(I.value), r(E), N(E.length);
4375
+ const R = sn(I.value, m);
4376
+ w((j) => [{ expr: a, result: R }, ...j].slice(0, 50)), f(I.value), r(R), N(R.length);
4373
4377
  }, $ = (I) => {
4374
4378
  switch (I) {
4375
4379
  case "eq":
@@ -4388,10 +4392,10 @@ function Jn({ def: e }) {
4388
4392
  P("M");
4389
4393
  break;
4390
4394
  case "mplus":
4391
- S.error || p((E) => E.plus(S.value));
4395
+ S.error || p((R) => R.plus(S.value));
4392
4396
  break;
4393
4397
  case "mminus":
4394
- S.error || p((E) => E.minus(S.value));
4398
+ S.error || p((R) => R.minus(S.value));
4395
4399
  break;
4396
4400
  }
4397
4401
  }, L = (I) => {
@@ -4401,71 +4405,71 @@ function Jn({ def: e }) {
4401
4405
  }, G = [
4402
4406
  [
4403
4407
  { t: "2nd", aria: "second function", cls: i ? "mode on" : "mode", act: void 0, ins: void 0 },
4404
- R("sin", "sine", "sin(", "fn", R("sin⁻¹", "arcsine", "asin(")),
4405
- R("cos", "cosine", "cos(", "fn", R("cos⁻¹", "arccosine", "acos(")),
4406
- R("tan", "tangent", "tan(", "fn", R("tan⁻¹", "arctangent", "atan(")),
4407
- R("ln", "natural log", "ln(", "fn", R("eˣ", "e to the x", "exp(")),
4408
- R("log", "log base 10", "log(", "fn", R("10ˣ", "ten to the x", "10^"))
4408
+ E("sin", "sine", "sin(", "fn", E("sin⁻¹", "arcsine", "asin(")),
4409
+ E("cos", "cosine", "cos(", "fn", E("cos⁻¹", "arccosine", "acos(")),
4410
+ E("tan", "tangent", "tan(", "fn", E("tan⁻¹", "arctangent", "atan(")),
4411
+ E("ln", "natural log", "ln(", "fn", E("eˣ", "e to the x", "exp(")),
4412
+ E("log", "log base 10", "log(", "fn", E("10ˣ", "ten to the x", "10^"))
4409
4413
  ],
4410
4414
  [
4411
- R("x²", "square", "^2", "fn", R("x³", "cube", "^3")),
4412
- R("√", "square root", "√", "fn", R("∛", "cube root", "∛")),
4413
- R("xʸ", "power", "^", "fn", R("ʸ√x", "nth root", "root(")),
4414
- R("π", "pi", "π", "fn", R("φ", "golden ratio", "phi")),
4415
- R("e", "euler number", "e", "fn", R("EE", "exponent", "E")),
4416
- R("1/x", "reciprocal", "recip(", "fn", R("|x|", "absolute value", "abs("))
4415
+ E("x²", "square", "^2", "fn", E("x³", "cube", "^3")),
4416
+ E("√", "square root", "√", "fn", E("∛", "cube root", "∛")),
4417
+ E("xʸ", "power", "^", "fn", E("ʸ√x", "nth root", "root(")),
4418
+ E("π", "pi", "π", "fn", E("φ", "golden ratio", "phi")),
4419
+ E("e", "euler number", "e", "fn", E("EE", "exponent", "E")),
4420
+ E("1/x", "reciprocal", "recip(", "fn", E("|x|", "absolute value", "abs("))
4417
4421
  ],
4418
4422
  [
4419
- R("n!", "factorial", "!", "fn", R("sinh", "hyperbolic sine", "sinh(")),
4420
- R("nCr", "combinations", "nCr(", "fn", R("cosh", "hyperbolic cosine", "cosh(")),
4421
- R("nPr", "permutations", "nPr(", "fn", R("tanh", "hyperbolic tangent", "tanh(")),
4422
- R("gcd", "greatest common divisor", "gcd(", "fn", R("lcm", "least common multiple", "lcm(")),
4423
- R("(", "open paren", "(", "fn"),
4424
- R(")", "close paren", ")", "fn")
4423
+ E("n!", "factorial", "!", "fn", E("sinh", "hyperbolic sine", "sinh(")),
4424
+ E("nCr", "combinations", "nCr(", "fn", E("cosh", "hyperbolic cosine", "cosh(")),
4425
+ E("nPr", "permutations", "nPr(", "fn", E("tanh", "hyperbolic tangent", "tanh(")),
4426
+ E("gcd", "greatest common divisor", "gcd(", "fn", E("lcm", "least common multiple", "lcm(")),
4427
+ E("(", "open paren", "(", "fn"),
4428
+ E(")", "close paren", ")", "fn")
4425
4429
  ],
4426
4430
  [
4427
4431
  { t: "C", aria: "clear", act: "clear", cls: "op" },
4428
4432
  { t: "⌫", aria: "backspace", act: "back", cls: "op" },
4429
- R("mod", "modulo", " mod ", "op", R("round", "round", "round(")),
4430
- R("%", "percent", "%", "op", R("floor", "floor", "floor(")),
4431
- R("÷", "divide", "÷", "op", R("ceil", "ceiling", "ceil("))
4433
+ E("mod", "modulo", " mod ", "op", E("round", "round", "round(")),
4434
+ E("%", "percent", "%", "op", E("floor", "floor", "floor(")),
4435
+ E("÷", "divide", "÷", "op", E("ceil", "ceiling", "ceil("))
4432
4436
  ],
4433
4437
  [
4434
- R("7", "7", "7", "num"),
4435
- R("8", "8", "8", "num"),
4436
- R("9", "9", "9", "num"),
4437
- R("×", "multiply", "×", "op"),
4438
- R("!", "factorial", "!", "op", R("sign", "sign", "sign("))
4438
+ E("7", "7", "7", "num"),
4439
+ E("8", "8", "8", "num"),
4440
+ E("9", "9", "9", "num"),
4441
+ E("×", "multiply", "×", "op"),
4442
+ E("!", "factorial", "!", "op", E("sign", "sign", "sign("))
4439
4443
  ],
4440
4444
  [
4441
- R("4", "4", "4", "num"),
4442
- R("5", "5", "5", "num"),
4443
- R("6", "6", "6", "num"),
4444
- R("−", "minus", "−", "op"),
4445
- R("^", "power", "^", "op")
4445
+ E("4", "4", "4", "num"),
4446
+ E("5", "5", "5", "num"),
4447
+ E("6", "6", "6", "num"),
4448
+ E("−", "minus", "−", "op"),
4449
+ E("^", "power", "^", "op")
4446
4450
  ],
4447
4451
  [
4448
- R("1", "1", "1", "num"),
4449
- R("2", "2", "2", "num"),
4450
- R("3", "3", "3", "num"),
4451
- R("+", "plus", "+", "op"),
4452
- R(".", "decimal point", ".", "num")
4452
+ E("1", "1", "1", "num"),
4453
+ E("2", "2", "2", "num"),
4454
+ E("3", "3", "3", "num"),
4455
+ E("+", "plus", "+", "op"),
4456
+ E(".", "decimal point", ".", "num")
4453
4457
  ],
4454
4458
  [
4455
- R("0", "0", "0", "num"),
4456
- R("±", "negate", "-", "num"),
4459
+ E("0", "0", "0", "num"),
4460
+ E("±", "negate", "-", "num"),
4457
4461
  { t: "M+", aria: "memory add", act: "mplus", cls: "op" },
4458
4462
  { t: "M−", aria: "memory subtract", act: "mminus", cls: "op" },
4459
4463
  { t: "=", aria: "equals", act: "eq", cls: "accent" }
4460
4464
  ]
4461
4465
  ], q = [
4462
- R("AND", "bitwise and", " and ", "op"),
4463
- R("OR", "bitwise or", " or ", "op"),
4464
- R("XOR", "bitwise xor", " xor ", "op"),
4465
- R("NOT", "bitwise not", "not ", "op"),
4466
- R("<<", "shift left", "<<", "op"),
4467
- R(">>", "shift right", ">>", "op")
4468
- ], A = ["A", "B", "C", "D", "E", "F"].map((I) => R(I, `hex ${I}`, I, "num"));
4466
+ E("AND", "bitwise and", " and ", "op"),
4467
+ E("OR", "bitwise or", " or ", "op"),
4468
+ E("XOR", "bitwise xor", " xor ", "op"),
4469
+ E("NOT", "bitwise not", "not ", "op"),
4470
+ E("<<", "shift left", "<<", "op"),
4471
+ E(">>", "shift right", ">>", "op")
4472
+ ], A = ["A", "B", "C", "D", "E", "F"].map((I) => E(I, `hex ${I}`, I, "num"));
4469
4473
  return /* @__PURE__ */ b("section", { className: "card sci", children: [
4470
4474
  /* @__PURE__ */ b("div", { className: "sci-toolbar", children: [
4471
4475
  /* @__PURE__ */ o("div", { className: "seg", role: "group", "aria-label": "angle mode", children: ["deg", "rad", "grad"].map((I) => /* @__PURE__ */ o("button", { type: "button", "aria-pressed": s === I, onClick: () => u(I), children: I }, I)) }),
@@ -4494,7 +4498,7 @@ function Jn({ def: e }) {
4494
4498
  ] }) : /* @__PURE__ */ o("span", { children: " " }) })
4495
4499
  ] }),
4496
4500
  /* @__PURE__ */ b("div", { className: "sci-pad", role: "group", "aria-label": "calculator keypad", children: [
4497
- G.map((I, E) => /* @__PURE__ */ o("div", { className: "sci-row", children: I.map((j, Y) => {
4501
+ G.map((I, R) => /* @__PURE__ */ o("div", { className: "sci-row", children: I.map((j, Y) => {
4498
4502
  const V = i && j.alt ? j.alt : j, Q = j.t === "2nd";
4499
4503
  return /* @__PURE__ */ o(
4500
4504
  "button",
@@ -4503,15 +4507,15 @@ function Jn({ def: e }) {
4503
4507
  className: `sci-key ${V.cls ?? "fn"}`,
4504
4508
  "aria-label": V.aria,
4505
4509
  "aria-pressed": Q ? i : void 0,
4506
- onClick: () => Q ? c((Re) => !Re) : B(V),
4510
+ onClick: () => Q ? c((Ee) => !Ee) : B(V),
4507
4511
  children: V.t
4508
4512
  },
4509
4513
  Y
4510
4514
  );
4511
- }) }, E)),
4515
+ }) }, R)),
4512
4516
  m !== "DEC" && /* @__PURE__ */ b(re, { children: [
4513
- m === "HEX" && /* @__PURE__ */ o("div", { className: "sci-row", children: A.map((I, E) => /* @__PURE__ */ o("button", { type: "button", className: `sci-key ${I.cls}`, "aria-label": I.aria, onClick: () => B(I), children: I.t }, E)) }),
4514
- /* @__PURE__ */ o("div", { className: "sci-row", children: q.map((I, E) => /* @__PURE__ */ o("button", { type: "button", className: `sci-key ${I.cls}`, "aria-label": I.aria, onClick: () => B(I), children: I.t }, E)) })
4517
+ m === "HEX" && /* @__PURE__ */ o("div", { className: "sci-row", children: A.map((I, R) => /* @__PURE__ */ o("button", { type: "button", className: `sci-key ${I.cls}`, "aria-label": I.aria, onClick: () => B(I), children: I.t }, R)) }),
4518
+ /* @__PURE__ */ o("div", { className: "sci-row", children: q.map((I, R) => /* @__PURE__ */ o("button", { type: "button", className: `sci-key ${I.cls}`, "aria-label": I.aria, onClick: () => B(I), children: I.t }, R)) })
4515
4519
  ] })
4516
4520
  ] }),
4517
4521
  /* @__PURE__ */ b("div", { className: "sci-row sci-memrow", children: [
@@ -4524,7 +4528,7 @@ function Jn({ def: e }) {
4524
4528
  /* @__PURE__ */ o("span", { children: "History" }),
4525
4529
  /* @__PURE__ */ o("button", { type: "button", className: "icon-btn", onClick: () => w([]), "aria-label": "clear history", children: "Clear" })
4526
4530
  ] }),
4527
- /* @__PURE__ */ o("ul", { children: y.map((I, E) => /* @__PURE__ */ o("li", { children: /* @__PURE__ */ b("button", { type: "button", onClick: () => {
4531
+ /* @__PURE__ */ o("ul", { children: y.map((I, R) => /* @__PURE__ */ o("li", { children: /* @__PURE__ */ b("button", { type: "button", onClick: () => {
4528
4532
  r(I.expr), N(I.expr.length);
4529
4533
  }, "aria-label": `reuse ${I.expr} equals ${I.result}`, children: [
4530
4534
  /* @__PURE__ */ o("span", { className: "sci-tape-expr num", children: I.expr }),
@@ -4532,11 +4536,11 @@ function Jn({ def: e }) {
4532
4536
  "= ",
4533
4537
  I.result
4534
4538
  ] })
4535
- ] }) }, E)) })
4539
+ ] }) }, R)) })
4536
4540
  ] })
4537
4541
  ] });
4538
4542
  }
4539
- const tt = [
4543
+ const nt = [
4540
4544
  { code: "USD", name: "US Dollar", symbol: "$" },
4541
4545
  { code: "EUR", name: "Euro", symbol: "€" },
4542
4546
  { code: "GBP", name: "British Pound", symbol: "£" },
@@ -4581,14 +4585,14 @@ const tt = [
4581
4585
  { code: "BDT", name: "Bangladeshi Taka", symbol: "৳" },
4582
4586
  { code: "LKR", name: "Sri Lankan Rupee", symbol: "Rs" },
4583
4587
  { code: "NPR", name: "Nepalese Rupee", symbol: "रू" }
4584
- ], Zo = (e) => tt.find((t) => t.code === e), Xo = (e) => e === "INR" ? "en-IN" : "en-US", Zn = (e, t) => g(e).times(t), Xn = (e) => {
4588
+ ], Xo = (e) => nt.find((t) => t.code === e), Qo = (e) => e === "INR" ? "en-IN" : "en-US", Zn = (e, t) => g(e).times(t), Xn = (e) => {
4585
4589
  const t = g(e);
4586
4590
  return t.gt(0) ? g(1).div(t) : g(0);
4587
4591
  };
4588
- function Rt(e, t) {
4592
+ function Mt(e, t) {
4589
4593
  const n = g(e);
4590
4594
  try {
4591
- return new Intl.NumberFormat(Xo(t), { style: "currency", currency: t }).format(
4595
+ return new Intl.NumberFormat(Qo(t), { style: "currency", currency: t }).format(
4592
4596
  Number(n.toFixed(4))
4593
4597
  );
4594
4598
  } catch {
@@ -4616,21 +4620,21 @@ function Je(e, t) {
4616
4620
  }
4617
4621
  const ea = (e, t) => t - e > 864e5, fs = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
4618
4622
  __proto__: null,
4619
- CURRENCIES: tt,
4623
+ CURRENCIES: nt,
4620
4624
  convert: Zn,
4621
- currencyByCode: Zo,
4625
+ currencyByCode: Xo,
4622
4626
  currencyDecimals: Qn,
4623
- formatCurrency: Rt,
4627
+ formatCurrency: Mt,
4624
4628
  inverseRate: Xn,
4625
4629
  isStale: ea,
4626
4630
  stalenessLabel: Je
4627
- }, Symbol.toStringTag, { value: "Module" })), Qo = (e) => `https://open.er-api.com/v6/latest/${encodeURIComponent(e)}`;
4628
- async function ei(e, t, n = {}) {
4631
+ }, Symbol.toStringTag, { value: "Module" })), ei = (e) => `https://open.er-api.com/v6/latest/${encodeURIComponent(e)}`;
4632
+ async function ti(e, t, n = {}) {
4629
4633
  var m;
4630
4634
  if (e === t) return { rate: "1", asOf: "", provider: "identity" };
4631
4635
  const a = n.fetchImpl ?? (typeof fetch < "u" ? fetch : void 0);
4632
4636
  if (!a) throw new Error("No fetch available in this environment");
4633
- const r = await a(Qo(e), { signal: n.signal });
4637
+ const r = await a(ei(e), { signal: n.signal });
4634
4638
  if (!r.ok) throw new Error(`Rate service returned HTTP ${r.status}`);
4635
4639
  const s = await r.json();
4636
4640
  if (s != null && s.result && s.result !== "success") throw new Error(s["error-type"] || "Rate service error");
@@ -4642,18 +4646,18 @@ function ln(e, t) {
4642
4646
  const n = Date.parse(e);
4643
4647
  return Number.isFinite(n) ? n : t;
4644
4648
  }
4645
- const ta = "calcsuite:fxrates", na = "calcsuite:fxmode", vt = () => {
4649
+ const ta = "calcsuite:fxrates", na = "calcsuite:fxmode", kt = () => {
4646
4650
  try {
4647
4651
  return JSON.parse(localStorage.getItem(ta) || "{}");
4648
4652
  } catch {
4649
4653
  return {};
4650
4654
  }
4651
- }, ti = (e) => {
4655
+ }, ni = (e) => {
4652
4656
  try {
4653
4657
  localStorage.setItem(ta, JSON.stringify(e));
4654
4658
  } catch {
4655
4659
  }
4656
- }, ni = () => {
4660
+ }, ai = () => {
4657
4661
  try {
4658
4662
  return localStorage.getItem(na) === "offline" ? "offline" : "online";
4659
4663
  } catch {
@@ -4662,7 +4666,7 @@ const ta = "calcsuite:fxrates", na = "calcsuite:fxmode", vt = () => {
4662
4666
  }, Ke = (e, t) => `${e}_${t}`;
4663
4667
  function aa() {
4664
4668
  var _t;
4665
- 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(() => ni()), [S, F] = M(() => vt()), [N, P] = M(() => Date.now()), x = de(null);
4669
+ 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(() => ai()), [S, F] = M(() => kt()), [N, P] = M(() => Date.now()), x = de(null);
4666
4670
  X(() => {
4667
4671
  const O = setInterval(() => P(Date.now()), 3e4);
4668
4672
  return () => clearInterval(O);
@@ -4670,7 +4674,7 @@ function aa() {
4670
4674
  const T = (O, Z) => {
4671
4675
  F((ae) => {
4672
4676
  const oe = { ...ae, [Ke(e, n)]: { rate: O, at: Z } };
4673
- return ti(oe), oe;
4677
+ return ni(oe), oe;
4674
4678
  });
4675
4679
  }, $ = (O, Z) => {
4676
4680
  var oe;
@@ -4680,11 +4684,11 @@ function aa() {
4680
4684
  m("1"), i("live"), l(""), h("idle");
4681
4685
  return;
4682
4686
  }
4683
- h("loading"), y(""), ei(O, Z, { signal: ae.signal }).then((xe) => {
4687
+ h("loading"), y(""), ti(O, Z, { signal: ae.signal }).then((xe) => {
4684
4688
  ae.signal.aborted || (m(xe.rate), i("live"), l(xe.asOf), h("idle"), T(xe.rate, ln(xe.asOf, Date.now())));
4685
4689
  }).catch((xe) => {
4686
4690
  if (ae.signal.aborted) return;
4687
- const Ht = vt()[Ke(O, Z)];
4691
+ const Ht = kt()[Ke(O, Z)];
4688
4692
  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.`));
4689
4693
  });
4690
4694
  }, L = (O, Z) => {
@@ -4693,7 +4697,7 @@ function aa() {
4693
4697
  m("1"), i("saved");
4694
4698
  return;
4695
4699
  }
4696
- const ae = vt()[Ke(O, Z)];
4700
+ const ae = kt()[Ke(O, Z)];
4697
4701
  ae ? (m(ae.rate), i("saved")) : (m(""), i("none"));
4698
4702
  };
4699
4703
  X(() => (w === "online" ? $(e, n) : L(e, n), () => {
@@ -4706,14 +4710,14 @@ function aa() {
4706
4710
  localStorage.setItem(na, O);
4707
4711
  } catch {
4708
4712
  }
4709
- }, G = (O) => O.replace(/[, ]/g, "").trim(), q = G(r), A = G(u), I = q !== "" && Number(q) >= 0 && Number.isFinite(Number(q)), E = A !== "" && Number(A) > 0 && Number.isFinite(Number(A)), j = ne(
4710
- () => I && E ? Zn(q, A) : null,
4711
- [I, E, q, A]
4712
- ), Y = E ? Xn(A) : null, V = (O) => {
4713
- m(O), i("manual"), h("idle"), y(""), (E || O.trim() !== "") && T(G(O), Date.now());
4713
+ }, 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 = ne(
4714
+ () => I && R ? Zn(q, A) : null,
4715
+ [I, R, q, A]
4716
+ ), Y = R ? Xn(A) : null, V = (O) => {
4717
+ m(O), i("manual"), h("idle"), y(""), (R || O.trim() !== "") && T(G(O), Date.now());
4714
4718
  }, Q = () => {
4715
4719
  t(n), a(e);
4716
- }, Re = c ? Je(ln(c, N), N) : "just now", K = (_t = S[Ke(e, n)]) == null ? void 0 : _t.at, pe = (O) => /* @__PURE__ */ b("option", { value: O.code, children: [
4720
+ }, Ee = c ? Je(ln(c, N), N) : "just now", K = (_t = S[Ke(e, n)]) == null ? void 0 : _t.at, pe = (O) => /* @__PURE__ */ b("option", { value: O.code, children: [
4717
4721
  O.code,
4718
4722
  " — ",
4719
4723
  O.name
@@ -4723,7 +4727,7 @@ function aa() {
4723
4727
  ] }) : 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: [
4724
4728
  /* @__PURE__ */ o("span", { className: "cc-live-dot" }),
4725
4729
  " Live rate · updated ",
4726
- Re,
4730
+ Ee,
4727
4731
  " · open.er-api.com"
4728
4732
  ] }) : null : d === "saved" && K ? /* @__PURE__ */ b("span", { children: [
4729
4733
  "✈ Offline · saved rate ",
@@ -4752,12 +4756,12 @@ function aa() {
4752
4756
  ] }),
4753
4757
  /* @__PURE__ */ b("label", { className: "field cc-cur", children: [
4754
4758
  /* @__PURE__ */ o("span", { className: "lbl", children: "From" }),
4755
- /* @__PURE__ */ o("div", { className: "input-wrap", children: /* @__PURE__ */ o("select", { value: e, onChange: (O) => t(O.target.value), "aria-label": "From currency", children: tt.map(pe) }) })
4759
+ /* @__PURE__ */ o("div", { className: "input-wrap", children: /* @__PURE__ */ o("select", { value: e, onChange: (O) => t(O.target.value), "aria-label": "From currency", children: nt.map(pe) }) })
4756
4760
  ] }),
4757
4761
  /* @__PURE__ */ o("button", { type: "button", className: "cc-swap", onClick: Q, "aria-label": "Swap currencies", title: "Swap", children: "⇄" }),
4758
4762
  /* @__PURE__ */ b("label", { className: "field cc-cur", children: [
4759
4763
  /* @__PURE__ */ o("span", { className: "lbl", children: "To" }),
4760
- /* @__PURE__ */ o("div", { className: "input-wrap", children: /* @__PURE__ */ o("select", { value: n, onChange: (O) => a(O.target.value), "aria-label": "To currency", children: tt.map(pe) }) })
4764
+ /* @__PURE__ */ o("div", { className: "input-wrap", children: /* @__PURE__ */ o("select", { value: n, onChange: (O) => a(O.target.value), "aria-label": "To currency", children: nt.map(pe) }) })
4761
4765
  ] })
4762
4766
  ] }),
4763
4767
  /* @__PURE__ */ b("label", { className: "field", style: { marginTop: 16 }, children: [
@@ -4798,10 +4802,10 @@ function aa() {
4798
4802
  /* @__PURE__ */ b("section", { className: "card", children: [
4799
4803
  j ? /* @__PURE__ */ b("div", { className: "result", "aria-live": "polite", children: [
4800
4804
  /* @__PURE__ */ b("div", { className: "label", children: [
4801
- Rt(q, e),
4805
+ Mt(q, e),
4802
4806
  " ="
4803
4807
  ] }),
4804
- /* @__PURE__ */ o("div", { className: "value num accent-txt", children: Rt(j, n) }),
4808
+ /* @__PURE__ */ o("div", { className: "value num accent-txt", children: Mt(j, n) }),
4805
4809
  /* @__PURE__ */ b("div", { className: "secondary", children: [
4806
4810
  /* @__PURE__ */ b("div", { className: "kv", children: [
4807
4811
  /* @__PURE__ */ o("div", { className: "k", children: "Rate" }),
@@ -4869,13 +4873,13 @@ function aa() {
4869
4873
  ] })
4870
4874
  ] });
4871
4875
  }
4872
- const ai = {
4876
+ const ri = {
4873
4877
  id: "",
4874
4878
  group: "tools",
4875
4879
  title: "",
4876
4880
  inputs: [],
4877
4881
  compute: () => ({ primary: { label: "", value: "" } })
4878
- }, ri = {
4882
+ }, oi = {
4879
4883
  "loan.emi": Wn,
4880
4884
  scientific: Jn,
4881
4885
  currency: aa
@@ -4885,7 +4889,7 @@ function cn(e, t) {
4885
4889
  for (const a of e.inputs) a.default !== void 0 && (n[a.key] = a.default);
4886
4890
  return t ? { ...n, ...t } : n;
4887
4891
  }
4888
- function oi({
4892
+ function ii({
4889
4893
  def: e,
4890
4894
  id: t,
4891
4895
  seed: n,
@@ -4894,9 +4898,9 @@ function oi({
4894
4898
  actions: s
4895
4899
  }) {
4896
4900
  var L, B, G, q;
4897
- const u = e ?? (t ? It(t) : void 0), m = u ?? ai, d = { ...ri, ...a }, { settings: i, fmt: c } = ue(), [l, p] = M(() => cn(m, n)), [h, f] = M("schedule"), [y, w] = M(!1);
4901
+ const u = e ?? (t ? Rt(t) : void 0), m = u ?? ri, d = { ...oi, ...a }, { settings: i, fmt: c } = ue(), [l, p] = M(() => cn(m, n)), [h, f] = M("schedule"), [y, w] = M(!1);
4898
4902
  X(() => p(cn(m, n)), [m.id, n]);
4899
- const k = i.region, S = (A, I) => p((E) => ({ ...E, [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 } = ne(() => {
4903
+ 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 } = ne(() => {
4900
4904
  const A = { settings: i, region: k, fmt: c, D: g };
4901
4905
  try {
4902
4906
  return { result: m.compute(l, A), error: null };
@@ -4932,7 +4936,7 @@ function oi({
4932
4936
  T && /* @__PURE__ */ o("div", { className: "error", role: "alert", style: { marginTop: 16 }, children: T })
4933
4937
  ] }),
4934
4938
  x && !T && /* @__PURE__ */ b("section", { className: "card", children: [
4935
- /* @__PURE__ */ o(Xr, { view: x }),
4939
+ /* @__PURE__ */ o(Qr, { view: x }),
4936
4940
  (B = x.warnings) == null ? void 0 : B.map((A, I) => /* @__PURE__ */ o("div", { className: "notice", children: A }, I)),
4937
4941
  s && /* @__PURE__ */ o("div", { className: "actions-row", children: s(x, l) }),
4938
4942
  $ && /* @__PURE__ */ b(re, { children: [
@@ -4943,8 +4947,8 @@ function oi({
4943
4947
  (((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" })
4944
4948
  ] }),
4945
4949
  /* @__PURE__ */ b("div", { className: "tab-anim", children: [
4946
- h === "schedule" && x.schedule && /* @__PURE__ */ o(to, { schedule: x.schedule }),
4947
- h === "chart" && x.chart && /* @__PURE__ */ o(no, { chart: x.chart }),
4950
+ h === "schedule" && x.schedule && /* @__PURE__ */ o(no, { schedule: x.schedule }),
4951
+ h === "chart" && x.chart && /* @__PURE__ */ o(ao, { chart: x.chart }),
4948
4952
  h === "formula" && x.formula && i.ui.showFormulas && /* @__PURE__ */ b("div", { className: "formula", children: [
4949
4953
  /* @__PURE__ */ o("code", { children: x.formula }),
4950
4954
  x.formulaSubstituted && /* @__PURE__ */ o("code", { style: { marginTop: 8 }, children: x.formulaSubstituted })
@@ -4967,374 +4971,91 @@ function un({ def: e, region: t }) {
4967
4971
  }
4968
4972
  function dn({ f: e, values: t, set: n }) {
4969
4973
  const a = e.kind === "cashflows" || e.kind === "segmented" ? "span2" : "";
4970
- return /* @__PURE__ */ o("div", { className: a, children: /* @__PURE__ */ o(zr, { f: e, value: t[e.key], onChange: (r) => n(e.key, r), values: t }) });
4974
+ return /* @__PURE__ */ o("div", { className: a, children: /* @__PURE__ */ o(Jr, { f: e, value: t[e.key], onChange: (r) => n(e.key, r), values: t }) });
4971
4975
  }
4972
- const ii = [
4976
+ const si = [
4973
4977
  { id: "default", label: "Green", main: "#00A76F", light: "#2CCF8E", dark: "#087055", ink: "#06251A" },
4974
4978
  { id: "cyan", label: "Cyan", main: "#078DEE", light: "#68CDF9", dark: "#0351AB", ink: "#FFFFFF" },
4975
4979
  { id: "purple", label: "Purple", main: "#7635DC", light: "#B985F4", dark: "#431A9E", ink: "#FFFFFF" },
4976
4980
  { id: "blue", label: "Blue", main: "#2065D1", light: "#76B0F1", dark: "#103996", ink: "#FFFFFF" },
4977
4981
  { id: "orange", label: "Orange", main: "#FDA92D", light: "#FED680", dark: "#B66816", ink: "#212B36" },
4978
4982
  { id: "gray", label: "Gray", main: "#A4AAB3", light: "#CED1D7", dark: "#63686C", ink: "#FFFFFF" }
4979
- ], kt = "-apple-system, 'Segoe UI', system-ui, sans-serif", si = [
4980
- { id: "Inter Tight", label: "Inter Tight", stack: `'Inter Tight', ${kt}` },
4981
- { id: "Public Sans", label: "Public Sans", stack: `'Public Sans', ${kt}` },
4982
- { id: "system-ui", label: "System UI", stack: `system-ui, ${kt}` },
4983
+ ], wt = "-apple-system, 'Segoe UI', system-ui, sans-serif", li = [
4984
+ { id: "Inter Tight", label: "Inter Tight", stack: `'Inter Tight', ${wt}` },
4985
+ { id: "Public Sans", label: "Public Sans", stack: `'Public Sans', ${wt}` },
4986
+ { id: "system-ui", label: "System UI", stack: `system-ui, ${wt}` },
4983
4987
  { id: "Georgia", label: "Georgia (serif)", stack: "Georgia, 'Times New Roman', serif" }
4984
- ], li = "1234567.891";
4985
- function ci() {
4986
- const { settings: e, update: t, setRegion: n, reset: a, replace: r } = ue(), s = de(null), u = Sn(e).money(g(li)), m = () => {
4987
- const i = new Blob([JSON.stringify(e, null, 2)], { type: "application/json" }), c = URL.createObjectURL(i), l = document.createElement("a");
4988
- l.href = c, l.download = "calcsuite-settings.json", l.click(), URL.revokeObjectURL(c);
4989
- }, d = (i) => {
4990
- const c = new FileReader();
4991
- c.onload = () => {
4988
+ ];
4989
+ class z extends Error {
4990
+ constructor(n, a = { code: "transport_error" }) {
4991
+ super(n);
4992
+ ge(this, "code");
4993
+ ge(this, "status");
4994
+ /** The request that failed, auth redacted. */
4995
+ ge(this, "request");
4996
+ this.name = "TransportError", this.code = a.code, this.status = a.status ?? 0, this.request = a.request;
4997
+ }
4998
+ }
4999
+ const ci = ["authorization", "cookie", "x-api-key", "x-auth-token", "api-key"], ui = {
5000
+ attempts: 3,
5001
+ backoff: "exponential",
5002
+ baseDelayMs: 300,
5003
+ retryOn: [408, 429, 500, 502, 503, 504],
5004
+ respectRetryAfter: !0
5005
+ }, di = {
5006
+ enabled: !0,
5007
+ headerName: "Idempotency-Key",
5008
+ keyFrom: "inputsHash"
5009
+ }, mi = {
5010
+ enabled: !0,
5011
+ storage: "memory",
5012
+ maxItems: 200,
5013
+ flushOn: "manual"
5014
+ }, mn = () => {
5015
+ try {
5016
+ return typeof localStorage < "u" && localStorage != null;
5017
+ } catch {
5018
+ return !1;
5019
+ }
5020
+ };
5021
+ function ra() {
5022
+ const e = globalThis.crypto;
5023
+ return e != null && e.randomUUID ? e.randomUUID() : "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, (t) => {
5024
+ const n = Math.random() * 16 | 0;
5025
+ return (t === "x" ? n : n & 3 | 8).toString(16);
5026
+ });
5027
+ }
5028
+ const pn = (e) => new Promise((t) => setTimeout(t, Math.max(0, e)));
5029
+ function pi(e) {
5030
+ let t = String(e).replace(/[\\/]+/g, "-").replace(/[\x00-\x1f\x7f]+/g, "").replace(/[<>:"|?*]+/g, "").replace(/^\.+/, "");
5031
+ return t = t.trim(), t || "file";
5032
+ }
5033
+ function oa(e, t) {
5034
+ var m;
5035
+ 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");
5036
+ return pi(u);
5037
+ }
5038
+ function $t(e, t = []) {
5039
+ const n = /* @__PURE__ */ new Set([...ci, ...t.map((r) => r.toLowerCase())]), a = {};
5040
+ for (const [r, s] of Object.entries(e)) a[r] = n.has(r.toLowerCase()) ? "***" : s;
5041
+ return a;
5042
+ }
5043
+ class hi {
5044
+ constructor(t, n) {
5045
+ ge(this, "items", []);
5046
+ ge(this, "key");
5047
+ this.cfg = t, this.key = `${n}:transport:queue`, this.load();
5048
+ }
5049
+ load() {
5050
+ if (this.cfg.storage === "localStorage" && mn())
4992
5051
  try {
4993
- r(JSON.parse(String(c.result)));
5052
+ this.items = JSON.parse(localStorage.getItem(this.key) || "[]");
4994
5053
  } catch {
4995
- alert("Could not read that settings file.");
4996
- }
4997
- }, c.readAsText(i);
4998
- };
4999
- return /* @__PURE__ */ b("div", { className: "settings", children: [
5000
- /* @__PURE__ */ b("div", { className: "panel-head", children: [
5001
- /* @__PURE__ */ o("h2", { children: "Settings" }),
5002
- /* @__PURE__ */ b("p", { children: [
5003
- "Everything below updates the numbers live. Sample: ",
5004
- /* @__PURE__ */ o("strong", { className: "num", children: u })
5005
- ] })
5006
- ] }),
5007
- /* @__PURE__ */ b(Te, { title: "Region & currency", children: [
5008
- /* @__PURE__ */ o(W, { label: "Region", children: /* @__PURE__ */ b("div", { className: "seg", children: [
5009
- /* @__PURE__ */ o("button", { "aria-pressed": e.region === "IN", onClick: () => n("IN"), children: "🇮🇳 India" }),
5010
- /* @__PURE__ */ o("button", { "aria-pressed": e.region === "US", onClick: () => n("US"), children: "🇺🇸 United States" })
5011
- ] }) }),
5012
- /* @__PURE__ */ o(W, { label: "Currency symbol", children: /* @__PURE__ */ o("input", { className: "mini", value: e.currency.symbol, onChange: (i) => t({ currency: { symbol: i.target.value } }) }) }),
5013
- /* @__PURE__ */ o(W, { label: "Symbol position", children: /* @__PURE__ */ o(
5014
- he,
5015
- {
5016
- value: e.currency.symbolPosition,
5017
- onChange: (i) => t({ currency: { symbolPosition: i } }),
5018
- options: [["prefix", "Prefix ₹100"], ["suffix", "Suffix 100₹"]]
5019
- }
5020
- ) })
5021
- ] }),
5022
- /* @__PURE__ */ b(Te, { title: "Number format", children: [
5023
- /* @__PURE__ */ o(W, { label: "Grouping", children: /* @__PURE__ */ o(
5024
- he,
5025
- {
5026
- value: e.numberFormat.grouping,
5027
- onChange: (i) => t({ numberFormat: { grouping: i } }),
5028
- options: [["indian", "Indian 12,34,567"], ["western", "Western 1,234,567"], ["european", "European 1.234.567"], ["swiss", "Swiss 1'234'567"], ["plain", "Plain 1234567"]]
5029
- }
5030
- ) }),
5031
- /* @__PURE__ */ o(W, { label: "Decimal places", children: /* @__PURE__ */ o("div", { className: "seg", children: [0, 1, 2, 3, 4].map((i) => /* @__PURE__ */ o("button", { "aria-pressed": e.numberFormat.decimalPlaces === i, onClick: () => t({ numberFormat: { decimalPlaces: i } }), children: i }, i)) }) }),
5032
- /* @__PURE__ */ o(W, { label: "Abbreviate (12.5 L / 1.2 Cr)", children: /* @__PURE__ */ o(Le, { on: e.numberFormat.abbreviate, onClick: () => t({ numberFormat: { abbreviate: !e.numberFormat.abbreviate } }) }) }),
5033
- /* @__PURE__ */ o(W, { label: "Abbreviation scale", children: /* @__PURE__ */ o(
5034
- he,
5035
- {
5036
- value: e.numberFormat.abbreviationScale,
5037
- onChange: (i) => t({ numberFormat: { abbreviationScale: i } }),
5038
- options: [["indian", "Lakh / Crore"], ["western", "K / M / B"]]
5039
- }
5040
- ) }),
5041
- /* @__PURE__ */ o(W, { label: "Negatives", children: /* @__PURE__ */ o(
5042
- he,
5043
- {
5044
- value: e.numberFormat.negativeFormat,
5045
- onChange: (i) => t({ numberFormat: { negativeFormat: i } }),
5046
- options: [["minus", "-1,000"], ["parentheses", "(1,000)"]]
5047
- }
5048
- ) })
5049
- ] }),
5050
- /* @__PURE__ */ b(Te, { title: "Calculation", children: [
5051
- /* @__PURE__ */ o(W, { label: "Rounding mode", children: /* @__PURE__ */ o(
5052
- he,
5053
- {
5054
- value: e.rounding.mode,
5055
- onChange: (i) => t({ rounding: { mode: i } }),
5056
- options: [["HALF_UP", "Half up"], ["HALF_EVEN", "Half even (banker’s)"], ["HALF_DOWN", "Half down"], ["UP", "Up"], ["DOWN", "Down"], ["CEIL", "Ceil"], ["FLOOR", "Floor"]]
5057
- }
5058
- ) }),
5059
- /* @__PURE__ */ o(W, { label: "Day-count convention", children: /* @__PURE__ */ o(
5060
- he,
5061
- {
5062
- value: e.dayCount,
5063
- onChange: (i) => t({ dayCount: i }),
5064
- options: [["30/360", "30/360"], ["ACT/365", "ACT/365"], ["ACT/360", "ACT/360"], ["ACT/ACT", "ACT/ACT"], ["30E/360", "30E/360"]]
5065
- }
5066
- ) })
5067
- ] }),
5068
- /* @__PURE__ */ b(Te, { title: "Appearance", children: [
5069
- /* @__PURE__ */ o(W, { label: "Theme", children: /* @__PURE__ */ o(
5070
- he,
5071
- {
5072
- value: e.ui.theme,
5073
- onChange: (i) => t({ ui: { theme: i } }),
5074
- options: [["system", "System"], ["light", "Light"], ["dark", "Dark"], ["highContrast", "High contrast"]]
5075
- }
5076
- ) }),
5077
- /* @__PURE__ */ o(W, { label: "Accent colour", children: /* @__PURE__ */ o("div", { className: "swatches", children: ii.map((i) => {
5078
- const c = e.ui.accent.toLowerCase() === i.main.toLowerCase();
5079
- return /* @__PURE__ */ o(
5080
- "button",
5081
- {
5082
- type: "button",
5083
- className: `swatch ${c ? "active" : ""}`,
5084
- style: { background: i.main },
5085
- "aria-label": i.label,
5086
- "aria-pressed": c,
5087
- title: i.label,
5088
- onClick: () => t({ ui: { accent: i.main } })
5089
- },
5090
- i.id
5091
- );
5092
- }) }) }),
5093
- /* @__PURE__ */ o(W, { label: "Font", children: /* @__PURE__ */ o(
5094
- he,
5095
- {
5096
- value: e.ui.fontFamily,
5097
- onChange: (i) => t({ ui: { fontFamily: i } }),
5098
- options: si.map((i) => [i.id, i.label])
5099
- }
5100
- ) }),
5101
- /* @__PURE__ */ o(W, { label: "Density", children: /* @__PURE__ */ o(
5102
- he,
5103
- {
5104
- value: e.ui.density,
5105
- onChange: (i) => t({ ui: { density: i } }),
5106
- options: [["comfortable", "Comfortable"], ["compact", "Compact"]]
5107
- }
5108
- ) }),
5109
- /* @__PURE__ */ o(W, { label: "Show formulas", children: /* @__PURE__ */ o(Le, { on: e.ui.showFormulas, onClick: () => t({ ui: { showFormulas: !e.ui.showFormulas } }) }) }),
5110
- /* @__PURE__ */ o(W, { label: "Show assumptions", children: /* @__PURE__ */ o(Le, { on: e.ui.showAssumptions, onClick: () => t({ ui: { showAssumptions: !e.ui.showAssumptions } }) }) })
5111
- ] }),
5112
- /* @__PURE__ */ o(Te, { title: "Compliance", children: /* @__PURE__ */ o(W, { label: "Show disclaimer", children: /* @__PURE__ */ o(Le, { on: e.compliance.showDisclaimer, onClick: () => t({ compliance: { showDisclaimer: !e.compliance.showDisclaimer } }) }) }) }),
5113
- /* @__PURE__ */ o(Te, { title: "Integration (advanced)", children: /* @__PURE__ */ o(W, { label: "Enable integration panel", children: /* @__PURE__ */ o(Le, { on: e.features.integrationPanel, onClick: () => t({ features: { integrationPanel: !e.features.integrationPanel } }) }) }) }),
5114
- /* @__PURE__ */ b("div", { className: "actions-row", children: [
5115
- /* @__PURE__ */ o("button", { className: "icon-btn", onClick: m, children: "Export settings" }),
5116
- /* @__PURE__ */ o("button", { className: "icon-btn", onClick: () => {
5117
- var i;
5118
- return (i = s.current) == null ? void 0 : i.click();
5119
- }, children: "Import settings" }),
5120
- /* @__PURE__ */ o("button", { className: "icon-btn", onClick: a, children: "Reset to defaults" }),
5121
- /* @__PURE__ */ o("input", { ref: s, type: "file", accept: "application/json", hidden: !0, onChange: (i) => {
5122
- var c;
5123
- return ((c = i.target.files) == null ? void 0 : c[0]) && d(i.target.files[0]);
5124
- } })
5125
- ] })
5126
- ] });
5127
- }
5128
- function Te({ title: e, children: t }) {
5129
- return /* @__PURE__ */ b("section", { className: "card settings-section", children: [
5130
- /* @__PURE__ */ o("h3", { children: e }),
5131
- t
5132
- ] });
5133
- }
5134
- function W({ label: e, children: t }) {
5135
- return /* @__PURE__ */ b("div", { className: "settings-row", children: [
5136
- /* @__PURE__ */ o("span", { className: "lbl", children: e }),
5137
- /* @__PURE__ */ o("div", { children: t })
5138
- ] });
5139
- }
5140
- function he({ value: e, onChange: t, options: n }) {
5141
- return /* @__PURE__ */ o("div", { className: "input-wrap mini-wrap", children: /* @__PURE__ */ o("select", { value: e, onChange: (a) => t(a.target.value), children: n.map(([a, r]) => /* @__PURE__ */ o("option", { value: a, children: r }, a)) }) });
5142
- }
5143
- function Le({ on: e, onClick: t }) {
5144
- return /* @__PURE__ */ o("button", { type: "button", role: "switch", "aria-checked": e, className: `toggle ${e ? "on" : ""}`, onClick: t, children: /* @__PURE__ */ o("span", { className: "knob" }) });
5145
- }
5146
- function ui({
5147
- items: e,
5148
- onRestore: t,
5149
- onClear: n
5150
- }) {
5151
- return /* @__PURE__ */ b("div", { className: "history", children: [
5152
- /* @__PURE__ */ b("div", { className: "panel-head", style: { display: "flex", justifyContent: "space-between", alignItems: "flex-end" }, children: [
5153
- /* @__PURE__ */ b("div", { children: [
5154
- /* @__PURE__ */ o("h2", { children: "History" }),
5155
- /* @__PURE__ */ o("p", { children: "Your recent calculations, saved on this device." })
5156
- ] }),
5157
- e.length > 0 && /* @__PURE__ */ o("button", { className: "icon-btn", onClick: n, children: "Clear all" })
5158
- ] }),
5159
- e.length === 0 ? /* @__PURE__ */ o("div", { className: "card empty", children: "No saved calculations yet. Compute something and press Save." }) : /* @__PURE__ */ o("div", { className: "card", style: { padding: 0 }, children: /* @__PURE__ */ o("ul", { className: "history-list", children: e.map((a, r) => /* @__PURE__ */ o("li", { children: /* @__PURE__ */ b("button", { className: "history-item", onClick: () => t(a), children: [
5160
- /* @__PURE__ */ b("div", { children: [
5161
- /* @__PURE__ */ o("div", { className: "history-title", children: a.title }),
5162
- /* @__PURE__ */ o("div", { className: "history-when", children: new Date(a.at).toLocaleString() })
5163
- ] }),
5164
- /* @__PURE__ */ o("div", { className: "history-value num", children: a.primary })
5165
- ] }) }, r)) }) })
5166
- ] });
5167
- }
5168
- function mn(e, t) {
5169
- const n = t.toLowerCase(), a = n.indexOf(e);
5170
- if (a >= 0) return 100 - a;
5171
- let r = 0;
5172
- for (let s = 0; s < n.length && r < e.length; s++) n[s] === e[r] && r++;
5173
- return r === e.length ? 10 : -1;
5174
- }
5175
- function di({
5176
- calculators: e,
5177
- actions: t,
5178
- onPick: n,
5179
- onClose: a
5180
- }) {
5181
- const [r, s] = M(""), [u, m] = M(0), d = de(null);
5182
- X(() => {
5183
- var l;
5184
- return (l = d.current) == null ? void 0 : l.focus();
5185
- }, []), X(() => (ka(), () => wa()), []);
5186
- const i = ne(() => {
5187
- const l = e.map((y) => ({
5188
- key: `calc:${y.id}`,
5189
- label: y.title,
5190
- group: y.group,
5191
- hint: y.blurb,
5192
- run: () => n(y.id)
5193
- })), p = t.map((y) => ({ key: `act:${y.id}`, label: y.label, group: "action", hint: y.hint, run: y.run })), h = [...l, ...p], f = r.trim().toLowerCase();
5194
- return f ? h.map((y) => {
5195
- var w, k;
5196
- return { it: y, s: Math.max(mn(f, y.label), mn(f, `${y.group} ${((k = (w = e.find((S) => S.title === y.label)) == null ? void 0 : w.keywords) == null ? void 0 : k.join(" ")) ?? ""}`)) };
5197
- }).filter((y) => y.s > 0).sort((y, w) => w.s - y.s).map((y) => y.it) : h;
5198
- }, [r, e, t, n]);
5199
- return X(() => m(0), [r]), /* @__PURE__ */ o("div", { className: "palette-backdrop", onClick: a, children: /* @__PURE__ */ b("div", { className: "palette", role: "dialog", "aria-label": "Command palette", onClick: (l) => l.stopPropagation(), children: [
5200
- /* @__PURE__ */ o(
5201
- "input",
5202
- {
5203
- ref: d,
5204
- className: "palette-input",
5205
- placeholder: "Search calculators and actions…",
5206
- value: r,
5207
- onChange: (l) => s(l.target.value),
5208
- onKeyDown: (l) => {
5209
- var p;
5210
- l.key === "ArrowDown" ? (l.preventDefault(), m((h) => Math.min(h + 1, i.length - 1))) : l.key === "ArrowUp" ? (l.preventDefault(), m((h) => Math.max(h - 1, 0))) : l.key === "Enter" ? (l.preventDefault(), (p = i[u]) == null || p.run()) : l.key === "Escape" && (l.preventDefault(), l.stopPropagation(), a());
5211
- },
5212
- "aria-label": "Search"
5213
- }
5214
- ),
5215
- /* @__PURE__ */ b("ul", { className: "palette-list", role: "listbox", children: [
5216
- i.length === 0 && /* @__PURE__ */ o("li", { className: "palette-empty", children: "No matches" }),
5217
- i.map((l, p) => /* @__PURE__ */ b(
5218
- "li",
5219
- {
5220
- role: "option",
5221
- "aria-selected": p === u,
5222
- className: `palette-item ${p === u ? "active" : ""}`,
5223
- onMouseEnter: () => m(p),
5224
- onClick: () => l.run(),
5225
- children: [
5226
- /* @__PURE__ */ o("span", { className: "palette-label", children: l.label }),
5227
- /* @__PURE__ */ o("span", { className: "palette-group", children: l.group })
5228
- ]
5229
- },
5230
- l.key
5231
- ))
5232
- ] })
5233
- ] }) });
5234
- }
5235
- const ct = (e) => ({
5236
- width: e,
5237
- height: e,
5238
- viewBox: "0 0 24 24",
5239
- fill: "none",
5240
- stroke: "currentColor",
5241
- strokeWidth: 2,
5242
- strokeLinecap: "round",
5243
- strokeLinejoin: "round",
5244
- "aria-hidden": !0
5245
- });
5246
- function mi({ size: e = 17 }) {
5247
- return /* @__PURE__ */ b("svg", { ...ct(e), children: [
5248
- /* @__PURE__ */ o("circle", { cx: "12", cy: "12", r: "3" }),
5249
- /* @__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" })
5250
- ] });
5251
- }
5252
- function pi({ size: e = 17 }) {
5253
- return /* @__PURE__ */ b("svg", { ...ct(e), children: [
5254
- /* @__PURE__ */ o("circle", { cx: "12", cy: "12", r: "4" }),
5255
- /* @__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" })
5256
- ] });
5257
- }
5258
- function hi({ size: e = 17 }) {
5259
- return /* @__PURE__ */ o("svg", { ...ct(e), children: /* @__PURE__ */ o("path", { d: "M12 3a6 6 0 0 0 9 9 9 9 0 1 1-9-9Z" }) });
5260
- }
5261
- function fi({ size: e = 17 }) {
5262
- return /* @__PURE__ */ b("svg", { ...ct(e), children: [
5263
- /* @__PURE__ */ o("path", { d: "M3 3v5h5" }),
5264
- /* @__PURE__ */ o("path", { d: "M3.05 13A9 9 0 1 0 6 5.3L3 8" }),
5265
- /* @__PURE__ */ o("path", { d: "M12 7v5l4 2" })
5266
- ] });
5267
- }
5268
- class z extends Error {
5269
- constructor(n, a = { code: "transport_error" }) {
5270
- super(n);
5271
- ge(this, "code");
5272
- ge(this, "status");
5273
- /** The request that failed, auth redacted. */
5274
- ge(this, "request");
5275
- this.name = "TransportError", this.code = a.code, this.status = a.status ?? 0, this.request = a.request;
5276
- }
5277
- }
5278
- const yi = ["authorization", "cookie", "x-api-key", "x-auth-token", "api-key"], bi = {
5279
- attempts: 3,
5280
- backoff: "exponential",
5281
- baseDelayMs: 300,
5282
- retryOn: [408, 429, 500, 502, 503, 504],
5283
- respectRetryAfter: !0
5284
- }, gi = {
5285
- enabled: !0,
5286
- headerName: "Idempotency-Key",
5287
- keyFrom: "inputsHash"
5288
- }, vi = {
5289
- enabled: !0,
5290
- storage: "memory",
5291
- maxItems: 200,
5292
- flushOn: "manual"
5293
- }, pn = () => {
5294
- try {
5295
- return typeof localStorage < "u" && localStorage != null;
5296
- } catch {
5297
- return !1;
5298
- }
5299
- };
5300
- function ra() {
5301
- const e = globalThis.crypto;
5302
- return e != null && e.randomUUID ? e.randomUUID() : "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, (t) => {
5303
- const n = Math.random() * 16 | 0;
5304
- return (t === "x" ? n : n & 3 | 8).toString(16);
5305
- });
5306
- }
5307
- const hn = (e) => new Promise((t) => setTimeout(t, Math.max(0, e)));
5308
- function ki(e) {
5309
- let t = String(e).replace(/[\\/]+/g, "-").replace(/[\x00-\x1f\x7f]+/g, "").replace(/[<>:"|?*]+/g, "").replace(/^\.+/, "");
5310
- return t = t.trim(), t || "file";
5311
- }
5312
- function oa(e, t) {
5313
- var m;
5314
- 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");
5315
- return ki(u);
5316
- }
5317
- function Mt(e, t = []) {
5318
- const n = /* @__PURE__ */ new Set([...yi, ...t.map((r) => r.toLowerCase())]), a = {};
5319
- for (const [r, s] of Object.entries(e)) a[r] = n.has(r.toLowerCase()) ? "***" : s;
5320
- return a;
5321
- }
5322
- class wi {
5323
- constructor(t, n) {
5324
- ge(this, "items", []);
5325
- ge(this, "key");
5326
- this.cfg = t, this.key = `${n}:transport:queue`, this.load();
5327
- }
5328
- load() {
5329
- if (this.cfg.storage === "localStorage" && pn())
5330
- try {
5331
- this.items = JSON.parse(localStorage.getItem(this.key) || "[]");
5332
- } catch {
5333
- this.items = [];
5054
+ this.items = [];
5334
5055
  }
5335
5056
  }
5336
5057
  save() {
5337
- if (this.cfg.storage === "localStorage" && pn())
5058
+ if (this.cfg.storage === "localStorage" && mn())
5338
5059
  try {
5339
5060
  localStorage.setItem(this.key, JSON.stringify(this.items));
5340
5061
  } catch {
@@ -5368,13 +5089,13 @@ class wi {
5368
5089
  return this.save(), { flushed: n, failed: a };
5369
5090
  }
5370
5091
  }
5371
- const fn = /* @__PURE__ */ new Set(["POST", "PUT", "PATCH", "DELETE"]);
5372
- function Ni(e) {
5373
- const t = e.fetch ?? globalThis.fetch, n = { ...bi, ...e.retry }, a = { ...gi, ...e.idempotency }, r = { ...vi, ...e.offlineQueue }, s = e.timeoutMs ?? 15e3, u = e.credentials ?? "same-origin", m = new wi(r, "calcsuite");
5092
+ const hn = /* @__PURE__ */ new Set(["POST", "PUT", "PATCH", "DELETE"]);
5093
+ function fi(e) {
5094
+ const t = e.fetch ?? globalThis.fetch, n = { ...ui, ...e.retry }, a = { ...di, ...e.idempotency }, r = { ...mi, ...e.offlineQueue }, s = e.timeoutMs ?? 15e3, u = e.credentials ?? "same-origin", m = new hi(r, "calcsuite");
5374
5095
  function d(N, P) {
5375
5096
  const x = e.endpoints[N];
5376
5097
  if (!x) throw new z(`Endpoint "${N}" is not configured`, { code: "no_endpoint" });
5377
- let T = /^https?:\/\//i.test(x) ? x : xi(e.baseUrl, x);
5098
+ let T = /^https?:\/\//i.test(x) ? x : yi(e.baseUrl, x);
5378
5099
  return P != null && (T = T.replace(/:id\b/, encodeURIComponent(P))), T;
5379
5100
  }
5380
5101
  function i() {
@@ -5387,9 +5108,9 @@ function Ni(e) {
5387
5108
  }
5388
5109
  function l(N, P, x) {
5389
5110
  if (!a.enabled || x) return x;
5390
- if (fn.has(yn(N))) {
5111
+ if (hn.has(fn(N))) {
5391
5112
  if (a.keyFrom === "inputsHash") {
5392
- const T = Ci(P);
5113
+ const T = gi(P);
5393
5114
  if (T) return T;
5394
5115
  }
5395
5116
  return ra();
@@ -5419,21 +5140,21 @@ function Ni(e) {
5419
5140
  }
5420
5141
  async function f(N, P = {}) {
5421
5142
  var B, G, q, A;
5422
- const x = yn(N), T = Si(d(N, P.pathParam), P.query), $ = l(N, P.body, P.idempotencyKey);
5143
+ const x = fn(N), T = bi(d(N, P.pathParam), P.query), $ = l(N, P.body, P.idempotencyKey);
5423
5144
  let L;
5424
5145
  for (let I = 1; I <= Math.max(1, n.attempts); I++) {
5425
- const E = await c(), j = {
5146
+ const R = await c(), j = {
5426
5147
  "content-type": "application/json",
5427
5148
  ...i(),
5428
5149
  ...P.headers ?? {},
5429
- ...E.headers
5150
+ ...R.headers
5430
5151
  };
5431
5152
  $ && (j[a.headerName] = $);
5432
- const Y = Mt(j, E.keys);
5153
+ const Y = $t(j, R.keys);
5433
5154
  let V = P.body;
5434
5155
  const Q = { endpoint: String(N), method: x, url: T, headers: Y, body: V, attempt: I };
5435
5156
  e.transformRequest && V !== void 0 && (V = e.transformRequest(V, Q)), (B = e.onRequest) == null || B.call(e, Q);
5436
- const Re = bn();
5157
+ const Ee = yn();
5437
5158
  try {
5438
5159
  const K = await p(
5439
5160
  T,
@@ -5446,14 +5167,14 @@ function Ni(e) {
5446
5167
  P.signal
5447
5168
  );
5448
5169
  if (!K.ok && n.retryOn.includes(K.status) && I < n.attempts) {
5449
- await hn(h(I, K));
5170
+ await pn(h(I, K));
5450
5171
  continue;
5451
5172
  }
5452
5173
  const pe = await ia(K), Me = {
5453
5174
  ...Q,
5454
5175
  status: K.status,
5455
5176
  ok: K.ok,
5456
- durationMs: bn() - Re,
5177
+ durationMs: yn() - Ee,
5457
5178
  data: pe
5458
5179
  };
5459
5180
  if ((G = e.onResponse) == null || G.call(e, Me), !K.ok) {
@@ -5468,10 +5189,10 @@ function Ni(e) {
5468
5189
  } catch (K) {
5469
5190
  if (L = K, K instanceof z && K.code === "http_error") throw K;
5470
5191
  if (I < n.attempts) {
5471
- await hn(h(I));
5192
+ await pn(h(I));
5472
5193
  continue;
5473
5194
  }
5474
- if (r.enabled && fn.has(x))
5195
+ if (r.enabled && hn.has(x))
5475
5196
  return { queued: !0, id: m.enqueue({
5476
5197
  endpoint: String(N),
5477
5198
  method: x,
@@ -5488,7 +5209,7 @@ function Ni(e) {
5488
5209
  }
5489
5210
  async function y(N, P, x = {}) {
5490
5211
  const T = e.upload;
5491
- Ti(N, P, T.accept, T.maxBytes);
5212
+ ki(N, P, T.accept, T.maxBytes);
5492
5213
  const $ = P.filename ?? oa(T.filenameTemplate, P), L = { ...P, filename: $, bytes: N.size, contentType: P.contentType ?? sa(N) };
5493
5214
  if (T.beforeUpload && !await T.beforeUpload(N, L))
5494
5215
  throw new z("Upload cancelled by host", { code: "upload_cancelled" });
@@ -5520,10 +5241,10 @@ function Ni(e) {
5520
5241
  { method: "POST", credentials: u, headers: B, body: $ },
5521
5242
  x.signal
5522
5243
  );
5523
- return Pi(G);
5244
+ return vi(G);
5524
5245
  }
5525
5246
  async function S(N, P, x) {
5526
- const T = await Fi(N);
5247
+ const T = await wi(N);
5527
5248
  return f("upload", {
5528
5249
  ...x,
5529
5250
  body: {
@@ -5594,7 +5315,7 @@ function Ni(e) {
5594
5315
  }
5595
5316
  };
5596
5317
  }
5597
- function yn(e) {
5318
+ function fn(e) {
5598
5319
  switch (e) {
5599
5320
  case "save":
5600
5321
  case "upload":
@@ -5607,20 +5328,20 @@ function yn(e) {
5607
5328
  return "GET";
5608
5329
  }
5609
5330
  }
5610
- function bn() {
5331
+ function yn() {
5611
5332
  return typeof performance < "u" && performance.now ? performance.now() : Date.now();
5612
5333
  }
5613
- function xi(e, t) {
5334
+ function yi(e, t) {
5614
5335
  return e ? `${e.replace(/\/+$/, "")}/${t.replace(/^\/+/, "")}` : t;
5615
5336
  }
5616
- function Si(e, t) {
5337
+ function bi(e, t) {
5617
5338
  if (!t) return e;
5618
5339
  const n = [];
5619
5340
  for (const [a, r] of Object.entries(t))
5620
5341
  r == null || r === "" || n.push(`${encodeURIComponent(a)}=${encodeURIComponent(String(r))}`);
5621
5342
  return n.length ? e + (e.includes("?") ? "&" : "?") + n.join("&") : e;
5622
5343
  }
5623
- function Ci(e) {
5344
+ function gi(e) {
5624
5345
  var a;
5625
5346
  if (!e || typeof e != "object") return;
5626
5347
  const t = e, n = ((a = t == null ? void 0 : t.meta) == null ? void 0 : a.inputsHash) ?? (t == null ? void 0 : t.inputsHash);
@@ -5634,21 +5355,21 @@ async function ia(e) {
5634
5355
  return null;
5635
5356
  }
5636
5357
  }
5637
- async function Pi(e) {
5358
+ async function vi(e) {
5638
5359
  if (!e.ok) throw new z(`Upload failed (${e.status})`, { code: "upload_failed", status: e.status });
5639
5360
  return ia(e);
5640
5361
  }
5641
5362
  function sa(e) {
5642
5363
  return e.type || "application/octet-stream";
5643
5364
  }
5644
- function Ti(e, t, n, a) {
5365
+ function ki(e, t, n, a) {
5645
5366
  if (e.size > a)
5646
5367
  throw new z(`File exceeds ${a} bytes`, { code: "too_large" });
5647
5368
  const r = t.contentType ?? sa(e);
5648
5369
  if (n.length && r && !n.includes(r))
5649
5370
  throw new z(`Content type ${r} not accepted`, { code: "bad_type" });
5650
5371
  }
5651
- async function Fi(e) {
5372
+ async function wi(e) {
5652
5373
  const t = await e.arrayBuffer(), n = new Uint8Array(t);
5653
5374
  if (typeof btoa == "function") {
5654
5375
  let r = "";
@@ -5668,7 +5389,7 @@ function We(e, t) {
5668
5389
  }
5669
5390
  return n;
5670
5391
  }
5671
- function gn(e, t, n) {
5392
+ function bn(e, t, n) {
5672
5393
  const a = t.split(".");
5673
5394
  let r = e;
5674
5395
  for (let s = 0; s < a.length - 1; s++) {
@@ -5677,15 +5398,15 @@ function gn(e, t, n) {
5677
5398
  }
5678
5399
  r[a[a.length - 1]] = n;
5679
5400
  }
5680
- function Ii(e, t) {
5401
+ function Ni(e, t) {
5681
5402
  if (t === "asIs") return e;
5682
5403
  const n = e.replace(/([a-z0-9])([A-Z])/g, "$1 $2").replace(/[_\-\s]+/g, " ").trim().split(" ").filter(Boolean);
5683
5404
  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("");
5684
5405
  }
5685
- function vn(e, t) {
5686
- return e.split(".").map((n) => Ii(n, t)).join(".");
5406
+ function gn(e, t) {
5407
+ return e.split(".").map((n) => Ni(n, t)).join(".");
5687
5408
  }
5688
- function Ei(e, t) {
5409
+ function xi(e, t) {
5689
5410
  switch (t) {
5690
5411
  case "toFixed2":
5691
5412
  return Number(e).toFixed(2);
@@ -5702,11 +5423,11 @@ function Ei(e, t) {
5702
5423
  return e;
5703
5424
  }
5704
5425
  }
5705
- function Ri(e, t) {
5426
+ function Si(e, t) {
5706
5427
  const n = e instanceof Date ? e : new Date(e);
5707
5428
  return Number.isNaN(n.getTime()) ? String(e) : n.toISOString();
5708
5429
  }
5709
- function Mi(e, t, n) {
5430
+ function Ci(e, t, n) {
5710
5431
  switch (t) {
5711
5432
  case "number": {
5712
5433
  if (n.numberEncoding === "number") {
@@ -5718,7 +5439,7 @@ function Mi(e, t, n) {
5718
5439
  case "boolean":
5719
5440
  return typeof e == "string" ? e.toLowerCase() === "true" : !!e;
5720
5441
  case "date":
5721
- return Ri(e, n.dateFormat);
5442
+ return Si(e, n.dateFormat);
5722
5443
  case "json":
5723
5444
  return e;
5724
5445
  case "string":
@@ -5726,18 +5447,18 @@ function Mi(e, t, n) {
5726
5447
  return String(e);
5727
5448
  }
5728
5449
  }
5729
- function nt(e, t) {
5450
+ function at(e, t) {
5730
5451
  if (t === "number") return e;
5731
5452
  if (typeof e == "number") return String(e);
5732
- if (Array.isArray(e)) return e.map((n) => nt(n, t));
5453
+ if (Array.isArray(e)) return e.map((n) => at(n, t));
5733
5454
  if (e && typeof e == "object") {
5734
5455
  const n = {};
5735
- for (const [a, r] of Object.entries(e)) n[a] = nt(r, t);
5456
+ for (const [a, r] of Object.entries(e)) n[a] = at(r, t);
5736
5457
  return n;
5737
5458
  }
5738
5459
  return e;
5739
5460
  }
5740
- function $i(e, t) {
5461
+ function Pi(e, t) {
5741
5462
  var n;
5742
5463
  switch (e.kind) {
5743
5464
  case "static":
@@ -5758,22 +5479,22 @@ function $i(e, t) {
5758
5479
  return;
5759
5480
  }
5760
5481
  }
5761
- function Ai(e, t, n) {
5482
+ function Ti(e, t, n) {
5762
5483
  const a = {};
5763
5484
  for (const u of e) {
5764
- let m = $i(u.source, n);
5485
+ let m = Pi(u.source, n);
5765
5486
  const d = m === "" || m == null;
5766
5487
  if (u.omitWhenEmpty && d) continue;
5767
- const i = vn(u.key, t.keyCase);
5488
+ const i = gn(u.key, t.keyCase);
5768
5489
  if (d) {
5769
5490
  if (t.nullHandling === "omit") continue;
5770
- gn(a, i, null);
5491
+ bn(a, i, null);
5771
5492
  continue;
5772
5493
  }
5773
- u.transform && u.transform !== "none" && (m = Ei(m, u.transform)), gn(a, i, Mi(m, u.type, t));
5494
+ u.transform && u.transform !== "none" && (m = xi(m, u.transform)), bn(a, i, Ci(m, u.type, t));
5774
5495
  }
5775
5496
  const r = t.include, s = (u, m) => {
5776
- m !== void 0 && (a[vn(u, t.keyCase)] = nt(m, t.numberEncoding));
5497
+ m !== void 0 && (a[gn(u, t.keyCase)] = at(m, t.numberEncoding));
5777
5498
  };
5778
5499
  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;
5779
5500
  }
@@ -5785,8 +5506,8 @@ const ys = {
5785
5506
  numberEncoding: "string",
5786
5507
  include: { inputs: !0, outputs: !0, schedule: !1, settingsSnapshot: !0, meta: !0 }
5787
5508
  };
5788
- function kn(e) {
5789
- return nt(e, "string");
5509
+ function vn(e) {
5510
+ return at(e, "string");
5790
5511
  }
5791
5512
  function bs(e) {
5792
5513
  const t = e.settings;
@@ -5800,7 +5521,7 @@ function bs(e) {
5800
5521
  locale: e.locale ?? t.locale,
5801
5522
  ...e.title ? { title: e.title } : {},
5802
5523
  ...e.tags && e.tags.length ? { tags: e.tags } : {},
5803
- inputs: kn(e.inputs),
5524
+ inputs: vn(e.inputs),
5804
5525
  settingsSnapshot: {
5805
5526
  rounding: {
5806
5527
  money: t.rounding.money,
@@ -5813,7 +5534,7 @@ function bs(e) {
5813
5534
  dayCount: t.dayCount,
5814
5535
  numberFormat: { grouping: t.numberFormat.grouping, decimalPlaces: t.numberFormat.decimalPlaces }
5815
5536
  },
5816
- outputs: kn(e.outputs),
5537
+ outputs: vn(e.outputs),
5817
5538
  meta: {
5818
5539
  inputsHash: e.inputsHash,
5819
5540
  computedAt: e.computedAt ?? (/* @__PURE__ */ new Date()).toISOString(),
@@ -5822,17 +5543,17 @@ function bs(e) {
5822
5543
  warnings: e.warnings ?? []
5823
5544
  },
5824
5545
  ...e.attachments && e.attachments.length ? { attachments: e.attachments } : {},
5825
- client: { tz: e.clientTz ?? Di(), platform: "web" }
5546
+ client: { tz: e.clientTz ?? Fi(), platform: "web" }
5826
5547
  };
5827
5548
  }
5828
- function Di() {
5549
+ function Fi() {
5829
5550
  try {
5830
5551
  return Intl.DateTimeFormat().resolvedOptions().timeZone || "UTC";
5831
5552
  } catch {
5832
5553
  return "UTC";
5833
5554
  }
5834
5555
  }
5835
- const He = ["save", "update", "get", "list", "delete", "upload", "uploadUrl", "rates", "settings"], Li = {
5556
+ const He = ["save", "update", "get", "list", "delete", "upload", "uploadUrl", "rates", "settings"], Ii = {
5836
5557
  save: "POST",
5837
5558
  update: "PUT",
5838
5559
  get: "GET",
@@ -5842,7 +5563,7 @@ const He = ["save", "update", "get", "list", "delete", "upload", "uploadUrl", "r
5842
5563
  uploadUrl: "GET",
5843
5564
  rates: "GET",
5844
5565
  settings: "GET"
5845
- }, la = ["bearer", "apiKeyHeader", "basic", "custom"], Ui = {
5566
+ }, la = ["bearer", "apiKeyHeader", "basic", "custom"], Ri = {
5846
5567
  strategy: "multipart",
5847
5568
  fieldName: "file",
5848
5569
  maxBytes: 10 * 1024 * 1024,
@@ -5854,7 +5575,7 @@ const He = ["save", "update", "get", "list", "delete", "upload", "uploadUrl", "r
5854
5575
  function ca() {
5855
5576
  const e = {};
5856
5577
  for (const t of He)
5857
- e[t] = { path: `/calculations${t === "save" || t === "list" ? "" : t === "get" || t === "update" || t === "delete" ? "/:id" : "/" + t}`, method: Li[t], enabled: t === "save" || t === "list" };
5578
+ e[t] = { path: `/calculations${t === "save" || t === "list" ? "" : t === "get" || t === "update" || t === "delete" ? "/:id" : "/" + t}`, method: Ii[t], enabled: t === "save" || t === "list" };
5858
5579
  return {
5859
5580
  baseUrl: "https://api.example.com/v1",
5860
5581
  auth: { strategy: "bearer", headerName: "Authorization" },
@@ -5862,17 +5583,17 @@ function ca() {
5862
5583
  credentials: "same-origin",
5863
5584
  retry: { attempts: 3, backoff: "exponential", baseDelayMs: 300, retryOn: [408, 429, 500, 502, 503, 504], respectRetryAfter: !0 },
5864
5585
  endpoints: e,
5865
- upload: Ui
5586
+ upload: Ri
5866
5587
  };
5867
5588
  }
5868
- const Oi = {
5589
+ const Ei = {
5869
5590
  mode: "flat",
5870
5591
  keyCase: "asIs",
5871
5592
  dateFormat: "iso",
5872
5593
  nullHandling: "omit",
5873
5594
  numberEncoding: "string",
5874
5595
  include: { inputs: !0, outputs: !0, schedule: !1, settingsSnapshot: !0, meta: !0 }
5875
- }, Bi = [
5596
+ }, Mi = [
5876
5597
  { key: "calculator", source: { kind: "context", path: "calculator" }, type: "string", required: !0, omitWhenEmpty: !1 },
5877
5598
  { key: "principal", source: { kind: "input", path: "principal" }, type: "number", required: !0, omitWhenEmpty: !1 },
5878
5599
  { key: "payment", source: { kind: "output", path: "payment" }, type: "number", required: !1, omitWhenEmpty: !1 },
@@ -5883,7 +5604,7 @@ const Oi = {
5883
5604
  calculator: "loan.emi",
5884
5605
  inputsHash: "sha256:9f2c1a44e0"
5885
5606
  };
5886
- function wn(e) {
5607
+ function kn(e) {
5887
5608
  if (e < 1024) return `${e} B`;
5888
5609
  const t = ["KB", "MB", "GB"];
5889
5610
  let n = e / 1024, a = 0;
@@ -5909,9 +5630,9 @@ function ua(e, t, n) {
5909
5630
  function qe(e, t) {
5910
5631
  return t ? /^https?:\/\//i.test(t) ? t : `${e.replace(/\/+$/, "")}/${t.replace(/^\/+/, "")}` : e;
5911
5632
  }
5912
- const _i = ["Connection", "Endpoints", "Upload", "Payload", "Test", "cURL", "Queue"];
5913
- function Hi({ hostConfig: e, getToken: t } = {}) {
5914
- const { settings: n } = ue(), [a, r] = M("Connection"), [s, u] = M(ca), [m, d] = M(Oi), [i, c] = M(Bi);
5633
+ const $i = ["Connection", "Endpoints", "Upload", "Payload", "Test", "cURL", "Queue"];
5634
+ function da({ hostConfig: e, getToken: t } = {}) {
5635
+ const { settings: n } = ue(), [a, r] = M("Connection"), [s, u] = M(ca), [m, d] = M(Ei), [i, c] = M(Mi);
5915
5636
  if (!n.features.integrationPanel)
5916
5637
  return /* @__PURE__ */ o("section", { className: "card", "data-part": "integration-panel", children: /* @__PURE__ */ b("div", { className: "panel-head", children: [
5917
5638
  /* @__PURE__ */ o("h2", { children: "Integration" }),
@@ -5933,12 +5654,12 @@ function Hi({ hostConfig: e, getToken: t } = {}) {
5933
5654
  /* @__PURE__ */ o("h2", { children: "Integration" }),
5934
5655
  /* @__PURE__ */ o("p", { children: "Point the library at your backend without a code change. Nothing here stores a secret." })
5935
5656
  ] }),
5936
- /* @__PURE__ */ o("div", { className: "tabs", role: "tablist", "aria-label": "Integration settings", children: _i.map((f) => /* @__PURE__ */ o("button", { role: "tab", "aria-selected": a === f, onClick: () => r(f), children: f }, f)) }),
5657
+ /* @__PURE__ */ o("div", { className: "tabs", role: "tablist", "aria-label": "Integration settings", children: $i.map((f) => /* @__PURE__ */ o("button", { role: "tab", "aria-selected": a === f, onClick: () => r(f), children: f }, f)) }),
5937
5658
  /* @__PURE__ */ b("div", { role: "tabpanel", "aria-label": a, children: [
5938
- a === "Connection" && /* @__PURE__ */ o(qi, { cfg: s, patch: p, hostLocked: l, getToken: t }),
5939
- a === "Endpoints" && /* @__PURE__ */ o(Gi, { cfg: s, setCfg: u, locked: l("endpoints") }),
5659
+ a === "Connection" && /* @__PURE__ */ o(Ai, { cfg: s, patch: p, hostLocked: l, getToken: t }),
5660
+ a === "Endpoints" && /* @__PURE__ */ o(Di, { cfg: s, setCfg: u, locked: l("endpoints") }),
5940
5661
  a === "Upload" && /* @__PURE__ */ o(
5941
- ji,
5662
+ Li,
5942
5663
  {
5943
5664
  upload: s.upload,
5944
5665
  baseUrl: s.baseUrl,
@@ -5948,7 +5669,7 @@ function Hi({ hostConfig: e, getToken: t } = {}) {
5948
5669
  }
5949
5670
  ),
5950
5671
  a === "Payload" && /* @__PURE__ */ o(
5951
- zi,
5672
+ Hi,
5952
5673
  {
5953
5674
  fields: i,
5954
5675
  setFields: c,
@@ -5957,11 +5678,11 @@ function Hi({ hostConfig: e, getToken: t } = {}) {
5957
5678
  ctx: h
5958
5679
  }
5959
5680
  ),
5960
- a === "Test" && /* @__PURE__ */ o(Zi, { cfg: s, getToken: t }),
5961
- a === "cURL" && /* @__PURE__ */ o(Xi, { cfg: s }),
5962
- a === "Queue" && /* @__PURE__ */ o(Qi, { cfg: s, getToken: t })
5681
+ a === "Test" && /* @__PURE__ */ o(Gi, { cfg: s, getToken: t }),
5682
+ a === "cURL" && /* @__PURE__ */ o(ji, { cfg: s }),
5683
+ a === "Queue" && /* @__PURE__ */ o(Vi, { cfg: s, getToken: t })
5963
5684
  ] }),
5964
- /* @__PURE__ */ o(es, { cfg: s, setCfg: u })
5685
+ /* @__PURE__ */ o(Yi, { cfg: s, setCfg: u })
5965
5686
  ] });
5966
5687
  }
5967
5688
  function Fe({ on: e, children: t }) {
@@ -6012,7 +5733,7 @@ function le({
6012
5733
  /* @__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)) }) })
6013
5734
  ] });
6014
5735
  }
6015
- function qi({
5736
+ function Ai({
6016
5737
  cfg: e,
6017
5738
  patch: t,
6018
5739
  hostLocked: n,
@@ -6071,7 +5792,7 @@ function qi({
6071
5792
  )
6072
5793
  ] });
6073
5794
  }
6074
- function Gi({ cfg: e, setCfg: t, locked: n }) {
5795
+ function Di({ cfg: e, setCfg: t, locked: n }) {
6075
5796
  const a = (r, s) => t((u) => ({ ...u, endpoints: { ...u.endpoints, [r]: { ...u.endpoints[r], ...s } } }));
6076
5797
  return /* @__PURE__ */ o(Fe, { on: n, children: /* @__PURE__ */ o("div", { className: "int-table-wrap", children: /* @__PURE__ */ b("table", { className: "int-table", children: [
6077
5798
  /* @__PURE__ */ o("thead", { children: /* @__PURE__ */ b("tr", { children: [
@@ -6094,7 +5815,7 @@ function Gi({ cfg: e, setCfg: t, locked: n }) {
6094
5815
  }) })
6095
5816
  ] }) }) });
6096
5817
  }
6097
- function ji({ upload: e, baseUrl: t, uploadUri: n, onChange: a, locked: r }) {
5818
+ function Li({ upload: e, baseUrl: t, uploadUri: n, onChange: a, locked: r }) {
6098
5819
  var m, d, i;
6099
5820
  const s = (c) => a({ ...e, ...c }), u = ne(
6100
5821
  () => oa(e.filenameTemplate, { calculator: "loan.emi", kind: "pdf", inputsHash: Ue.inputsHash, filename: "x.pdf" }),
@@ -6104,7 +5825,7 @@ function ji({ upload: e, baseUrl: t, uploadUri: n, onChange: a, locked: r }) {
6104
5825
  /* @__PURE__ */ o(te, { label: "Upload URI", value: n, readOnly: !0, help: "Resolved from baseUrl + the 'upload' endpoint path (edit it under Endpoints)" }),
6105
5826
  /* @__PURE__ */ o(le, { label: "Strategy", value: e.strategy, options: ["multipart", "presigned", "base64Json"], onChange: (c) => s({ strategy: c }) }),
6106
5827
  /* @__PURE__ */ o(te, { label: "Field name", value: e.fieldName, onChange: (c) => s({ fieldName: c }) }),
6107
- /* @__PURE__ */ o(te, { label: "Max bytes", type: "number", value: String(e.maxBytes), onChange: (c) => s({ maxBytes: Number(c) || 0 }), affix: wn(e.maxBytes) }),
5828
+ /* @__PURE__ */ o(te, { label: "Max bytes", type: "number", value: String(e.maxBytes), onChange: (c) => s({ maxBytes: Number(c) || 0 }), affix: kn(e.maxBytes) }),
6108
5829
  /* @__PURE__ */ b("div", { className: "field span2", children: [
6109
5830
  /* @__PURE__ */ o(te, { label: "Filename template", value: e.filenameTemplate, onChange: (c) => s({ filenameTemplate: c }), help: "{calculator} {yyyy} {MM} {dd} {hash8} {ext}" }),
6110
5831
  /* @__PURE__ */ b("div", { className: "int-note mono", children: [
@@ -6132,7 +5853,7 @@ function ji({ upload: e, baseUrl: t, uploadUri: n, onChange: a, locked: r }) {
6132
5853
  }
6133
5854
  )
6134
5855
  ] }),
6135
- ((i = e.chunked) == null ? void 0 : i.enabled) && /* @__PURE__ */ o(te, { label: "Chunk size", type: "number", value: String(e.chunked.chunkBytes), onChange: (c) => s({ chunked: { enabled: !0, chunkBytes: Number(c) || 1 } }), affix: wn(e.chunked.chunkBytes) }),
5856
+ ((i = e.chunked) == null ? void 0 : i.enabled) && /* @__PURE__ */ o(te, { label: "Chunk size", type: "number", value: String(e.chunked.chunkBytes), onChange: (c) => s({ chunked: { enabled: !0, chunkBytes: Number(c) || 1 } }), affix: kn(e.chunked.chunkBytes) }),
6136
5857
  e.strategy === "presigned" && /* @__PURE__ */ b("div", { className: "span2 int-subform", children: [
6137
5858
  /* @__PURE__ */ b("div", { className: "int-note", children: [
6138
5859
  /* @__PURE__ */ o("strong", { children: "Presigned sub-form" }),
@@ -6149,14 +5870,14 @@ function ji({ upload: e, baseUrl: t, uploadUri: n, onChange: a, locked: r }) {
6149
5870
  ] })
6150
5871
  ] }) });
6151
5872
  }
6152
- const Vi = ["static", "input", "output", "setting", "context", "token", "callback"];
6153
- function Yi(e) {
5873
+ const Ui = ["static", "input", "output", "setting", "context", "token", "callback"];
5874
+ function Oi(e) {
6154
5875
  return e.kind === "static" ? String(e.value) : e.kind === "token" ? e.name : e.kind === "callback" ? "fn()" : e.path;
6155
5876
  }
6156
- function Ki(e, t) {
5877
+ function Bi(e, t) {
6157
5878
  return e.kind === "static" ? { kind: "static", value: t } : e.kind === "token" ? { kind: "token", name: t } : e.kind === "callback" ? e : { kind: e.kind, path: t };
6158
5879
  }
6159
- function Wi(e) {
5880
+ function _i(e) {
6160
5881
  switch (e) {
6161
5882
  case "static":
6162
5883
  return { kind: "static", value: "" };
@@ -6168,7 +5889,7 @@ function Wi(e) {
6168
5889
  return { kind: e, path: "" };
6169
5890
  }
6170
5891
  }
6171
- function zi({
5892
+ function Hi({
6172
5893
  fields: e,
6173
5894
  setFields: t,
6174
5895
  envelope: n,
@@ -6177,7 +5898,7 @@ function zi({
6177
5898
  }) {
6178
5899
  const s = ne(() => {
6179
5900
  try {
6180
- return JSON.stringify(Ai(e, n, r), null, 2);
5901
+ return JSON.stringify(Ti(e, n, r), null, 2);
6181
5902
  } catch (i) {
6182
5903
  return `// ${i instanceof Error ? i.message : "preview failed"}`;
6183
5904
  }
@@ -6218,13 +5939,13 @@ function zi({
6218
5939
  ] }) }),
6219
5940
  /* @__PURE__ */ o("tbody", { children: e.map((i, c) => /* @__PURE__ */ b("tr", { children: [
6220
5941
  /* @__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" }) }),
6221
- /* @__PURE__ */ o("td", { children: /* @__PURE__ */ o("select", { value: i.source.kind, onChange: (l) => u(c, { source: Wi(l.target.value) }), "aria-label": "source kind", children: Vi.map((l) => /* @__PURE__ */ o("option", { children: l }, l)) }) }),
5942
+ /* @__PURE__ */ o("td", { children: /* @__PURE__ */ o("select", { value: i.source.kind, onChange: (l) => u(c, { source: _i(l.target.value) }), "aria-label": "source kind", children: Ui.map((l) => /* @__PURE__ */ o("option", { children: l }, l)) }) }),
6222
5943
  /* @__PURE__ */ o("td", { children: /* @__PURE__ */ o(
6223
5944
  "input",
6224
5945
  {
6225
- value: Yi(i.source),
5946
+ value: Oi(i.source),
6226
5947
  disabled: i.source.kind === "callback",
6227
- onChange: (l) => u(c, { source: Ki(i.source, l.target.value) }),
5948
+ onChange: (l) => u(c, { source: Bi(i.source, l.target.value) }),
6228
5949
  "aria-label": "source value",
6229
5950
  className: "int-cell-input"
6230
5951
  }
@@ -6255,7 +5976,7 @@ function zi({
6255
5976
  ] })
6256
5977
  ] });
6257
5978
  }
6258
- function Ji(e, t) {
5979
+ function qi(e, t) {
6259
5980
  const n = {};
6260
5981
  for (const a of He) {
6261
5982
  const r = e.endpoints[a];
@@ -6272,7 +5993,7 @@ function Ji(e, t) {
6272
5993
  getAuth: t ? async () => ua(e.auth.strategy, e.auth.headerName, await t()) : void 0
6273
5994
  };
6274
5995
  }
6275
- function Zi({ cfg: e, getToken: t }) {
5996
+ function Gi({ cfg: e, getToken: t }) {
6276
5997
  const [n, a] = M({ loading: !1 }), [r, s] = M("save");
6277
5998
  return /* @__PURE__ */ b("div", { children: [
6278
5999
  /* @__PURE__ */ b("div", { className: "grid two", children: [
@@ -6284,9 +6005,9 @@ function Zi({ cfg: e, getToken: t }) {
6284
6005
  const c = performance.now();
6285
6006
  try {
6286
6007
  const l = await fetch(d, { method: m.method, headers: i, credentials: e.credentials }), p = await l.text(), h = {};
6287
- 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: ts(p), sent: { url: d, method: m.method, headers: Mt(i) } });
6008
+ 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: Ki(p), sent: { url: d, method: m.method, headers: $t(i) } });
6288
6009
  } catch (l) {
6289
- 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: Mt(i) } });
6010
+ 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) } });
6290
6011
  }
6291
6012
  }, disabled: n.loading, children: n.loading ? "Testing…" : "Test connection" }) })
6292
6013
  ] }),
@@ -6314,7 +6035,7 @@ ${JSON.stringify(n.sent.headers, null, 2)}` })
6314
6035
  ] })
6315
6036
  ] });
6316
6037
  }
6317
- function Xi({ cfg: e }) {
6038
+ function ji({ cfg: e }) {
6318
6039
  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" };
6319
6040
  la.includes(e.auth.strategy) && (m[e.auth.strategy === "apiKeyHeader" || e.auth.strategy === "custom" ? e.auth.headerName || "X-API-Key" : "Authorization"] = t ? "<token>" : "***");
6320
6041
  const d = [`curl -X ${s.method} '${u}'`];
@@ -6337,8 +6058,8 @@ function Xi({ cfg: e }) {
6337
6058
  }, children: "Copy" })
6338
6059
  ] });
6339
6060
  }
6340
- function Qi({ cfg: e, getToken: t }) {
6341
- const n = ne(() => Ni(Ji(e, t)), [e, t]), [a, r] = M(() => n.queue.list()), [s, u] = M(""), m = () => r(n.queue.list());
6061
+ function Vi({ cfg: e, getToken: t }) {
6062
+ const n = ne(() => fi(qi(e, t)), [e, t]), [a, r] = M(() => n.queue.list()), [s, u] = M(""), m = () => r(n.queue.list());
6342
6063
  return /* @__PURE__ */ b("div", { children: [
6343
6064
  /* @__PURE__ */ b("div", { className: "actions-row", style: { marginTop: 0 }, children: [
6344
6065
  /* @__PURE__ */ o("button", { type: "button", className: "icon-btn", onClick: m, children: "Refresh" }),
@@ -6367,7 +6088,7 @@ function Qi({ cfg: e, getToken: t }) {
6367
6088
  ] }) })
6368
6089
  ] });
6369
6090
  }
6370
- function es({ cfg: e, setCfg: t }) {
6091
+ function Yi({ cfg: e, setCfg: t }) {
6371
6092
  const [n, a] = M(""), [r, s] = M("");
6372
6093
  return /* @__PURE__ */ b("div", { className: "accordion", style: { marginTop: 20 }, children: [
6373
6094
  /* @__PURE__ */ o("span", { className: "lbl", children: "Import / export config (JSON)" }),
@@ -6390,20 +6111,312 @@ function es({ cfg: e, setCfg: t }) {
6390
6111
  r && /* @__PURE__ */ o("div", { className: "int-note", children: r })
6391
6112
  ] });
6392
6113
  }
6393
- function ts(e) {
6114
+ function Ki(e) {
6394
6115
  try {
6395
6116
  return JSON.stringify(JSON.parse(e), null, 2);
6396
6117
  } catch {
6397
6118
  return e;
6398
6119
  }
6399
6120
  }
6121
+ const Wi = "1234567.891";
6122
+ function zi() {
6123
+ const { settings: e, update: t, setRegion: n, reset: a, replace: r } = ue(), s = de(null), u = Sn(e).money(g(Wi)), m = () => {
6124
+ const i = new Blob([JSON.stringify(e, null, 2)], { type: "application/json" }), c = URL.createObjectURL(i), l = document.createElement("a");
6125
+ l.href = c, l.download = "calcsuite-settings.json", l.click(), URL.revokeObjectURL(c);
6126
+ }, d = (i) => {
6127
+ const c = new FileReader();
6128
+ c.onload = () => {
6129
+ try {
6130
+ r(JSON.parse(String(c.result)));
6131
+ } catch {
6132
+ alert("Could not read that settings file.");
6133
+ }
6134
+ }, c.readAsText(i);
6135
+ };
6136
+ return /* @__PURE__ */ b("div", { className: "settings", children: [
6137
+ /* @__PURE__ */ b("div", { className: "panel-head", children: [
6138
+ /* @__PURE__ */ o("h2", { children: "Settings" }),
6139
+ /* @__PURE__ */ b("p", { children: [
6140
+ "Everything below updates the numbers live. Sample: ",
6141
+ /* @__PURE__ */ o("strong", { className: "num", children: u })
6142
+ ] })
6143
+ ] }),
6144
+ /* @__PURE__ */ b(Te, { title: "Region & currency", children: [
6145
+ /* @__PURE__ */ o(W, { label: "Region", children: /* @__PURE__ */ b("div", { className: "seg", children: [
6146
+ /* @__PURE__ */ o("button", { "aria-pressed": e.region === "IN", onClick: () => n("IN"), children: "🇮🇳 India" }),
6147
+ /* @__PURE__ */ o("button", { "aria-pressed": e.region === "US", onClick: () => n("US"), children: "🇺🇸 United States" })
6148
+ ] }) }),
6149
+ /* @__PURE__ */ o(W, { label: "Currency symbol", children: /* @__PURE__ */ o("input", { className: "mini", value: e.currency.symbol, onChange: (i) => t({ currency: { symbol: i.target.value } }) }) }),
6150
+ /* @__PURE__ */ o(W, { label: "Symbol position", children: /* @__PURE__ */ o(
6151
+ he,
6152
+ {
6153
+ value: e.currency.symbolPosition,
6154
+ onChange: (i) => t({ currency: { symbolPosition: i } }),
6155
+ options: [["prefix", "Prefix ₹100"], ["suffix", "Suffix 100₹"]]
6156
+ }
6157
+ ) })
6158
+ ] }),
6159
+ /* @__PURE__ */ b(Te, { title: "Number format", children: [
6160
+ /* @__PURE__ */ o(W, { label: "Grouping", children: /* @__PURE__ */ o(
6161
+ he,
6162
+ {
6163
+ value: e.numberFormat.grouping,
6164
+ onChange: (i) => t({ numberFormat: { grouping: i } }),
6165
+ options: [["indian", "Indian 12,34,567"], ["western", "Western 1,234,567"], ["european", "European 1.234.567"], ["swiss", "Swiss 1'234'567"], ["plain", "Plain 1234567"]]
6166
+ }
6167
+ ) }),
6168
+ /* @__PURE__ */ o(W, { label: "Decimal places", children: /* @__PURE__ */ o("div", { className: "seg", children: [0, 1, 2, 3, 4].map((i) => /* @__PURE__ */ o("button", { "aria-pressed": e.numberFormat.decimalPlaces === i, onClick: () => t({ numberFormat: { decimalPlaces: i } }), children: i }, i)) }) }),
6169
+ /* @__PURE__ */ o(W, { label: "Abbreviate (12.5 L / 1.2 Cr)", children: /* @__PURE__ */ o(Le, { on: e.numberFormat.abbreviate, onClick: () => t({ numberFormat: { abbreviate: !e.numberFormat.abbreviate } }) }) }),
6170
+ /* @__PURE__ */ o(W, { label: "Abbreviation scale", children: /* @__PURE__ */ o(
6171
+ he,
6172
+ {
6173
+ value: e.numberFormat.abbreviationScale,
6174
+ onChange: (i) => t({ numberFormat: { abbreviationScale: i } }),
6175
+ options: [["indian", "Lakh / Crore"], ["western", "K / M / B"]]
6176
+ }
6177
+ ) }),
6178
+ /* @__PURE__ */ o(W, { label: "Negatives", children: /* @__PURE__ */ o(
6179
+ he,
6180
+ {
6181
+ value: e.numberFormat.negativeFormat,
6182
+ onChange: (i) => t({ numberFormat: { negativeFormat: i } }),
6183
+ options: [["minus", "-1,000"], ["parentheses", "(1,000)"]]
6184
+ }
6185
+ ) })
6186
+ ] }),
6187
+ /* @__PURE__ */ b(Te, { title: "Calculation", children: [
6188
+ /* @__PURE__ */ o(W, { label: "Rounding mode", children: /* @__PURE__ */ o(
6189
+ he,
6190
+ {
6191
+ value: e.rounding.mode,
6192
+ onChange: (i) => t({ rounding: { mode: i } }),
6193
+ options: [["HALF_UP", "Half up"], ["HALF_EVEN", "Half even (banker’s)"], ["HALF_DOWN", "Half down"], ["UP", "Up"], ["DOWN", "Down"], ["CEIL", "Ceil"], ["FLOOR", "Floor"]]
6194
+ }
6195
+ ) }),
6196
+ /* @__PURE__ */ o(W, { label: "Day-count convention", children: /* @__PURE__ */ o(
6197
+ he,
6198
+ {
6199
+ value: e.dayCount,
6200
+ onChange: (i) => t({ dayCount: i }),
6201
+ options: [["30/360", "30/360"], ["ACT/365", "ACT/365"], ["ACT/360", "ACT/360"], ["ACT/ACT", "ACT/ACT"], ["30E/360", "30E/360"]]
6202
+ }
6203
+ ) })
6204
+ ] }),
6205
+ /* @__PURE__ */ b(Te, { title: "Appearance", children: [
6206
+ /* @__PURE__ */ o(W, { label: "Theme", children: /* @__PURE__ */ o(
6207
+ he,
6208
+ {
6209
+ value: e.ui.theme,
6210
+ onChange: (i) => t({ ui: { theme: i } }),
6211
+ options: [["system", "System"], ["light", "Light"], ["dark", "Dark"], ["highContrast", "High contrast"]]
6212
+ }
6213
+ ) }),
6214
+ /* @__PURE__ */ o(W, { label: "Accent colour", children: /* @__PURE__ */ o("div", { className: "swatches", children: si.map((i) => {
6215
+ const c = e.ui.accent.toLowerCase() === i.main.toLowerCase();
6216
+ return /* @__PURE__ */ o(
6217
+ "button",
6218
+ {
6219
+ type: "button",
6220
+ className: `swatch ${c ? "active" : ""}`,
6221
+ style: { background: i.main },
6222
+ "aria-label": i.label,
6223
+ "aria-pressed": c,
6224
+ title: i.label,
6225
+ onClick: () => t({ ui: { accent: i.main } })
6226
+ },
6227
+ i.id
6228
+ );
6229
+ }) }) }),
6230
+ /* @__PURE__ */ o(W, { label: "Font", children: /* @__PURE__ */ o(
6231
+ he,
6232
+ {
6233
+ value: e.ui.fontFamily,
6234
+ onChange: (i) => t({ ui: { fontFamily: i } }),
6235
+ options: li.map((i) => [i.id, i.label])
6236
+ }
6237
+ ) }),
6238
+ /* @__PURE__ */ o(W, { label: "Density", children: /* @__PURE__ */ o(
6239
+ he,
6240
+ {
6241
+ value: e.ui.density,
6242
+ onChange: (i) => t({ ui: { density: i } }),
6243
+ options: [["comfortable", "Comfortable"], ["compact", "Compact"]]
6244
+ }
6245
+ ) }),
6246
+ /* @__PURE__ */ o(W, { label: "Show formulas", children: /* @__PURE__ */ o(Le, { on: e.ui.showFormulas, onClick: () => t({ ui: { showFormulas: !e.ui.showFormulas } }) }) }),
6247
+ /* @__PURE__ */ o(W, { label: "Show assumptions", children: /* @__PURE__ */ o(Le, { on: e.ui.showAssumptions, onClick: () => t({ ui: { showAssumptions: !e.ui.showAssumptions } }) }) })
6248
+ ] }),
6249
+ /* @__PURE__ */ o(Te, { title: "Compliance", children: /* @__PURE__ */ o(W, { label: "Show disclaimer", children: /* @__PURE__ */ o(Le, { on: e.compliance.showDisclaimer, onClick: () => t({ compliance: { showDisclaimer: !e.compliance.showDisclaimer } }) }) }) }),
6250
+ /* @__PURE__ */ b(Te, { title: "File upload & server API", children: [
6251
+ /* @__PURE__ */ o(W, { label: "Save & upload to your server", children: /* @__PURE__ */ o(Le, { on: e.features.integrationPanel, onClick: () => t({ features: { integrationPanel: !e.features.integrationPanel } }) }) }),
6252
+ !e.features.integrationPanel && /* @__PURE__ */ b("p", { style: { fontSize: 12, color: "var(--fc-slate)", margin: "8px 0 0" }, children: [
6253
+ "Turn this on to configure your ",
6254
+ /* @__PURE__ */ o("strong", { children: "upload URL, authentication, and payload" }),
6255
+ " — so exports (PDF/CSV/…) and saved calculations post directly to your own server. No secret is ever stored by the app."
6256
+ ] })
6257
+ ] }),
6258
+ e.features.integrationPanel && /* @__PURE__ */ o(da, {}),
6259
+ /* @__PURE__ */ b("div", { className: "actions-row", children: [
6260
+ /* @__PURE__ */ o("button", { className: "icon-btn", onClick: m, children: "Export settings" }),
6261
+ /* @__PURE__ */ o("button", { className: "icon-btn", onClick: () => {
6262
+ var i;
6263
+ return (i = s.current) == null ? void 0 : i.click();
6264
+ }, children: "Import settings" }),
6265
+ /* @__PURE__ */ o("button", { className: "icon-btn", onClick: a, children: "Reset to defaults" }),
6266
+ /* @__PURE__ */ o("input", { ref: s, type: "file", accept: "application/json", hidden: !0, onChange: (i) => {
6267
+ var c;
6268
+ return ((c = i.target.files) == null ? void 0 : c[0]) && d(i.target.files[0]);
6269
+ } })
6270
+ ] })
6271
+ ] });
6272
+ }
6273
+ function Te({ title: e, children: t }) {
6274
+ return /* @__PURE__ */ b("section", { className: "card settings-section", children: [
6275
+ /* @__PURE__ */ o("h3", { children: e }),
6276
+ t
6277
+ ] });
6278
+ }
6279
+ function W({ label: e, children: t }) {
6280
+ return /* @__PURE__ */ b("div", { className: "settings-row", children: [
6281
+ /* @__PURE__ */ o("span", { className: "lbl", children: e }),
6282
+ /* @__PURE__ */ o("div", { children: t })
6283
+ ] });
6284
+ }
6285
+ function he({ value: e, onChange: t, options: n }) {
6286
+ return /* @__PURE__ */ o("div", { className: "input-wrap mini-wrap", children: /* @__PURE__ */ o("select", { value: e, onChange: (a) => t(a.target.value), children: n.map(([a, r]) => /* @__PURE__ */ o("option", { value: a, children: r }, a)) }) });
6287
+ }
6288
+ function Le({ on: e, onClick: t }) {
6289
+ return /* @__PURE__ */ o("button", { type: "button", role: "switch", "aria-checked": e, className: `toggle ${e ? "on" : ""}`, onClick: t, children: /* @__PURE__ */ o("span", { className: "knob" }) });
6290
+ }
6291
+ function Ji({
6292
+ items: e,
6293
+ onRestore: t,
6294
+ onClear: n
6295
+ }) {
6296
+ return /* @__PURE__ */ b("div", { className: "history", children: [
6297
+ /* @__PURE__ */ b("div", { className: "panel-head", style: { display: "flex", justifyContent: "space-between", alignItems: "flex-end" }, children: [
6298
+ /* @__PURE__ */ b("div", { children: [
6299
+ /* @__PURE__ */ o("h2", { children: "History" }),
6300
+ /* @__PURE__ */ o("p", { children: "Your recent calculations, saved on this device." })
6301
+ ] }),
6302
+ e.length > 0 && /* @__PURE__ */ o("button", { className: "icon-btn", onClick: n, children: "Clear all" })
6303
+ ] }),
6304
+ e.length === 0 ? /* @__PURE__ */ o("div", { className: "card empty", children: "No saved calculations yet. Compute something and press Save." }) : /* @__PURE__ */ o("div", { className: "card", style: { padding: 0 }, children: /* @__PURE__ */ o("ul", { className: "history-list", children: e.map((a, r) => /* @__PURE__ */ o("li", { children: /* @__PURE__ */ b("button", { className: "history-item", onClick: () => t(a), children: [
6305
+ /* @__PURE__ */ b("div", { children: [
6306
+ /* @__PURE__ */ o("div", { className: "history-title", children: a.title }),
6307
+ /* @__PURE__ */ o("div", { className: "history-when", children: new Date(a.at).toLocaleString() })
6308
+ ] }),
6309
+ /* @__PURE__ */ o("div", { className: "history-value num", children: a.primary })
6310
+ ] }) }, r)) }) })
6311
+ ] });
6312
+ }
6313
+ function wn(e, t) {
6314
+ const n = t.toLowerCase(), a = n.indexOf(e);
6315
+ if (a >= 0) return 100 - a;
6316
+ let r = 0;
6317
+ for (let s = 0; s < n.length && r < e.length; s++) n[s] === e[r] && r++;
6318
+ return r === e.length ? 10 : -1;
6319
+ }
6320
+ function Zi({
6321
+ calculators: e,
6322
+ actions: t,
6323
+ onPick: n,
6324
+ onClose: a
6325
+ }) {
6326
+ const [r, s] = M(""), [u, m] = M(0), d = de(null);
6327
+ X(() => {
6328
+ var l;
6329
+ return (l = d.current) == null ? void 0 : l.focus();
6330
+ }, []), X(() => (wa(), () => Na()), []);
6331
+ const i = ne(() => {
6332
+ const l = e.map((y) => ({
6333
+ key: `calc:${y.id}`,
6334
+ label: y.title,
6335
+ group: y.group,
6336
+ hint: y.blurb,
6337
+ run: () => n(y.id)
6338
+ })), p = t.map((y) => ({ key: `act:${y.id}`, label: y.label, group: "action", hint: y.hint, run: y.run })), h = [...l, ...p], f = r.trim().toLowerCase();
6339
+ return f ? h.map((y) => {
6340
+ var w, k;
6341
+ return { it: y, s: Math.max(wn(f, y.label), wn(f, `${y.group} ${((k = (w = e.find((S) => S.title === y.label)) == null ? void 0 : w.keywords) == null ? void 0 : k.join(" ")) ?? ""}`)) };
6342
+ }).filter((y) => y.s > 0).sort((y, w) => w.s - y.s).map((y) => y.it) : h;
6343
+ }, [r, e, t, n]);
6344
+ return X(() => m(0), [r]), /* @__PURE__ */ o("div", { className: "palette-backdrop", onClick: a, children: /* @__PURE__ */ b("div", { className: "palette", role: "dialog", "aria-label": "Command palette", onClick: (l) => l.stopPropagation(), children: [
6345
+ /* @__PURE__ */ o(
6346
+ "input",
6347
+ {
6348
+ ref: d,
6349
+ className: "palette-input",
6350
+ placeholder: "Search calculators and actions…",
6351
+ value: r,
6352
+ onChange: (l) => s(l.target.value),
6353
+ onKeyDown: (l) => {
6354
+ var p;
6355
+ l.key === "ArrowDown" ? (l.preventDefault(), m((h) => Math.min(h + 1, i.length - 1))) : l.key === "ArrowUp" ? (l.preventDefault(), m((h) => Math.max(h - 1, 0))) : l.key === "Enter" ? (l.preventDefault(), (p = i[u]) == null || p.run()) : l.key === "Escape" && (l.preventDefault(), l.stopPropagation(), a());
6356
+ },
6357
+ "aria-label": "Search"
6358
+ }
6359
+ ),
6360
+ /* @__PURE__ */ b("ul", { className: "palette-list", role: "listbox", children: [
6361
+ i.length === 0 && /* @__PURE__ */ o("li", { className: "palette-empty", children: "No matches" }),
6362
+ i.map((l, p) => /* @__PURE__ */ b(
6363
+ "li",
6364
+ {
6365
+ role: "option",
6366
+ "aria-selected": p === u,
6367
+ className: `palette-item ${p === u ? "active" : ""}`,
6368
+ onMouseEnter: () => m(p),
6369
+ onClick: () => l.run(),
6370
+ children: [
6371
+ /* @__PURE__ */ o("span", { className: "palette-label", children: l.label }),
6372
+ /* @__PURE__ */ o("span", { className: "palette-group", children: l.group })
6373
+ ]
6374
+ },
6375
+ l.key
6376
+ ))
6377
+ ] })
6378
+ ] }) });
6379
+ }
6380
+ const ut = (e) => ({
6381
+ width: e,
6382
+ height: e,
6383
+ viewBox: "0 0 24 24",
6384
+ fill: "none",
6385
+ stroke: "currentColor",
6386
+ strokeWidth: 2,
6387
+ strokeLinecap: "round",
6388
+ strokeLinejoin: "round",
6389
+ "aria-hidden": !0
6390
+ });
6391
+ function Xi({ size: e = 17 }) {
6392
+ return /* @__PURE__ */ b("svg", { ...ut(e), children: [
6393
+ /* @__PURE__ */ o("circle", { cx: "12", cy: "12", r: "3" }),
6394
+ /* @__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" })
6395
+ ] });
6396
+ }
6397
+ function Qi({ size: e = 17 }) {
6398
+ return /* @__PURE__ */ b("svg", { ...ut(e), children: [
6399
+ /* @__PURE__ */ o("circle", { cx: "12", cy: "12", r: "4" }),
6400
+ /* @__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" })
6401
+ ] });
6402
+ }
6403
+ function es({ size: e = 17 }) {
6404
+ return /* @__PURE__ */ o("svg", { ...ut(e), children: /* @__PURE__ */ o("path", { d: "M12 3a6 6 0 0 0 9 9 9 9 0 1 1-9-9Z" }) });
6405
+ }
6406
+ function ts({ size: e = 17 }) {
6407
+ return /* @__PURE__ */ b("svg", { ...ut(e), children: [
6408
+ /* @__PURE__ */ o("path", { d: "M3 3v5h5" }),
6409
+ /* @__PURE__ */ o("path", { d: "M3.05 13A9 9 0 1 0 6 5.3L3 8" }),
6410
+ /* @__PURE__ */ o("path", { d: "M12 7v5l4 2" })
6411
+ ] });
6412
+ }
6400
6413
  const ns = { "loan.emi": Wn, scientific: Jn, currency: aa };
6401
6414
  function as({ onClose: e }) {
6402
- const { settings: t, setRegion: n, update: a, resolvedTheme: r } = ue(), s = t.region, u = ne(() => Yr(s), [s]), [m, d] = M("loan.emi"), [i, c] = M("calc"), [l, p] = M(void 0), [h, f] = M(!1), { items: y, clear: w } = Ro();
6415
+ const { settings: t, setRegion: n, update: a, resolvedTheme: r } = ue(), s = t.region, u = ne(() => Kr(s), [s]), [m, d] = M("loan.emi"), [i, c] = M("calc"), [l, p] = M(void 0), [h, f] = M(!1), { items: y, clear: w } = Mo();
6403
6416
  X(() => {
6404
6417
  const x = () => {
6405
6418
  const T = new URLSearchParams(location.hash.replace(/^#/, "") || location.search), $ = T.get("fincalc");
6406
- if ($ && It($)) {
6419
+ if ($ && Rt($)) {
6407
6420
  d($), c("calc");
6408
6421
  const L = T.get("s");
6409
6422
  if (L)
@@ -6419,7 +6432,7 @@ function as({ onClose: e }) {
6419
6432
  (x.metaKey || x.ctrlKey) && x.key.toLowerCase() === "k" && (x.preventDefault(), f(!0));
6420
6433
  }, S = (x) => {
6421
6434
  d(x), c("calc"), p(void 0), f(!1);
6422
- }, F = It(m) ?? u[0], N = [
6435
+ }, F = Rt(m) ?? u[0], N = [
6423
6436
  { id: "settings", label: "Open settings", run: () => {
6424
6437
  c("settings"), f(!1);
6425
6438
  } },
@@ -6451,17 +6464,17 @@ function as({ onClose: e }) {
6451
6464
  /* @__PURE__ */ o("button", { "aria-pressed": s === "IN", onClick: () => n("IN"), children: "🇮🇳" }),
6452
6465
  /* @__PURE__ */ o("button", { "aria-pressed": s === "US", onClick: () => n("US"), children: "🇺🇸" })
6453
6466
  ] }),
6454
- /* @__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(pi, {}) : /* @__PURE__ */ o(hi, {}) }),
6467
+ /* @__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(Qi, {}) : /* @__PURE__ */ o(es, {}) }),
6455
6468
  /* @__PURE__ */ b("button", { className: "icon-btn", "aria-label": "History", onClick: () => c("history"), children: [
6456
- /* @__PURE__ */ o(fi, {}),
6469
+ /* @__PURE__ */ o(ts, {}),
6457
6470
  " History"
6458
6471
  ] }),
6459
- /* @__PURE__ */ o("button", { className: "icon-btn icon-only", "aria-label": "Settings", onClick: () => c("settings"), children: /* @__PURE__ */ o(mi, {}) }),
6472
+ /* @__PURE__ */ o("button", { className: "icon-btn icon-only", "aria-label": "Settings", onClick: () => c("settings"), children: /* @__PURE__ */ o(Xi, {}) }),
6460
6473
  e && /* @__PURE__ */ o("button", { className: "icon-btn icon-only", "aria-label": "Close", onClick: e, children: "✕" })
6461
6474
  ] })
6462
6475
  ] }),
6463
6476
  /* @__PURE__ */ b("div", { className: "fc-body", children: [
6464
- /* @__PURE__ */ o("nav", { className: "fc-rail", "aria-label": "Calculators", children: Kr.map((x) => {
6477
+ /* @__PURE__ */ o("nav", { className: "fc-rail", "aria-label": "Calculators", children: Wr.map((x) => {
6465
6478
  const T = u.filter(($) => $.group === x.id);
6466
6479
  return T.length === 0 ? null : /* @__PURE__ */ b("div", { className: "rail-group", children: [
6467
6480
  /* @__PURE__ */ o("div", { className: "rail-group-label", children: x.label }),
@@ -6477,11 +6490,11 @@ function as({ onClose: e }) {
6477
6490
  ] }, x.id);
6478
6491
  }) }),
6479
6492
  /* @__PURE__ */ o("main", { className: "fc-main", children: /* @__PURE__ */ b("div", { className: "fc-anim-in", children: [
6480
- i === "settings" && /* @__PURE__ */ o(ci, {}),
6481
- i === "history" && /* @__PURE__ */ o(ui, { items: y, onRestore: P, onClear: w }),
6482
- i === "integration" && /* @__PURE__ */ o(Hi, {}),
6493
+ i === "settings" && /* @__PURE__ */ o(zi, {}),
6494
+ i === "history" && /* @__PURE__ */ o(Ji, { items: y, onRestore: P, onClear: w }),
6495
+ i === "integration" && /* @__PURE__ */ o(da, {}),
6483
6496
  i === "calc" && /* @__PURE__ */ o(
6484
- oi,
6497
+ ii,
6485
6498
  {
6486
6499
  def: F,
6487
6500
  seed: l,
@@ -6511,7 +6524,7 @@ function as({ onClose: e }) {
6511
6524
  )
6512
6525
  ] }, i === "calc" ? `calc:${F.id}` : i) })
6513
6526
  ] }),
6514
- h && /* @__PURE__ */ o(di, { calculators: u, actions: N, onPick: S, onClose: () => f(!1) })
6527
+ h && /* @__PURE__ */ o(Zi, { calculators: u, actions: N, onPick: S, onClose: () => f(!1) })
6515
6528
  ] });
6516
6529
  }
6517
6530
  function Nn({ size: e = 22 }) {
@@ -6578,10 +6591,10 @@ function gs({
6578
6591
  /* @__PURE__ */ o("span", { "aria-hidden": !0, style: { marginRight: 6, display: "inline-flex", alignItems: "center" }, children: m ?? /* @__PURE__ */ o(Nn, { size: 16 }) }),
6579
6592
  u
6580
6593
  ] }),
6581
- /* @__PURE__ */ o(Sa, { open: k, onClose: F.close, title: h, size: p, children: /* @__PURE__ */ o(as, { onClose: F.close }) })
6594
+ /* @__PURE__ */ o(Ca, { open: k, onClose: F.close, title: h, size: p, children: /* @__PURE__ */ o(as, { onClose: F.close }) })
6582
6595
  ] });
6583
6596
  }
6584
- const rs = 60 * 60 * 1e3, wt = (e, t) => `${e}|${[...t].sort().join(",")}`;
6597
+ const rs = 60 * 60 * 1e3, Nt = (e, t) => `${e}|${[...t].sort().join(",")}`;
6585
6598
  function vs(e, t = {}) {
6586
6599
  const n = t.ttlMs ?? rs, a = t.now ?? Date.now, r = /* @__PURE__ */ new Map();
6587
6600
  let s = null;
@@ -6595,7 +6608,7 @@ function vs(e, t = {}) {
6595
6608
  return a() - i.lastUpdated < n;
6596
6609
  }
6597
6610
  async function d(i, c) {
6598
- const l = wt(i, c), p = r.get(l);
6611
+ const l = Nt(i, c), p = r.get(l);
6599
6612
  if (p && m(p)) return { ...p, stale: !1 };
6600
6613
  if (e)
6601
6614
  try {
@@ -6618,12 +6631,12 @@ function vs(e, t = {}) {
6618
6631
  return {
6619
6632
  getRates: d,
6620
6633
  /** Non-throwing peek at whatever is cached, if anything. */
6621
- peek: (i, c) => r.get(wt(i, c)),
6634
+ peek: (i, c) => r.get(Nt(i, c)),
6622
6635
  get lastUpdated() {
6623
6636
  return s == null ? null : new Date(s);
6624
6637
  },
6625
6638
  isStale(i, c) {
6626
- const l = r.get(wt(i, c));
6639
+ const l = r.get(Nt(i, c));
6627
6640
  return !l || !m(l);
6628
6641
  },
6629
6642
  clear: () => r.clear()
@@ -6631,53 +6644,53 @@ function vs(e, t = {}) {
6631
6644
  }
6632
6645
  const ks = { solve: Ie, REGIONS: me };
6633
6646
  export {
6634
- oi as CalculatorPanel,
6635
- no as Chart,
6636
- di as CommandPalette,
6647
+ ii as CalculatorPanel,
6648
+ ao as Chart,
6649
+ Zi as CommandPalette,
6637
6650
  aa as CurrencyConverter,
6638
6651
  g as D,
6639
6652
  ys as DEFAULT_ENVELOPE,
6640
6653
  Ze as DEFAULT_SETTINGS,
6641
6654
  H as Decimal,
6642
- Sa as Dialog,
6643
- ao as EXPORT_FORMATS,
6655
+ Ca as Dialog,
6656
+ ro as EXPORT_FORMATS,
6644
6657
  Gn as ExportMenu,
6645
- zr as Field,
6646
- Sa as FinCalcDialog,
6658
+ Jr as Field,
6659
+ Ca as FinCalcDialog,
6647
6660
  se as FinCalcError,
6648
6661
  gs as FinCalcLauncher,
6649
6662
  ms as FinCalcProvider,
6650
6663
  as as FinCalcRoot,
6651
- Kr as GROUPS,
6652
- ui as HistoryPanel,
6653
- Hi as IntegrationPanel,
6664
+ Wr as GROUPS,
6665
+ Ji as HistoryPanel,
6666
+ da as IntegrationPanel,
6654
6667
  gs as Launcher,
6655
6668
  Wn as LoanEmiPanel,
6656
- ya as POLICY_DEFAULT,
6657
- Xr as ResultCard,
6669
+ ba as POLICY_DEFAULT,
6670
+ Qr as ResultCard,
6658
6671
  Kn as SaveButton,
6659
- to as ScheduleTable,
6672
+ no as ScheduleTable,
6660
6673
  Jn as SciCalculator,
6661
- ci as SettingsPanel,
6674
+ zi as SettingsPanel,
6662
6675
  ms as SettingsProvider,
6663
6676
  as as Shell,
6664
6677
  Dn as allCalculators,
6665
6678
  ye as boolval,
6666
6679
  oa as buildFilename,
6667
- Ai as buildPayload,
6680
+ Ti as buildPayload,
6668
6681
  bs as buildSavePayload,
6669
- It as calculatorById,
6670
- Yr as calculatorsForRegion,
6682
+ Rt as calculatorById,
6683
+ Kr as calculatorsForRegion,
6671
6684
  Eo as clearHistory,
6672
- Po as createExporter,
6685
+ To as createExporter,
6673
6686
  vs as createFxCache,
6674
- Ni as createTransport,
6687
+ fi as createTransport,
6675
6688
  fs as currency,
6676
6689
  D as dmoney,
6677
6690
  cs as eq,
6678
6691
  on as evalExpression,
6679
- Jo as evaluateExpression,
6680
- ei as fetchLiveRate,
6692
+ Zo as evaluateExpression,
6693
+ ti as fetchLiveRate,
6681
6694
  ps as finance,
6682
6695
  us as gt,
6683
6696
  ce as isZeroish,
@@ -6686,14 +6699,14 @@ export {
6686
6699
  Sn as makeFormatter,
6687
6700
  v as metric,
6688
6701
  C as numval,
6689
- jo as parseExpression,
6690
- Nt as regionDefaults,
6702
+ Vo as parseExpression,
6703
+ xt as regionDefaults,
6691
6704
  hs as registerCalculator,
6692
- ki as sanitizeFilename,
6705
+ pi as sanitizeFilename,
6693
6706
  Yn as saveHistory,
6694
6707
  Ie as solveLoan,
6695
6708
  _ as strval,
6696
6709
  ue as useFinCalc,
6697
- Ro as useHistory,
6710
+ Mo as useHistory,
6698
6711
  ue as useSettings
6699
6712
  };