calcsuite-react 1.1.2 → 1.1.4

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