calcsuite-react 1.1.2 → 1.1.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/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,7 +3261,7 @@ function Co(e, t = 2) {
3251
3261
  (i, c) => s.toBlob((l) => l ? i(l) : c(new Error("Could not render PNG.")), "image/png")
3252
3262
  );
3253
3263
  }
3254
- async function Po(e) {
3264
+ async function Fo(e) {
3255
3265
  let t;
3256
3266
  try {
3257
3267
  t = await import(
@@ -3277,7 +3287,7 @@ async function Po(e) {
3277
3287
  const s = ve(e, "pdf");
3278
3288
  return a.save(s), { ok: !0, filename: s };
3279
3289
  }
3280
- async function To(e) {
3290
+ async function Io(e) {
3281
3291
  var i, c;
3282
3292
  let t;
3283
3293
  try {
@@ -3300,12 +3310,12 @@ async function To(e) {
3300
3310
  const m = a(u, { type: "array", bookType: "xlsx" }), d = ve(e, "xlsx");
3301
3311
  return Se(d, new Blob([m], { type: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet" })), { ok: !0, filename: d };
3302
3312
  }
3303
- function Gn(e) {
3304
- const t = _n(e.calculatorId, e.values);
3313
+ function jn(e) {
3314
+ const t = Hn(e.calculatorId, e.values);
3305
3315
  return (typeof location < "u" ? location.origin + location.pathname : "") + t;
3306
3316
  }
3307
- async function Fo(e) {
3308
- const t = _n(e.calculatorId, e.values), n = Gn(e);
3317
+ async function Ro(e) {
3318
+ const t = Hn(e.calculatorId, e.values), n = jn(e);
3309
3319
  if (typeof location < "u")
3310
3320
  try {
3311
3321
  location.hash = t;
@@ -3313,31 +3323,31 @@ async function Fo(e) {
3313
3323
  }
3314
3324
  const a = n.length > 2e3 ? `Link is long (${n.length} chars) — some apps may trim it. ` : "";
3315
3325
  try {
3316
- return await qn(n), { ok: !0, data: n, note: `${a}Link copied to clipboard.` };
3326
+ return await Gn(n), { ok: !0, data: n, note: `${a}Link copied to clipboard.` };
3317
3327
  } catch {
3318
3328
  return { ok: !0, data: n, note: `${a}Link is in the address bar — copy it from there.` };
3319
3329
  }
3320
3330
  }
3321
- function Io(e) {
3331
+ function Eo(e) {
3322
3332
  return {
3323
3333
  ok: !0,
3324
- data: Gn(e),
3334
+ data: jn(e),
3325
3335
  note: "A QR image needs an optional QR library — share this link instead."
3326
3336
  };
3327
3337
  }
3328
- function Ro(e = {}) {
3329
- const t = e.schemaVersion ?? On, n = {
3338
+ function Mo(e = {}) {
3339
+ const t = e.schemaVersion ?? Bn, n = {
3330
3340
  csv: (a) => {
3331
3341
  const r = ve(a, "csv");
3332
- return Se(r, mo(a), "text/csv;charset=utf-8"), { ok: !0, filename: r };
3342
+ return Se(r, ho(a), "text/csv;charset=utf-8"), { ok: !0, filename: r };
3333
3343
  },
3334
3344
  tsv: (a) => {
3335
3345
  const r = ve(a, "tsv");
3336
- return Se(r, po(a), "text/tab-separated-values;charset=utf-8"), { ok: !0, filename: r };
3346
+ return Se(r, fo(a), "text/tab-separated-values;charset=utf-8"), { ok: !0, filename: r };
3337
3347
  },
3338
3348
  json: (a) => {
3339
3349
  const r = ve(a, "json");
3340
- return Se(r, ho(a, t), "application/json"), { ok: !0, filename: r };
3350
+ return Se(r, yo(a, t), "application/json"), { ok: !0, filename: r };
3341
3351
  },
3342
3352
  markdown: (a) => {
3343
3353
  const r = ve(a, "md");
@@ -3345,18 +3355,18 @@ function Ro(e = {}) {
3345
3355
  },
3346
3356
  ics: (a) => {
3347
3357
  const r = ve(a, "ics");
3348
- return Se(r, No(a), "text/calendar;charset=utf-8"), { ok: !0, filename: r };
3358
+ return Se(r, So(a), "text/calendar;charset=utf-8"), { ok: !0, filename: r };
3349
3359
  },
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),
3360
+ clipboard: async (a) => (await Co(qn(a), Jt(a)), { ok: !0, note: "Copied table to clipboard." }),
3361
+ print: (a) => (Po(a), { ok: !0 }),
3362
+ url: (a) => Ro(a),
3363
+ qr: (a) => Eo(a),
3354
3364
  png: async (a, r) => {
3355
3365
  const s = ve(a, "png");
3356
- return Se(s, await Co(a, r.scale ?? 2)), { ok: !0, filename: s };
3366
+ return Se(s, await To(a, r.scale ?? 2)), { ok: !0, filename: s };
3357
3367
  },
3358
- pdf: (a) => Po(a),
3359
- xlsx: (a) => To(a)
3368
+ pdf: (a) => Fo(a),
3369
+ xlsx: (a) => Io(a)
3360
3370
  };
3361
3371
  return {
3362
3372
  formats: Object.keys(n),
@@ -3366,8 +3376,8 @@ function Ro(e = {}) {
3366
3376
  }
3367
3377
  };
3368
3378
  }
3369
- function jn({ payload: e }) {
3370
- const t = X(() => Ro(), []), [n, a] = M(!1), [r, s] = M(null), u = de(null), m = de(null), d = de([]);
3379
+ function Vn({ payload: e }) {
3380
+ const t = X(() => Mo(), []), [n, a] = M(!1), [r, s] = M(null), u = de(null), m = de(null), d = de([]);
3371
3381
  Q(() => {
3372
3382
  if (!r) return;
3373
3383
  const p = setTimeout(() => s(null), 4500);
@@ -3435,7 +3445,7 @@ function jn({ payload: e }) {
3435
3445
  }
3436
3446
  )
3437
3447
  ] }),
3438
- n && /* @__PURE__ */ o("div", { ref: m, className: "menu-list", role: "menu", "aria-label": "Export as", children: so.map((p, h) => /* @__PURE__ */ o(
3448
+ n && /* @__PURE__ */ o("div", { ref: m, className: "menu-list", role: "menu", "aria-label": "Export as", children: co.map((p, h) => /* @__PURE__ */ o(
3439
3449
  "button",
3440
3450
  {
3441
3451
  type: "button",
@@ -3452,10 +3462,10 @@ function jn({ payload: e }) {
3452
3462
  r && /* @__PURE__ */ o("div", { className: `export-toast ${r.kind}`, role: "status", "aria-live": "polite", children: r.msg })
3453
3463
  ] });
3454
3464
  }
3455
- const Bt = "calcsuite:history", Eo = 100, Mo = [];
3465
+ const Bt = "calcsuite:history", $o = 100, Ao = [];
3456
3466
  let Ce = null;
3457
- const Je = /* @__PURE__ */ new Set();
3458
- function Vn() {
3467
+ const Ze = /* @__PURE__ */ new Set();
3468
+ function Yn() {
3459
3469
  if (Ce) return Ce;
3460
3470
  try {
3461
3471
  Ce = JSON.parse(localStorage.getItem(Bt) || "[]");
@@ -3464,38 +3474,38 @@ function Vn() {
3464
3474
  }
3465
3475
  return Ce;
3466
3476
  }
3467
- function Yn(e) {
3477
+ function Kn(e) {
3468
3478
  Ce = e;
3469
3479
  try {
3470
3480
  localStorage.setItem(Bt, JSON.stringify(e));
3471
3481
  } catch {
3472
3482
  }
3473
- Je.forEach((t) => t());
3483
+ Ze.forEach((t) => t());
3474
3484
  }
3475
3485
  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);
3486
+ function Do(e) {
3487
+ return Ze.add(e), !Qt && typeof window < "u" && (Qt = !0, window.addEventListener("storage", (t) => {
3488
+ t.key === Bt && (Ce = null, Ze.forEach((n) => n()));
3489
+ })), () => Ze.delete(e);
3480
3490
  }
3481
- function Kn(e) {
3482
- Yn([{ ...e, at: Date.now() }, ...Vn()].slice(0, Eo));
3491
+ function Wn(e) {
3492
+ Kn([{ ...e, at: Date.now() }, ...Yn()].slice(0, $o));
3483
3493
  }
3484
- function Ao() {
3485
- Yn([]);
3494
+ function Lo() {
3495
+ Kn([]);
3486
3496
  }
3487
- function Do() {
3488
- const e = ba($o, Vn, () => Mo), t = ke((a) => Kn(a), []), n = ke(() => Ao(), []);
3497
+ function Uo() {
3498
+ const e = va(Do, Yn, () => Ao), t = ke((a) => Wn(a), []), n = ke(() => Lo(), []);
3489
3499
  return { items: e, save: t, clear: n };
3490
3500
  }
3491
- function Wn({ item: e }) {
3501
+ function zn({ item: e }) {
3492
3502
  const [t, n] = M(!1), a = de();
3493
3503
  return Q(() => () => clearTimeout(a.current), []), /* @__PURE__ */ o("button", { className: `icon-btn ${t ? "saved" : ""}`, onClick: () => {
3494
- Kn(e), n(!0), clearTimeout(a.current), a.current = setTimeout(() => n(!1), 1500);
3504
+ Wn(e), n(!0), clearTimeout(a.current), a.current = setTimeout(() => n(!1), 1500);
3495
3505
  }, "aria-live": "polite", children: t ? "Saved ✓" : "Save" });
3496
3506
  }
3497
- const Lo = { payment: "Payment", principal: "Amount", rate: "Rate", tenure: "Term" };
3498
- function zn() {
3507
+ const Oo = { payment: "Payment", principal: "Amount", rate: "Rate", tenure: "Term" };
3508
+ function Jn() {
3499
3509
  const { settings: e, fmt: t } = ue(), n = e.region, a = me[n], [r, s] = M("payment"), [u, m] = M(a.defaultBasis), [d, i] = M(n === "IN" ? "2500000" : "300000"), [c, l] = M(a.defaultRatePct), [p, h] = M(String(Math.floor(a.defaultTermMonths / 12))), [f, y] = M(String(a.defaultTermMonths % 12)), [w, k] = M(n === "IN" ? "21934" : "1896"), [S, F] = M("schedule"), N = u === "flat" ? ["payment", "principal"] : ["payment", "principal", "rate", "tenure"], P = (parseInt(p || "0", 10) || 0) * 12 + (parseInt(f || "0", 10) || 0), x = (R) => R.replace(/[, ]/g, "").trim(), { result: T, error: $ } = X(() => {
3500
3510
  try {
3501
3511
  return { result: Ie({
@@ -3571,7 +3581,7 @@ function zn() {
3571
3581
  /* @__PURE__ */ b("section", { className: "card", children: [
3572
3582
  /* @__PURE__ */ b("div", { className: "solve-row", children: [
3573
3583
  /* @__PURE__ */ o("span", { className: "lbl", children: "Solve for" }),
3574
- /* @__PURE__ */ o("div", { className: "seg", role: "group", "aria-label": "Solve for", children: N.map((R) => /* @__PURE__ */ o("button", { "aria-pressed": r === R, onClick: () => s(R), children: Lo[R] }, R)) })
3584
+ /* @__PURE__ */ o("div", { className: "seg", role: "group", "aria-label": "Solve for", children: N.map((R) => /* @__PURE__ */ o("button", { "aria-pressed": r === R, onClick: () => s(R), children: Oo[R] }, R)) })
3575
3585
  ] }),
3576
3586
  /* @__PURE__ */ b("div", { className: "field", style: { marginBottom: "calc(var(--fc-space) * 2)" }, children: [
3577
3587
  /* @__PURE__ */ o("span", { className: "lbl", children: "Interest basis" }),
@@ -3625,7 +3635,7 @@ function zn() {
3625
3635
  /* @__PURE__ */ o("span", { className: "per", children: " /month" })
3626
3636
  ] })
3627
3637
  ] }),
3628
- /* @__PURE__ */ o(Uo, { result: T }),
3638
+ /* @__PURE__ */ o(Bo, { result: T }),
3629
3639
  /* @__PURE__ */ b("div", { className: "secondary", children: [
3630
3640
  /* @__PURE__ */ b("div", { className: "kv", children: [
3631
3641
  /* @__PURE__ */ o("div", { className: "k", children: "Principal" }),
@@ -3646,13 +3656,13 @@ function zn() {
3646
3656
  ] }),
3647
3657
  /* @__PURE__ */ b("div", { className: "actions-row", children: [
3648
3658
  /* @__PURE__ */ o(
3649
- Wn,
3659
+ zn,
3650
3660
  {
3651
3661
  item: { id: "loan.emi", title: `Loan — ${t.money(T.payment)}/mo`, primary: t.money(T.payment), values: A }
3652
3662
  }
3653
3663
  ),
3654
3664
  /* @__PURE__ */ o(
3655
- jn,
3665
+ Vn,
3656
3666
  {
3657
3667
  payload: {
3658
3668
  calculatorId: "loan.emi",
@@ -3684,8 +3694,8 @@ function zn() {
3684
3694
  e.ui.showFormulas && /* @__PURE__ */ o("button", { role: "tab", "aria-selected": S === "formula", onClick: () => F("formula"), children: "Formula" })
3685
3695
  ] }),
3686
3696
  /* @__PURE__ */ b("div", { className: "tab-anim", children: [
3687
- S === "schedule" && /* @__PURE__ */ o(Oo, { result: T }),
3688
- S === "chart" && /* @__PURE__ */ o(Bo, { result: T }),
3697
+ S === "schedule" && /* @__PURE__ */ o(_o, { result: T }),
3698
+ S === "chart" && /* @__PURE__ */ o(Ho, { result: T }),
3689
3699
  S === "formula" && e.ui.showFormulas && /* @__PURE__ */ b("div", { className: "formula", children: [
3690
3700
  /* @__PURE__ */ o("code", { children: T.formula }),
3691
3701
  /* @__PURE__ */ b("div", { className: "assumptions", children: [
@@ -3730,7 +3740,7 @@ function bt({
3730
3740
  ] })
3731
3741
  ] });
3732
3742
  }
3733
- function Uo({ result: e }) {
3743
+ function Bo({ result: e }) {
3734
3744
  const { fmt: t } = ue(), n = Number(e.principal.toFixed(2)), a = Number(e.totalInterest.toFixed(2)), r = n + a || 1, s = Math.round(n / r * 100);
3735
3745
  return /* @__PURE__ */ b(re, { children: [
3736
3746
  /* @__PURE__ */ b("div", { className: "splitbar", role: "img", "aria-label": `Principal ${s}%, interest ${100 - s}%`, children: [
@@ -3755,7 +3765,7 @@ function Uo({ result: e }) {
3755
3765
  ] })
3756
3766
  ] });
3757
3767
  }
3758
- function Oo({ result: e }) {
3768
+ function _o({ result: e }) {
3759
3769
  const { fmt: t } = ue(), [n, a] = M("yearly"), [r, s] = M(/* @__PURE__ */ new Set([1])), u = (d) => s((i) => {
3760
3770
  const c = new Set(i);
3761
3771
  return c.has(d) ? c.delete(d) : c.add(d), c;
@@ -3817,7 +3827,7 @@ function Oo({ result: e }) {
3817
3827
  ] }) })
3818
3828
  ] });
3819
3829
  }
3820
- function Bo({ result: e }) {
3830
+ function Ho({ result: e }) {
3821
3831
  const { fmt: t } = ue(), n = e.chart.balance.map((k) => k.toNumber()), a = e.chart.cumulativeInterest.map((k) => k.toNumber()), r = n.length, s = 720, u = 260, m = 8, d = 8, i = 12, c = 22, l = e.principal.toNumber(), p = Math.max(l, a[a.length - 1] ?? 0) || 1, h = (k) => m + k / Math.max(r - 1, 1) * (s - m - d), f = (k) => i + (1 - k / p) * (u - i - c), y = (k) => k.map((S, F) => `${F === 0 ? "M" : "L"}${h(F).toFixed(1)},${f(S).toFixed(1)}`).join(" "), w = `M${h(0)},${f(l)} ${n.map((k, S) => `L${h(S).toFixed(1)},${f(k).toFixed(1)}`).join(" ")} L${h(r - 1)},${f(0)} L${h(0)},${f(0)} Z`;
3822
3832
  return /* @__PURE__ */ b("div", { className: "chart", children: [
3823
3833
  /* @__PURE__ */ b("svg", { viewBox: `0 0 ${s} ${u}`, role: "img", "aria-label": "Balance and cumulative interest over the term", children: [
@@ -3840,7 +3850,7 @@ function Bo({ result: e }) {
3840
3850
  ] })
3841
3851
  ] });
3842
3852
  }
3843
- const _o = /* @__PURE__ */ new Set([
3853
+ const qo = /* @__PURE__ */ new Set([
3844
3854
  "sin",
3845
3855
  "cos",
3846
3856
  "tan",
@@ -3877,7 +3887,7 @@ const _o = /* @__PURE__ */ new Set([
3877
3887
  "sq",
3878
3888
  "cube",
3879
3889
  "recip"
3880
- ]), Ho = {
3890
+ ]), Go = {
3881
3891
  arcsin: "asin",
3882
3892
  arccos: "acos",
3883
3893
  arctan: "atan",
@@ -3885,14 +3895,14 @@ const _o = /* @__PURE__ */ new Set([
3885
3895
  log10: "log",
3886
3896
  ncr: "ncr",
3887
3897
  npr: "npr"
3888
- }, 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 };
3898
+ }, jo = (e) => e === " " || e === " " || e === `
3899
+ ` || e === "\r", fe = (e) => e >= "0" && e <= "9", en = (e) => e >= "a" && e <= "z" || e >= "A" && e <= "Z", Zn = (e) => fe(e) || e >= "a" && e <= "f" || e >= "A" && e <= "F", tn = /* @__PURE__ */ new Set(["num", "const", "var", "func", "lparen", "uop"]), Vo = /* @__PURE__ */ new Set(["num", "const", "var", "rparen", "postfix"]);
3900
+ function Yo(e) {
3901
+ return e === "HEX" ? Zn : e === "OCT" ? (t) => t >= "0" && t <= "7" : e === "BIN" ? (t) => t === "0" || t === "1" : fe;
3902
+ }
3903
+ function Ko(e) {
3904
+ const t = e.toLowerCase(), n = Go[t] ?? t;
3905
+ if (qo.has(n)) return { type: "func", value: n };
3896
3906
  if (t === "mod") return { type: "op", value: "mod" };
3897
3907
  if (t === "and") return { type: "op", value: "and" };
3898
3908
  if (t === "or") return { type: "op", value: "or" };
@@ -3909,12 +3919,12 @@ function Vo(e) {
3909
3919
  }
3910
3920
  throw new Error(`Unknown name: ${e}`);
3911
3921
  }
3912
- function Yo(e, t = {}) {
3922
+ function Wo(e, t = {}) {
3913
3923
  const n = t.base ?? "DEC", a = e, r = [];
3914
3924
  let s = 0;
3915
3925
  for (; s < a.length; ) {
3916
3926
  const d = a[s];
3917
- if (qo(d)) {
3927
+ if (jo(d)) {
3918
3928
  s++;
3919
3929
  continue;
3920
3930
  }
@@ -3922,14 +3932,14 @@ function Yo(e, t = {}) {
3922
3932
  if (d === "0" && (a[s + 1] === "x" || a[s + 1] === "X" || a[s + 1] === "o" || a[s + 1] === "O" || a[s + 1] === "b" || a[s + 1] === "B")) {
3923
3933
  const l = a[s + 1].toLowerCase();
3924
3934
  let p = s + 2;
3925
- const h = l === "x" ? Jn : l === "o" ? (y) => y >= "0" && y <= "7" : (y) => y === "0" || y === "1", f = p;
3935
+ const h = l === "x" ? Zn : l === "o" ? (y) => y >= "0" && y <= "7" : (y) => y === "0" || y === "1", f = p;
3926
3936
  for (; p < a.length && h(a[p]); ) p++;
3927
3937
  if (p === f) throw new Error(`Malformed 0${l} literal`);
3928
3938
  r.push({ type: "num", value: BigInt(`0${l}${a.slice(f, p)}`).toString() }), s = p;
3929
3939
  continue;
3930
3940
  }
3931
3941
  if (n !== "DEC") {
3932
- const l = jo(n);
3942
+ const l = Yo(n);
3933
3943
  let p = s;
3934
3944
  for (; p < a.length && l(a[p]); ) p++;
3935
3945
  const h = a.slice(s, p), f = n === "HEX" ? "0x" : n === "OCT" ? "0o" : "0b";
@@ -3953,7 +3963,7 @@ function Yo(e, t = {}) {
3953
3963
  if (en(d) || d === "_") {
3954
3964
  let c = s;
3955
3965
  for (; c < a.length && (en(a[c]) || fe(a[c]) || a[c] === "_"); ) c++;
3956
- r.push(Vo(a.slice(s, c))), s = c;
3966
+ r.push(Ko(a.slice(s, c))), s = c;
3957
3967
  continue;
3958
3968
  }
3959
3969
  const i = a.slice(s, s + 2);
@@ -4033,11 +4043,11 @@ function Yo(e, t = {}) {
4033
4043
  }), m = [];
4034
4044
  for (let d = 0; d < u.length; d++) {
4035
4045
  const i = u[d], c = m[m.length - 1];
4036
- c && Go.has(c.type) && tn.has(i.type) && m.push({ type: "op", value: "*", implicit: !0 }), m.push(i);
4046
+ c && Vo.has(c.type) && tn.has(i.type) && m.push({ type: "op", value: "*", implicit: !0 }), m.push(i);
4037
4047
  }
4038
4048
  return m;
4039
4049
  }
4040
- const Ko = {
4050
+ const zo = {
4041
4051
  or: { prec: 1 },
4042
4052
  xor: { prec: 2 },
4043
4053
  and: { prec: 3 },
@@ -4051,7 +4061,7 @@ const Ko = {
4051
4061
  "%": { prec: 6 },
4052
4062
  "^": { prec: 8, right: !0 }
4053
4063
  }, nn = { neg: 7, bnot: 7, sqrt: 10, cbrt: 10, qdrt: 10 }, De = Symbol("arg");
4054
- function Wo(e) {
4064
+ function Jo(e) {
4055
4065
  const t = [], n = [];
4056
4066
  let a = !0;
4057
4067
  const r = () => {
@@ -4102,7 +4112,7 @@ function Wo(e) {
4102
4112
  else if (d.value !== "+") throw new Error(`Unexpected operator: ${d.value}`);
4103
4113
  a = !0;
4104
4114
  } else {
4105
- const i = Ko[d.value];
4115
+ const i = zo[d.value];
4106
4116
  if (!i) throw new Error(`Unknown operator: ${d.value}`);
4107
4117
  for (; n.length; ) {
4108
4118
  const c = n[n.length - 1];
@@ -4143,7 +4153,7 @@ function Wo(e) {
4143
4153
  if (m === De) throw new Error("Malformed expression");
4144
4154
  return m;
4145
4155
  }
4146
- const zo = new H("3.141592653589793238462643383279502884197"), Jo = new H("2.718281828459045235360287471352662497757"), Zo = new H("1.618033988749894848204586834365638117720");
4156
+ const Zo = new H("3.141592653589793238462643383279502884197"), Xo = new H("2.718281828459045235360287471352662497757"), Qo = new H("1.618033988749894848204586834365638117720");
4147
4157
  function gt(e, t) {
4148
4158
  return t === "deg" ? e * Math.PI / 180 : t === "grad" ? e * Math.PI / 200 : e;
4149
4159
  }
@@ -4157,13 +4167,13 @@ function an(e) {
4157
4167
  for (let n = 2; n <= e.toNumber(); n++) t = t.times(n);
4158
4168
  return t;
4159
4169
  }
4160
- function Xo(e, t) {
4170
+ function ei(e, t) {
4161
4171
  if (!e.isInteger() || !t.isInteger() || t.isNegative() || t.gt(e)) throw new Error("nPr domain");
4162
4172
  let n = g(1);
4163
4173
  for (let a = 0; a < t.toNumber(); a++) n = n.times(e.minus(a));
4164
4174
  return n;
4165
4175
  }
4166
- function Qo(e, t) {
4176
+ function ti(e, t) {
4167
4177
  if (!e.isInteger() || !t.isInteger() || t.isNegative() || t.gt(e)) throw new Error("nCr domain");
4168
4178
  const n = H.min(t, e.minus(t));
4169
4179
  let a = g(1);
@@ -4186,7 +4196,7 @@ function kt(e, t) {
4186
4196
  return e.pow(g(1).div(t));
4187
4197
  }
4188
4198
  const ie = (e) => BigInt(e.trunc().toFixed(0));
4189
- function ei(e, t = {}) {
4199
+ function ni(e, t = {}) {
4190
4200
  const n = t.angleMode ?? "deg", a = t.percentMode ?? "of", r = (i) => {
4191
4201
  var l;
4192
4202
  if (i === "ans") return g(t.ans ?? 0);
@@ -4268,9 +4278,9 @@ function ei(e, t = {}) {
4268
4278
  case "tenpow":
4269
4279
  return p(1), g(10).pow(l);
4270
4280
  case "ncr":
4271
- return p(2), Qo(l, c[1]);
4281
+ return p(2), ti(l, c[1]);
4272
4282
  case "npr":
4273
- return p(2), Xo(l, c[1]);
4283
+ return p(2), ei(l, c[1]);
4274
4284
  case "gcd":
4275
4285
  return p(2), rn(l, c[1]);
4276
4286
  case "lcm":
@@ -4336,7 +4346,7 @@ function ei(e, t = {}) {
4336
4346
  case "num":
4337
4347
  return g(i.value);
4338
4348
  case "const":
4339
- return i.name === "PI" ? zo : i.name === "E" ? Jo : Zo;
4349
+ return i.name === "PI" ? Zo : i.name === "E" ? Xo : Qo;
4340
4350
  case "var":
4341
4351
  return r(i.name);
4342
4352
  case "percent":
@@ -4363,7 +4373,7 @@ function ei(e, t = {}) {
4363
4373
  function on(e, t = {}) {
4364
4374
  if (e == null || e.trim() === "") return { value: new H(0) };
4365
4375
  try {
4366
- const n = Yo(e, { base: t.base }), a = Wo(n), r = ei(a, t);
4376
+ const n = Wo(e, { base: t.base }), a = Jo(n), r = ni(a, t);
4367
4377
  return r.isNaN() ? { value: r, error: "Not a number" } : { value: r };
4368
4378
  } catch (n) {
4369
4379
  return { value: new H(NaN), error: n instanceof Error ? n.message : String(n) };
@@ -4378,7 +4388,7 @@ function sn(e, t) {
4378
4388
  }
4379
4389
  return e.toSignificantDigits(12).toString();
4380
4390
  }
4381
- function Zn({ def: e }) {
4391
+ function Xn({ def: e }) {
4382
4392
  const { settings: t } = ue(), n = t.percentMode ?? "of", [a, r] = M(""), [s, u] = M("deg"), [m, d] = M("DEC"), [i, c] = M(!1), [l, p] = M(() => new H(0)), [h, f] = M(() => new H(0)), [y, w] = M([]), k = de(null), S = X(
4383
4393
  () => on(a, { angleMode: s, percentMode: n, base: m, ans: h, memory: l }),
4384
4394
  [a, s, n, m, h, l]
@@ -4567,7 +4577,7 @@ function Zn({ def: e }) {
4567
4577
  ] })
4568
4578
  ] });
4569
4579
  }
4570
- const at = [
4580
+ const rt = [
4571
4581
  { code: "USD", name: "US Dollar", symbol: "$" },
4572
4582
  { code: "EUR", name: "Euro", symbol: "€" },
4573
4583
  { code: "GBP", name: "British Pound", symbol: "£" },
@@ -4612,28 +4622,28 @@ const at = [
4612
4622
  { code: "BDT", name: "Bangladeshi Taka", symbol: "৳" },
4613
4623
  { code: "LKR", name: "Sri Lankan Rupee", symbol: "Rs" },
4614
4624
  { code: "NPR", name: "Nepalese Rupee", symbol: "रू" }
4615
- ], 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) => {
4625
+ ], ai = (e) => rt.find((t) => t.code === e), ri = (e) => e === "INR" ? "en-IN" : "en-US", Qn = (e, t) => g(e).times(t), ea = (e) => {
4616
4626
  const t = g(e);
4617
4627
  return t.gt(0) ? g(1).div(t) : g(0);
4618
4628
  };
4619
4629
  function Mt(e, t) {
4620
4630
  const n = g(e);
4621
4631
  try {
4622
- return new Intl.NumberFormat(ni(t), { style: "currency", currency: t }).format(
4632
+ return new Intl.NumberFormat(ri(t), { style: "currency", currency: t }).format(
4623
4633
  Number(n.toFixed(4))
4624
4634
  );
4625
4635
  } catch {
4626
4636
  return `${new Intl.NumberFormat("en-US", { maximumFractionDigits: 4 }).format(Number(n.toFixed(4)))} ${t}`;
4627
4637
  }
4628
4638
  }
4629
- function ea(e) {
4639
+ function ta(e) {
4630
4640
  try {
4631
4641
  return new Intl.NumberFormat("en-US", { style: "currency", currency: e }).resolvedOptions().maximumFractionDigits ?? 2;
4632
4642
  } catch {
4633
4643
  return 2;
4634
4644
  }
4635
4645
  }
4636
- function Ze(e, t) {
4646
+ function Xe(e, t) {
4637
4647
  const n = Math.max(0, Math.floor((t - e) / 1e3));
4638
4648
  if (n < 60) return "just now";
4639
4649
  const a = Math.floor(n / 60);
@@ -4645,23 +4655,23 @@ function Ze(e, t) {
4645
4655
  const u = Math.floor(s / 30);
4646
4656
  return `${u} month${u === 1 ? "" : "s"} ago`;
4647
4657
  }
4648
- const ta = (e, t) => t - e > 864e5, ys = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
4658
+ const na = (e, t) => t - e > 864e5, gs = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
4649
4659
  __proto__: null,
4650
- CURRENCIES: at,
4651
- convert: Xn,
4652
- currencyByCode: ti,
4653
- currencyDecimals: ea,
4660
+ CURRENCIES: rt,
4661
+ convert: Qn,
4662
+ currencyByCode: ai,
4663
+ currencyDecimals: ta,
4654
4664
  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 = {}) {
4665
+ inverseRate: ea,
4666
+ isStale: na,
4667
+ stalenessLabel: Xe
4668
+ }, Symbol.toStringTag, { value: "Module" })), oi = (e) => `https://open.er-api.com/v6/latest/${encodeURIComponent(e)}`;
4669
+ async function ii(e, t, n = {}) {
4660
4670
  var m;
4661
4671
  if (e === t) return { rate: "1", asOf: "", provider: "identity" };
4662
4672
  const a = n.fetchImpl ?? (typeof fetch < "u" ? fetch : void 0);
4663
4673
  if (!a) throw new Error("No fetch available in this environment");
4664
- const r = await a(ai(e), { signal: n.signal });
4674
+ const r = await a(oi(e), { signal: n.signal });
4665
4675
  if (!r.ok) throw new Error(`Rate service returned HTTP ${r.status}`);
4666
4676
  const s = await r.json();
4667
4677
  if (s != null && s.result && s.result !== "success") throw new Error(s["error-type"] || "Rate service error");
@@ -4673,35 +4683,35 @@ function ln(e, t) {
4673
4683
  const n = Date.parse(e);
4674
4684
  return Number.isFinite(n) ? n : t;
4675
4685
  }
4676
- const na = "calcsuite:fxrates", aa = "calcsuite:fxmode", wt = () => {
4686
+ const aa = "calcsuite:fxrates", ra = "calcsuite:fxmode", wt = () => {
4677
4687
  try {
4678
- return JSON.parse(localStorage.getItem(na) || "{}");
4688
+ return JSON.parse(localStorage.getItem(aa) || "{}");
4679
4689
  } catch {
4680
4690
  return {};
4681
4691
  }
4682
- }, oi = (e) => {
4692
+ }, si = (e) => {
4683
4693
  try {
4684
- localStorage.setItem(na, JSON.stringify(e));
4694
+ localStorage.setItem(aa, JSON.stringify(e));
4685
4695
  } catch {
4686
4696
  }
4687
- }, ii = () => {
4697
+ }, li = () => {
4688
4698
  try {
4689
- return localStorage.getItem(aa) === "offline" ? "offline" : "online";
4699
+ return localStorage.getItem(ra) === "offline" ? "offline" : "online";
4690
4700
  } catch {
4691
4701
  return "online";
4692
4702
  }
4693
- }, Ke = (e, t) => `${e}_${t}`;
4694
- function ra() {
4703
+ }, We = (e, t) => `${e}_${t}`;
4704
+ function oa() {
4695
4705
  var _t;
4696
- const [e, t] = M("USD"), [n, a] = M("INR"), [r, s] = M(""), [u, m] = M(""), [d, i] = M("none"), [c, l] = M(""), [p, h] = M("idle"), [f, y] = M(""), [w, k] = M(() => ii()), [S, F] = M(() => wt()), [N, P] = M(() => Date.now()), x = de(null);
4706
+ const [e, t] = M("USD"), [n, a] = M("INR"), [r, s] = M(""), [u, m] = M(""), [d, i] = M("none"), [c, l] = M(""), [p, h] = M("idle"), [f, y] = M(""), [w, k] = M(() => li()), [S, F] = M(() => wt()), [N, P] = M(() => Date.now()), x = de(null);
4697
4707
  Q(() => {
4698
4708
  const O = setInterval(() => P(Date.now()), 3e4);
4699
4709
  return () => clearInterval(O);
4700
4710
  }, []);
4701
4711
  const T = (O, Z) => {
4702
4712
  F((ae) => {
4703
- const oe = { ...ae, [Ke(e, n)]: { rate: O, at: Z } };
4704
- return oi(oe), oe;
4713
+ const oe = { ...ae, [We(e, n)]: { rate: O, at: Z } };
4714
+ return si(oe), oe;
4705
4715
  });
4706
4716
  }, $ = (O, Z) => {
4707
4717
  var oe;
@@ -4711,11 +4721,11 @@ function ra() {
4711
4721
  m("1"), i("live"), l(""), h("idle");
4712
4722
  return;
4713
4723
  }
4714
- h("loading"), y(""), ri(O, Z, { signal: ae.signal }).then((xe) => {
4724
+ h("loading"), y(""), ii(O, Z, { signal: ae.signal }).then((xe) => {
4715
4725
  ae.signal.aborted || (m(xe.rate), i("live"), l(xe.asOf), h("idle"), T(xe.rate, ln(xe.asOf, Date.now())));
4716
4726
  }).catch((xe) => {
4717
4727
  if (ae.signal.aborted) return;
4718
- const Ht = wt()[Ke(O, Z)];
4728
+ const Ht = wt()[We(O, Z)];
4719
4729
  Ht ? (m(Ht.rate), i("saved"), h("error"), y("Offline — showing your last saved rate. Refresh when back online.")) : (i("none"), h("error"), y(`Couldn’t fetch a live rate (${xe instanceof Error ? xe.message : "offline"}). Enter one manually.`));
4720
4730
  });
4721
4731
  }, L = (O, Z) => {
@@ -4724,7 +4734,7 @@ function ra() {
4724
4734
  m("1"), i("saved");
4725
4735
  return;
4726
4736
  }
4727
- const ae = wt()[Ke(O, Z)];
4737
+ const ae = wt()[We(O, Z)];
4728
4738
  ae ? (m(ae.rate), i("saved")) : (m(""), i("none"));
4729
4739
  };
4730
4740
  Q(() => (w === "online" ? $(e, n) : L(e, n), () => {
@@ -4734,21 +4744,21 @@ function ra() {
4734
4744
  const B = (O) => {
4735
4745
  k(O);
4736
4746
  try {
4737
- localStorage.setItem(aa, O);
4747
+ localStorage.setItem(ra, O);
4738
4748
  } catch {
4739
4749
  }
4740
4750
  }, G = (O) => O.replace(/[, ]/g, "").trim(), q = G(r), A = G(u), I = q !== "" && Number(q) >= 0 && Number.isFinite(Number(q)), R = A !== "" && Number(A) > 0 && Number.isFinite(Number(A)), j = X(
4741
- () => I && R ? Xn(q, A) : null,
4751
+ () => I && R ? Qn(q, A) : null,
4742
4752
  [I, R, q, A]
4743
- ), Y = R ? Qn(A) : null, V = (O) => {
4753
+ ), Y = R ? ea(A) : null, V = (O) => {
4744
4754
  m(O), i("manual"), h("idle"), y(""), (R || O.trim() !== "") && T(G(O), Date.now());
4745
4755
  }, ee = () => {
4746
4756
  t(n), a(e);
4747
- }, Ee = c ? 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: [
4757
+ }, Ee = c ? Xe(ln(c, N), N) : "just now", K = (_t = S[We(e, n)]) == null ? void 0 : _t.at, pe = (O) => /* @__PURE__ */ b("option", { value: O.code, children: [
4748
4758
  O.code,
4749
4759
  " — ",
4750
4760
  O.name
4751
- ] }, O.code), Me = Object.entries(S).sort((O, Z) => Z[1].at - O[1].at), Ge = () => p === "error" ? /* @__PURE__ */ b("span", { children: [
4761
+ ] }, O.code), Me = Object.entries(S).sort((O, Z) => Z[1].at - O[1].at), je = () => p === "error" ? /* @__PURE__ */ b("span", { children: [
4752
4762
  "⚠ ",
4753
4763
  f
4754
4764
  ] }) : d === "manual" ? /* @__PURE__ */ o("span", { children: "Manual rate (you entered this)" }) : w === "online" ? p === "loading" ? /* @__PURE__ */ o("span", { children: "Fetching live rate…" }) : d === "live" ? /* @__PURE__ */ b("span", { children: [
@@ -4758,7 +4768,7 @@ function ra() {
4758
4768
  " · open.er-api.com"
4759
4769
  ] }) : null : d === "saved" && K ? /* @__PURE__ */ b("span", { children: [
4760
4770
  "✈ Offline · saved rate ",
4761
- Ze(K, N)
4771
+ Xe(K, N)
4762
4772
  ] }) : /* @__PURE__ */ o("span", { children: "✈ Offline · enter a rate manually" });
4763
4773
  return /* @__PURE__ */ b("div", { "data-part": "calculator", "data-calculator": "tools.currency", children: [
4764
4774
  /* @__PURE__ */ b("section", { className: "card", children: [
@@ -4783,12 +4793,12 @@ function ra() {
4783
4793
  ] }),
4784
4794
  /* @__PURE__ */ b("label", { className: "field cc-cur", children: [
4785
4795
  /* @__PURE__ */ o("span", { className: "lbl", children: "From" }),
4786
- /* @__PURE__ */ o("div", { className: "input-wrap", children: /* @__PURE__ */ o("select", { value: e, onChange: (O) => t(O.target.value), "aria-label": "From currency", children: at.map(pe) }) })
4796
+ /* @__PURE__ */ o("div", { className: "input-wrap", children: /* @__PURE__ */ o("select", { value: e, onChange: (O) => t(O.target.value), "aria-label": "From currency", children: rt.map(pe) }) })
4787
4797
  ] }),
4788
4798
  /* @__PURE__ */ o("button", { type: "button", className: "cc-swap", onClick: ee, "aria-label": "Swap currencies", title: "Swap", children: "⇄" }),
4789
4799
  /* @__PURE__ */ b("label", { className: "field cc-cur", children: [
4790
4800
  /* @__PURE__ */ o("span", { className: "lbl", children: "To" }),
4791
- /* @__PURE__ */ o("div", { className: "input-wrap", children: /* @__PURE__ */ o("select", { value: n, onChange: (O) => a(O.target.value), "aria-label": "To currency", children: at.map(pe) }) })
4801
+ /* @__PURE__ */ o("div", { className: "input-wrap", children: /* @__PURE__ */ o("select", { value: n, onChange: (O) => a(O.target.value), "aria-label": "To currency", children: rt.map(pe) }) })
4792
4802
  ] })
4793
4803
  ] }),
4794
4804
  /* @__PURE__ */ b("label", { className: "field", style: { marginTop: 16 }, children: [
@@ -4822,7 +4832,7 @@ function ra() {
4822
4832
  }
4823
4833
  )
4824
4834
  ] }),
4825
- /* @__PURE__ */ o("div", { className: `cc-status ${p === "error" ? "cc-stale" : ""}`, "aria-live": "polite", children: Ge() }),
4835
+ /* @__PURE__ */ o("div", { className: `cc-status ${p === "error" ? "cc-stale" : ""}`, "aria-live": "polite", children: je() }),
4826
4836
  e === n && /* @__PURE__ */ o("div", { className: "notice", children: "“From” and “To” are the same currency — the rate is 1." })
4827
4837
  ] })
4828
4838
  ] }),
@@ -4859,7 +4869,7 @@ function ra() {
4859
4869
  /* @__PURE__ */ b("div", { className: "kv", children: [
4860
4870
  /* @__PURE__ */ o("div", { className: "k", children: "Precision" }),
4861
4871
  /* @__PURE__ */ b("div", { className: "v num", children: [
4862
- ea(n),
4872
+ ta(n),
4863
4873
  " dp · ",
4864
4874
  n
4865
4875
  ] })
@@ -4892,7 +4902,7 @@ function ra() {
4892
4902
  oe
4893
4903
  ] }),
4894
4904
  /* @__PURE__ */ o("span", { className: "num", children: Z.rate }),
4895
- /* @__PURE__ */ o("span", { className: `cc-book-when ${ta(Z.at, N) ? "cc-stale" : ""}`, children: Ze(Z.at, N) })
4905
+ /* @__PURE__ */ o("span", { className: `cc-book-when ${na(Z.at, N) ? "cc-stale" : ""}`, children: Xe(Z.at, N) })
4896
4906
  ]
4897
4907
  }
4898
4908
  ) }, O);
@@ -4900,23 +4910,23 @@ function ra() {
4900
4910
  ] })
4901
4911
  ] });
4902
4912
  }
4903
- const si = {
4913
+ const ci = {
4904
4914
  id: "",
4905
4915
  group: "tools",
4906
4916
  title: "",
4907
4917
  inputs: [],
4908
4918
  compute: () => ({ primary: { label: "", value: "" } })
4909
- }, li = {
4910
- "loan.emi": zn,
4911
- scientific: Zn,
4912
- currency: ra
4919
+ }, ui = {
4920
+ "loan.emi": Jn,
4921
+ scientific: Xn,
4922
+ currency: oa
4913
4923
  };
4914
4924
  function cn(e, t) {
4915
4925
  const n = {};
4916
4926
  for (const a of e.inputs) a.default !== void 0 && (n[a.key] = a.default);
4917
4927
  return t ? { ...n, ...t } : n;
4918
4928
  }
4919
- function ci({
4929
+ function di({
4920
4930
  def: e,
4921
4931
  id: t,
4922
4932
  seed: n,
@@ -4925,7 +4935,7 @@ function ci({
4925
4935
  actions: s
4926
4936
  }) {
4927
4937
  var L, B, G, q;
4928
- const u = e ?? (t ? Rt(t) : void 0), m = u ?? si, d = { ...li, ...a }, { settings: i, fmt: c } = ue(), [l, p] = M(() => cn(m, n)), [h, f] = M("schedule"), [y, w] = M(!1);
4938
+ const u = e ?? (t ? Rt(t) : void 0), m = u ?? ci, d = { ...ui, ...a }, { settings: i, fmt: c } = ue(), [l, p] = M(() => cn(m, n)), [h, f] = M("schedule"), [y, w] = M(!1);
4929
4939
  Q(() => p(cn(m, n)), [m.id, n]);
4930
4940
  const k = i.region, S = (A, I) => p((R) => ({ ...R, [A]: I })), F = m.inputs.filter((A) => A.showIf ? A.showIf(l, k) : !0), N = F.filter((A) => !A.advanced), P = F.filter((A) => A.advanced), { result: x, error: T } = X(() => {
4931
4941
  const A = { settings: i, region: k, fmt: c, D: g };
@@ -4963,7 +4973,7 @@ function ci({
4963
4973
  T && /* @__PURE__ */ o("div", { className: "error", role: "alert", style: { marginTop: 16 }, children: T })
4964
4974
  ] }),
4965
4975
  x && !T && /* @__PURE__ */ b("section", { className: "card", children: [
4966
- /* @__PURE__ */ o(no, { view: x }),
4976
+ /* @__PURE__ */ o(ro, { view: x }),
4967
4977
  (B = x.warnings) == null ? void 0 : B.map((A, I) => /* @__PURE__ */ o("div", { className: "notice", children: A }, I)),
4968
4978
  s && /* @__PURE__ */ o("div", { className: "actions-row", children: s(x, l) }),
4969
4979
  $ && /* @__PURE__ */ b(re, { children: [
@@ -4974,8 +4984,8 @@ function ci({
4974
4984
  (((G = x.notes) == null ? void 0 : G.length) ?? 0) > 0 && i.ui.showAssumptions && /* @__PURE__ */ o("button", { role: "tab", "aria-selected": h === "assumptions", onClick: () => f("assumptions"), children: "Assumptions" })
4975
4985
  ] }),
4976
4986
  /* @__PURE__ */ b("div", { className: "tab-anim", children: [
4977
- h === "schedule" && x.schedule && /* @__PURE__ */ o(oo, { schedule: x.schedule }),
4978
- h === "chart" && x.chart && /* @__PURE__ */ o(io, { chart: x.chart }),
4987
+ h === "schedule" && x.schedule && /* @__PURE__ */ o(so, { schedule: x.schedule }),
4988
+ h === "chart" && x.chart && /* @__PURE__ */ o(lo, { chart: x.chart }),
4979
4989
  h === "formula" && x.formula && i.ui.showFormulas && /* @__PURE__ */ b("div", { className: "formula", children: [
4980
4990
  /* @__PURE__ */ o("code", { children: x.formula }),
4981
4991
  x.formulaSubstituted && /* @__PURE__ */ o("code", { style: { marginTop: 8 }, children: x.formulaSubstituted })
@@ -4998,7 +5008,7 @@ function un({ def: e, region: t }) {
4998
5008
  }
4999
5009
  function dn({ f: e, values: t, set: n }) {
5000
5010
  const a = e.kind === "cashflows" || e.kind === "segmented" ? "span2" : "";
5001
- return /* @__PURE__ */ o("div", { className: a, children: /* @__PURE__ */ o(Qr, { f: e, value: t[e.key], onChange: (r) => n(e.key, r), values: t }) });
5011
+ return /* @__PURE__ */ o("div", { className: a, children: /* @__PURE__ */ o(to, { f: e, value: t[e.key], onChange: (r) => n(e.key, r), values: t }) });
5002
5012
  }
5003
5013
  class z extends Error {
5004
5014
  constructor(n, a = { code: "transport_error" }) {
@@ -5010,17 +5020,17 @@ class z extends Error {
5010
5020
  this.name = "TransportError", this.code = a.code, this.status = a.status ?? 0, this.request = a.request;
5011
5021
  }
5012
5022
  }
5013
- const ui = ["authorization", "cookie", "x-api-key", "x-auth-token", "api-key"], di = {
5023
+ const mi = ["authorization", "cookie", "x-api-key", "x-auth-token", "api-key"], pi = {
5014
5024
  attempts: 3,
5015
5025
  backoff: "exponential",
5016
5026
  baseDelayMs: 300,
5017
5027
  retryOn: [408, 429, 500, 502, 503, 504],
5018
5028
  respectRetryAfter: !0
5019
- }, mi = {
5029
+ }, hi = {
5020
5030
  enabled: !0,
5021
5031
  headerName: "Idempotency-Key",
5022
5032
  keyFrom: "inputsHash"
5023
- }, pi = {
5033
+ }, fi = {
5024
5034
  enabled: !0,
5025
5035
  storage: "memory",
5026
5036
  maxItems: 200,
@@ -5032,7 +5042,7 @@ const ui = ["authorization", "cookie", "x-api-key", "x-auth-token", "api-key"],
5032
5042
  return !1;
5033
5043
  }
5034
5044
  };
5035
- function oa() {
5045
+ function ia() {
5036
5046
  const e = globalThis.crypto;
5037
5047
  return e != null && e.randomUUID ? e.randomUUID() : "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, (t) => {
5038
5048
  const n = Math.random() * 16 | 0;
@@ -5040,21 +5050,21 @@ function oa() {
5040
5050
  });
5041
5051
  }
5042
5052
  const pn = (e) => new Promise((t) => setTimeout(t, Math.max(0, e)));
5043
- function hi(e) {
5053
+ function yi(e) {
5044
5054
  let t = String(e).replace(/[\\/]+/g, "-").replace(/[\x00-\x1f\x7f]+/g, "").replace(/[<>:"|?*]+/g, "").replace(/^\.+/, "");
5045
5055
  return t = t.trim(), t || "file";
5046
5056
  }
5047
- function ia(e, t) {
5057
+ function sa(e, t) {
5048
5058
  var m;
5049
5059
  const n = /* @__PURE__ */ new Date(), a = (d) => String(d).padStart(2, "0"), r = (((m = t.filename) == null ? void 0 : m.split(".").pop()) || t.kind || "bin").toLowerCase(), s = (t.inputsHash || "").replace(/^sha256:/, "").slice(0, 8) || "00000000", u = e.replace(/\{calculator\}/g, t.calculator || "calc").replace(/\{yyyy\}/g, String(n.getFullYear())).replace(/\{MM\}/g, a(n.getMonth() + 1)).replace(/\{dd\}/g, a(n.getDate())).replace(/\{hash8\}/g, s).replace(/\{ext\}/g, r).replace(/\{kind\}/g, t.kind || "file");
5050
- return hi(u);
5060
+ return yi(u);
5051
5061
  }
5052
5062
  function $t(e, t = []) {
5053
- const n = /* @__PURE__ */ new Set([...ui, ...t.map((r) => r.toLowerCase())]), a = {};
5063
+ const n = /* @__PURE__ */ new Set([...mi, ...t.map((r) => r.toLowerCase())]), a = {};
5054
5064
  for (const [r, s] of Object.entries(e)) a[r] = n.has(r.toLowerCase()) ? "***" : s;
5055
5065
  return a;
5056
5066
  }
5057
- class fi {
5067
+ class bi {
5058
5068
  constructor(t, n) {
5059
5069
  ge(this, "items", []);
5060
5070
  ge(this, "key");
@@ -5082,7 +5092,7 @@ class fi {
5082
5092
  return this.items.length;
5083
5093
  }
5084
5094
  enqueue(t) {
5085
- const n = { ...t, id: oa(), createdAt: (/* @__PURE__ */ new Date()).toISOString(), retryCount: 0 };
5095
+ const n = { ...t, id: ia(), createdAt: (/* @__PURE__ */ new Date()).toISOString(), retryCount: 0 };
5086
5096
  for (this.items.push(n); this.items.length > this.cfg.maxItems; ) this.items.shift();
5087
5097
  return this.save(), n;
5088
5098
  }
@@ -5104,12 +5114,12 @@ class fi {
5104
5114
  }
5105
5115
  }
5106
5116
  const hn = /* @__PURE__ */ new Set(["POST", "PUT", "PATCH", "DELETE"]);
5107
- function 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");
5117
+ function gi(e) {
5118
+ const t = e.fetch ?? globalThis.fetch, n = { ...pi, ...e.retry }, a = { ...hi, ...e.idempotency }, r = { ...fi, ...e.offlineQueue }, s = e.timeoutMs ?? 15e3, u = e.credentials ?? "same-origin", m = new bi(r, "calcsuite");
5109
5119
  function d(N, P) {
5110
5120
  const x = e.endpoints[N];
5111
5121
  if (!x) throw new z(`Endpoint "${N}" is not configured`, { code: "no_endpoint" });
5112
- let T = /^https?:\/\//i.test(x) ? x : bi(e.baseUrl, x);
5122
+ let T = /^https?:\/\//i.test(x) ? x : vi(e.baseUrl, x);
5113
5123
  return P != null && (T = T.replace(/:id\b/, encodeURIComponent(P))), T;
5114
5124
  }
5115
5125
  function i() {
@@ -5124,10 +5134,10 @@ function yi(e) {
5124
5134
  if (!a.enabled || x) return x;
5125
5135
  if (hn.has(fn(N))) {
5126
5136
  if (a.keyFrom === "inputsHash") {
5127
- const T = vi(P);
5137
+ const T = wi(P);
5128
5138
  if (T) return T;
5129
5139
  }
5130
- return oa();
5140
+ return ia();
5131
5141
  }
5132
5142
  }
5133
5143
  async function p(N, P, x) {
@@ -5154,7 +5164,7 @@ function yi(e) {
5154
5164
  }
5155
5165
  async function f(N, P = {}) {
5156
5166
  var B, G, q, A;
5157
- const x = fn(N), T = gi(d(N, P.pathParam), P.query), $ = l(N, P.body, P.idempotencyKey);
5167
+ const x = fn(N), T = ki(d(N, P.pathParam), P.query), $ = l(N, P.body, P.idempotencyKey);
5158
5168
  let L;
5159
5169
  for (let I = 1; I <= Math.max(1, n.attempts); I++) {
5160
5170
  const R = await c(), j = {
@@ -5184,7 +5194,7 @@ function yi(e) {
5184
5194
  await pn(h(I, K));
5185
5195
  continue;
5186
5196
  }
5187
- const pe = await sa(K), Me = {
5197
+ const pe = await la(K), Me = {
5188
5198
  ...ee,
5189
5199
  status: K.status,
5190
5200
  ok: K.ok,
@@ -5192,12 +5202,12 @@ function yi(e) {
5192
5202
  data: pe
5193
5203
  };
5194
5204
  if ((G = e.onResponse) == null || G.call(e, Me), !K.ok) {
5195
- const Ge = new z(`Request failed with ${K.status}`, {
5205
+ const je = new z(`Request failed with ${K.status}`, {
5196
5206
  code: "http_error",
5197
5207
  status: K.status,
5198
5208
  request: ee
5199
5209
  });
5200
- throw (q = e.onError) == null || q.call(e, Ge, ee), Ge;
5210
+ throw (q = e.onError) == null || q.call(e, je, ee), je;
5201
5211
  }
5202
5212
  return e.transformResponse ? e.transformResponse(pe, ee) : pe;
5203
5213
  } catch (K) {
@@ -5223,8 +5233,8 @@ function yi(e) {
5223
5233
  }
5224
5234
  async function y(N, P, x = {}) {
5225
5235
  const T = e.upload;
5226
- 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) };
5236
+ xi(N, P, T.accept, T.maxBytes);
5237
+ const $ = P.filename ?? sa(T.filenameTemplate, P), L = { ...P, filename: $, bytes: N.size, contentType: P.contentType ?? ca(N) };
5228
5238
  if (T.beforeUpload && !await T.beforeUpload(N, L))
5229
5239
  throw new z("Upload cancelled by host", { code: "upload_cancelled" });
5230
5240
  return T.strategy === "presigned" ? F(N, L, x) : T.strategy === "base64Json" ? S(N, L, x) : k(N, L, x);
@@ -5255,10 +5265,10 @@ function yi(e) {
5255
5265
  { method: "POST", credentials: u, headers: B, body: $ },
5256
5266
  x.signal
5257
5267
  );
5258
- return ki(G);
5268
+ return Ni(G);
5259
5269
  }
5260
5270
  async function S(N, P, x) {
5261
- const T = await Ni(N);
5271
+ const T = await Si(N);
5262
5272
  return f("upload", {
5263
5273
  ...x,
5264
5274
  body: {
@@ -5345,23 +5355,23 @@ function fn(e) {
5345
5355
  function yn() {
5346
5356
  return typeof performance < "u" && performance.now ? performance.now() : Date.now();
5347
5357
  }
5348
- function bi(e, t) {
5358
+ function vi(e, t) {
5349
5359
  return e ? `${e.replace(/\/+$/, "")}/${t.replace(/^\/+/, "")}` : t;
5350
5360
  }
5351
- function gi(e, t) {
5361
+ function ki(e, t) {
5352
5362
  if (!t) return e;
5353
5363
  const n = [];
5354
5364
  for (const [a, r] of Object.entries(t))
5355
5365
  r == null || r === "" || n.push(`${encodeURIComponent(a)}=${encodeURIComponent(String(r))}`);
5356
5366
  return n.length ? e + (e.includes("?") ? "&" : "?") + n.join("&") : e;
5357
5367
  }
5358
- function vi(e) {
5368
+ function wi(e) {
5359
5369
  var a;
5360
5370
  if (!e || typeof e != "object") return;
5361
5371
  const t = e, n = ((a = t == null ? void 0 : t.meta) == null ? void 0 : a.inputsHash) ?? (t == null ? void 0 : t.inputsHash);
5362
5372
  return typeof n == "string" && n ? n : void 0;
5363
5373
  }
5364
- async function sa(e) {
5374
+ async function la(e) {
5365
5375
  const t = e.headers.get("content-type") || "";
5366
5376
  try {
5367
5377
  return t.includes("application/json") ? await e.json() : await e.text() || null;
@@ -5369,21 +5379,21 @@ async function sa(e) {
5369
5379
  return null;
5370
5380
  }
5371
5381
  }
5372
- async function ki(e) {
5382
+ async function Ni(e) {
5373
5383
  if (!e.ok) throw new z(`Upload failed (${e.status})`, { code: "upload_failed", status: e.status });
5374
- return sa(e);
5384
+ return la(e);
5375
5385
  }
5376
- function la(e) {
5386
+ function ca(e) {
5377
5387
  return e.type || "application/octet-stream";
5378
5388
  }
5379
- function wi(e, t, n, a) {
5389
+ function xi(e, t, n, a) {
5380
5390
  if (e.size > a)
5381
5391
  throw new z(`File exceeds ${a} bytes`, { code: "too_large" });
5382
- const r = t.contentType ?? la(e);
5392
+ const r = t.contentType ?? ca(e);
5383
5393
  if (n.length && r && !n.includes(r))
5384
5394
  throw new z(`Content type ${r} not accepted`, { code: "bad_type" });
5385
5395
  }
5386
- async function Ni(e) {
5396
+ async function Si(e) {
5387
5397
  const t = await e.arrayBuffer(), n = new Uint8Array(t);
5388
5398
  if (typeof btoa == "function") {
5389
5399
  let r = "";
@@ -5394,7 +5404,7 @@ async function Ni(e) {
5394
5404
  if (a) return a.from(n).toString("base64");
5395
5405
  throw new z("No base64 encoder available", { code: "no_base64" });
5396
5406
  }
5397
- function We(e, t) {
5407
+ function ze(e, t) {
5398
5408
  if (!t) return e;
5399
5409
  let n = e;
5400
5410
  for (const a of t.split(".")) {
@@ -5412,15 +5422,15 @@ function bn(e, t, n) {
5412
5422
  }
5413
5423
  r[a[a.length - 1]] = n;
5414
5424
  }
5415
- function xi(e, t) {
5425
+ function Ci(e, t) {
5416
5426
  if (t === "asIs") return e;
5417
5427
  const n = e.replace(/([a-z0-9])([A-Z])/g, "$1 $2").replace(/[_\-\s]+/g, " ").trim().split(" ").filter(Boolean);
5418
5428
  return n.length === 0 ? e : t === "snake" ? n.map((a) => a.toLowerCase()).join("_") : t === "kebab" ? n.map((a) => a.toLowerCase()).join("-") : n.map((a, r) => r === 0 ? a.toLowerCase() : a[0].toUpperCase() + a.slice(1).toLowerCase()).join("");
5419
5429
  }
5420
5430
  function gn(e, t) {
5421
- return e.split(".").map((n) => xi(n, t)).join(".");
5431
+ return e.split(".").map((n) => Ci(n, t)).join(".");
5422
5432
  }
5423
- function Si(e, t) {
5433
+ function Pi(e, t) {
5424
5434
  switch (t) {
5425
5435
  case "toFixed2":
5426
5436
  return Number(e).toFixed(2);
@@ -5437,11 +5447,11 @@ function Si(e, t) {
5437
5447
  return e;
5438
5448
  }
5439
5449
  }
5440
- function Ci(e, t) {
5450
+ function Ti(e, t) {
5441
5451
  const n = e instanceof Date ? e : new Date(e);
5442
5452
  return Number.isNaN(n.getTime()) ? String(e) : n.toISOString();
5443
5453
  }
5444
- function Pi(e, t, n) {
5454
+ function Fi(e, t, n) {
5445
5455
  switch (t) {
5446
5456
  case "number": {
5447
5457
  if (n.numberEncoding === "number") {
@@ -5453,7 +5463,7 @@ function Pi(e, t, n) {
5453
5463
  case "boolean":
5454
5464
  return typeof e == "string" ? e.toLowerCase() === "true" : !!e;
5455
5465
  case "date":
5456
- return Ci(e, n.dateFormat);
5466
+ return Ti(e, n.dateFormat);
5457
5467
  case "json":
5458
5468
  return e;
5459
5469
  case "string":
@@ -5461,30 +5471,30 @@ function Pi(e, t, n) {
5461
5471
  return String(e);
5462
5472
  }
5463
5473
  }
5464
- function rt(e, t) {
5474
+ function ot(e, t) {
5465
5475
  if (t === "number") return e;
5466
5476
  if (typeof e == "number") return String(e);
5467
- if (Array.isArray(e)) return e.map((n) => rt(n, t));
5477
+ if (Array.isArray(e)) return e.map((n) => ot(n, t));
5468
5478
  if (e && typeof e == "object") {
5469
5479
  const n = {};
5470
- for (const [a, r] of Object.entries(e)) n[a] = rt(r, t);
5480
+ for (const [a, r] of Object.entries(e)) n[a] = ot(r, t);
5471
5481
  return n;
5472
5482
  }
5473
5483
  return e;
5474
5484
  }
5475
- function Ti(e, t) {
5485
+ function Ii(e, t) {
5476
5486
  var n;
5477
5487
  switch (e.kind) {
5478
5488
  case "static":
5479
5489
  return e.value;
5480
5490
  case "input":
5481
- return We(t.inputs, e.path);
5491
+ return ze(t.inputs, e.path);
5482
5492
  case "output":
5483
- return We(t.outputs, e.path);
5493
+ return ze(t.outputs, e.path);
5484
5494
  case "setting":
5485
- return We(t.settings, e.path);
5495
+ return ze(t.settings, e.path);
5486
5496
  case "context":
5487
- return We(t.context, e.path);
5497
+ return ze(t.context, e.path);
5488
5498
  case "token":
5489
5499
  return (n = t.tokens) == null ? void 0 : n[e.name];
5490
5500
  case "callback":
@@ -5493,10 +5503,10 @@ function Ti(e, t) {
5493
5503
  return;
5494
5504
  }
5495
5505
  }
5496
- function Fi(e, t, n) {
5506
+ function Ri(e, t, n) {
5497
5507
  const a = {};
5498
5508
  for (const u of e) {
5499
- let m = Ti(u.source, n);
5509
+ let m = Ii(u.source, n);
5500
5510
  const d = m === "" || m == null;
5501
5511
  if (u.omitWhenEmpty && d) continue;
5502
5512
  const i = gn(u.key, t.keyCase);
@@ -5505,14 +5515,14 @@ function Fi(e, t, n) {
5505
5515
  bn(a, i, null);
5506
5516
  continue;
5507
5517
  }
5508
- u.transform && u.transform !== "none" && (m = Si(m, u.transform)), bn(a, i, Pi(m, u.type, t));
5518
+ u.transform && u.transform !== "none" && (m = Pi(m, u.transform)), bn(a, i, Fi(m, u.type, t));
5509
5519
  }
5510
5520
  const r = t.include, s = (u, m) => {
5511
- m !== void 0 && (a[gn(u, t.keyCase)] = rt(m, t.numberEncoding));
5521
+ m !== void 0 && (a[gn(u, t.keyCase)] = ot(m, t.numberEncoding));
5512
5522
  };
5513
5523
  return r != null && r.inputs && s("inputs", n.inputs), r != null && r.outputs && s("outputs", n.outputs), r != null && r.schedule && s("schedule", n.schedule), r != null && r.settingsSnapshot && s("settingsSnapshot", n.settings), r != null && r.meta && s("meta", n.context), t.numberEncoding === "number" && console.warn('[fincalc] numberEncoding="number" reintroduces float error; prefer "string".'), t.mode === "wrapped" && t.wrapperKey ? { [t.wrapperKey]: a } : a;
5514
5524
  }
5515
- const bs = {
5525
+ const vs = {
5516
5526
  mode: "flat",
5517
5527
  keyCase: "asIs",
5518
5528
  dateFormat: "iso",
@@ -5521,9 +5531,9 @@ const bs = {
5521
5531
  include: { inputs: !0, outputs: !0, schedule: !1, settingsSnapshot: !0, meta: !0 }
5522
5532
  };
5523
5533
  function vn(e) {
5524
- return rt(e, "string");
5534
+ return ot(e, "string");
5525
5535
  }
5526
- function gs(e) {
5536
+ function ks(e) {
5527
5537
  const t = e.settings;
5528
5538
  return {
5529
5539
  schemaVersion: 1,
@@ -5557,17 +5567,17 @@ function gs(e) {
5557
5567
  warnings: e.warnings ?? []
5558
5568
  },
5559
5569
  ...e.attachments && e.attachments.length ? { attachments: e.attachments } : {},
5560
- client: { tz: e.clientTz ?? Ii(), platform: "web" }
5570
+ client: { tz: e.clientTz ?? Ei(), platform: "web" }
5561
5571
  };
5562
5572
  }
5563
- function Ii() {
5573
+ function Ei() {
5564
5574
  try {
5565
5575
  return Intl.DateTimeFormat().resolvedOptions().timeZone || "UTC";
5566
5576
  } catch {
5567
5577
  return "UTC";
5568
5578
  }
5569
5579
  }
5570
- const He = ["save", "update", "get", "list", "delete", "upload", "uploadUrl", "rates", "settings"], Ri = {
5580
+ const He = ["save", "update", "get", "list", "delete", "upload", "uploadUrl", "rates", "settings"], Mi = {
5571
5581
  save: "POST",
5572
5582
  update: "PUT",
5573
5583
  get: "GET",
@@ -5577,7 +5587,7 @@ const He = ["save", "update", "get", "list", "delete", "upload", "uploadUrl", "r
5577
5587
  uploadUrl: "GET",
5578
5588
  rates: "GET",
5579
5589
  settings: "GET"
5580
- }, ca = ["bearer", "apiKeyHeader", "basic", "custom"], Ei = {
5590
+ }, ua = ["bearer", "apiKeyHeader", "basic", "custom"], $i = {
5581
5591
  strategy: "multipart",
5582
5592
  fieldName: "file",
5583
5593
  maxBytes: 10 * 1024 * 1024,
@@ -5586,10 +5596,10 @@ const He = ["save", "update", "get", "list", "delete", "upload", "uploadUrl", "r
5586
5596
  checksum: "none",
5587
5597
  chunked: { enabled: !1, chunkBytes: 1024 * 1024 }
5588
5598
  };
5589
- function ua() {
5599
+ function da() {
5590
5600
  const e = {};
5591
5601
  for (const t of He)
5592
- e[t] = { path: `/calculations${t === "save" || t === "list" ? "" : t === "get" || t === "update" || t === "delete" ? "/:id" : "/" + t}`, method: Ri[t], enabled: t === "save" || t === "list" };
5602
+ e[t] = { path: `/calculations${t === "save" || t === "list" ? "" : t === "get" || t === "update" || t === "delete" ? "/:id" : "/" + t}`, method: Mi[t], enabled: t === "save" || t === "list" };
5593
5603
  return {
5594
5604
  baseUrl: "https://api.example.com/v1",
5595
5605
  auth: { strategy: "bearer", headerName: "Authorization" },
@@ -5597,17 +5607,17 @@ function ua() {
5597
5607
  credentials: "same-origin",
5598
5608
  retry: { attempts: 3, backoff: "exponential", baseDelayMs: 300, retryOn: [408, 429, 500, 502, 503, 504], respectRetryAfter: !0 },
5599
5609
  endpoints: e,
5600
- upload: Ei
5610
+ upload: $i
5601
5611
  };
5602
5612
  }
5603
- const Mi = {
5613
+ const Ai = {
5604
5614
  mode: "flat",
5605
5615
  keyCase: "asIs",
5606
5616
  dateFormat: "iso",
5607
5617
  nullHandling: "omit",
5608
5618
  numberEncoding: "string",
5609
5619
  include: { inputs: !0, outputs: !0, schedule: !1, settingsSnapshot: !0, meta: !0 }
5610
- }, $i = [
5620
+ }, Di = [
5611
5621
  { key: "calculator", source: { kind: "context", path: "calculator" }, type: "string", required: !0, omitWhenEmpty: !1 },
5612
5622
  { key: "principal", source: { kind: "input", path: "principal" }, type: "number", required: !0, omitWhenEmpty: !1 },
5613
5623
  { key: "payment", source: { kind: "output", path: "payment" }, type: "number", required: !1, omitWhenEmpty: !1 },
@@ -5626,7 +5636,7 @@ function kn(e) {
5626
5636
  n /= 1024, a++;
5627
5637
  return `${n.toFixed(n < 10 ? 1 : 0)} ${t[a]}`;
5628
5638
  }
5629
- function da(e, t, n) {
5639
+ function ma(e, t, n) {
5630
5640
  switch (e) {
5631
5641
  case "bearer":
5632
5642
  return { Authorization: `Bearer ${n}` };
@@ -5644,9 +5654,9 @@ function da(e, t, n) {
5644
5654
  function qe(e, t) {
5645
5655
  return t ? /^https?:\/\//i.test(t) ? t : `${e.replace(/\/+$/, "")}/${t.replace(/^\/+/, "")}` : e;
5646
5656
  }
5647
- const 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);
5657
+ const Li = ["Connection", "Endpoints", "Upload", "Payload", "Test", "cURL", "Queue"];
5658
+ function pa({ hostConfig: e, getToken: t } = {}) {
5659
+ const { settings: n } = ue(), [a, r] = M("Connection"), [s, u] = M(da), [m, d] = M(Ai), [i, c] = M(Di);
5650
5660
  if (!n.features.integrationPanel)
5651
5661
  return /* @__PURE__ */ o("section", { className: "card", "data-part": "integration-panel", children: /* @__PURE__ */ b("div", { className: "panel-head", children: [
5652
5662
  /* @__PURE__ */ o("h2", { children: "Integration" }),
@@ -5668,12 +5678,12 @@ function ma({ hostConfig: e, getToken: t } = {}) {
5668
5678
  /* @__PURE__ */ o("h2", { children: "Integration" }),
5669
5679
  /* @__PURE__ */ o("p", { children: "Point the library at your backend without a code change. Nothing here stores a secret." })
5670
5680
  ] }),
5671
- /* @__PURE__ */ o("div", { className: "tabs", role: "tablist", "aria-label": "Integration settings", children: Ai.map((f) => /* @__PURE__ */ o("button", { role: "tab", "aria-selected": a === f, onClick: () => r(f), children: f }, f)) }),
5681
+ /* @__PURE__ */ o("div", { className: "tabs", role: "tablist", "aria-label": "Integration settings", children: Li.map((f) => /* @__PURE__ */ o("button", { role: "tab", "aria-selected": a === f, onClick: () => r(f), children: f }, f)) }),
5672
5682
  /* @__PURE__ */ b("div", { role: "tabpanel", "aria-label": a, children: [
5673
- a === "Connection" && /* @__PURE__ */ o(Di, { cfg: s, patch: p, hostLocked: l, getToken: t }),
5674
- a === "Endpoints" && /* @__PURE__ */ o(Li, { cfg: s, setCfg: u, locked: l("endpoints") }),
5683
+ a === "Connection" && /* @__PURE__ */ o(Ui, { cfg: s, patch: p, hostLocked: l, getToken: t }),
5684
+ a === "Endpoints" && /* @__PURE__ */ o(Oi, { cfg: s, setCfg: u, locked: l("endpoints") }),
5675
5685
  a === "Upload" && /* @__PURE__ */ o(
5676
- Ui,
5686
+ Bi,
5677
5687
  {
5678
5688
  upload: s.upload,
5679
5689
  baseUrl: s.baseUrl,
@@ -5683,7 +5693,7 @@ function ma({ hostConfig: e, getToken: t } = {}) {
5683
5693
  }
5684
5694
  ),
5685
5695
  a === "Payload" && /* @__PURE__ */ o(
5686
- qi,
5696
+ ji,
5687
5697
  {
5688
5698
  fields: i,
5689
5699
  setFields: c,
@@ -5692,11 +5702,11 @@ function ma({ hostConfig: e, getToken: t } = {}) {
5692
5702
  ctx: h
5693
5703
  }
5694
5704
  ),
5695
- a === "Test" && /* @__PURE__ */ o(ji, { cfg: s, getToken: t }),
5696
- a === "cURL" && /* @__PURE__ */ o(Vi, { cfg: s }),
5697
- a === "Queue" && /* @__PURE__ */ o(Yi, { cfg: s, getToken: t })
5705
+ a === "Test" && /* @__PURE__ */ o(Yi, { cfg: s, getToken: t }),
5706
+ a === "cURL" && /* @__PURE__ */ o(Ki, { cfg: s }),
5707
+ a === "Queue" && /* @__PURE__ */ o(Wi, { cfg: s, getToken: t })
5698
5708
  ] }),
5699
- /* @__PURE__ */ o(Ki, { cfg: s, setCfg: u })
5709
+ /* @__PURE__ */ o(zi, { cfg: s, setCfg: u })
5700
5710
  ] });
5701
5711
  }
5702
5712
  function Fe({ on: e, children: t }) {
@@ -5747,13 +5757,13 @@ function le({
5747
5757
  /* @__PURE__ */ o("div", { className: "input-wrap", children: /* @__PURE__ */ o("select", { value: t, onChange: (s) => a(s.target.value), "aria-label": e, children: r.map((s) => /* @__PURE__ */ o("option", { value: s.value, children: s.label }, s.value)) }) })
5748
5758
  ] });
5749
5759
  }
5750
- function Di({
5760
+ function Ui({
5751
5761
  cfg: e,
5752
5762
  patch: t,
5753
5763
  hostLocked: n,
5754
5764
  getToken: a
5755
5765
  }) {
5756
- const r = ca.includes(e.auth.strategy);
5766
+ const r = ua.includes(e.auth.strategy);
5757
5767
  return /* @__PURE__ */ b("div", { className: "grid two", children: [
5758
5768
  /* @__PURE__ */ o(Fe, { on: n("baseUrl"), children: /* @__PURE__ */ o(ne, { label: "Base URL", value: e.baseUrl, onChange: (s) => t({ baseUrl: s }), help: "Absolute origin + base path" }) }),
5759
5769
  /* @__PURE__ */ o(
@@ -5806,7 +5816,7 @@ function Di({
5806
5816
  )
5807
5817
  ] });
5808
5818
  }
5809
- function Li({ cfg: e, setCfg: t, locked: n }) {
5819
+ function Oi({ cfg: e, setCfg: t, locked: n }) {
5810
5820
  const a = (r, s) => t((u) => ({ ...u, endpoints: { ...u.endpoints, [r]: { ...u.endpoints[r], ...s } } }));
5811
5821
  return /* @__PURE__ */ o(Fe, { on: n, children: /* @__PURE__ */ o("div", { className: "int-table-wrap", children: /* @__PURE__ */ b("table", { className: "int-table", children: [
5812
5822
  /* @__PURE__ */ o("thead", { children: /* @__PURE__ */ b("tr", { children: [
@@ -5829,10 +5839,10 @@ function Li({ cfg: e, setCfg: t, locked: n }) {
5829
5839
  }) })
5830
5840
  ] }) }) });
5831
5841
  }
5832
- function Ui({ upload: e, baseUrl: t, uploadUri: n, onChange: a, locked: r }) {
5842
+ function Bi({ upload: e, baseUrl: t, uploadUri: n, onChange: a, locked: r }) {
5833
5843
  var m, d, i;
5834
5844
  const s = (c) => a({ ...e, ...c }), u = X(
5835
- () => ia(e.filenameTemplate, { calculator: "loan.emi", kind: "pdf", inputsHash: Ue.inputsHash, filename: "x.pdf" }),
5845
+ () => sa(e.filenameTemplate, { calculator: "loan.emi", kind: "pdf", inputsHash: Ue.inputsHash, filename: "x.pdf" }),
5836
5846
  [e.filenameTemplate]
5837
5847
  );
5838
5848
  return /* @__PURE__ */ o(Fe, { on: r, children: /* @__PURE__ */ b("div", { className: "grid two", children: [
@@ -5884,14 +5894,14 @@ function Ui({ upload: e, baseUrl: t, uploadUri: n, onChange: a, locked: r }) {
5884
5894
  ] })
5885
5895
  ] }) });
5886
5896
  }
5887
- const Oi = ["static", "input", "output", "setting", "context", "token", "callback"];
5888
- function Bi(e) {
5897
+ const _i = ["static", "input", "output", "setting", "context", "token", "callback"];
5898
+ function Hi(e) {
5889
5899
  return e.kind === "static" ? String(e.value) : e.kind === "token" ? e.name : e.kind === "callback" ? "fn()" : e.path;
5890
5900
  }
5891
- function _i(e, t) {
5901
+ function qi(e, t) {
5892
5902
  return e.kind === "static" ? { kind: "static", value: t } : e.kind === "token" ? { kind: "token", name: t } : e.kind === "callback" ? e : { kind: e.kind, path: t };
5893
5903
  }
5894
- function Hi(e) {
5904
+ function Gi(e) {
5895
5905
  switch (e) {
5896
5906
  case "static":
5897
5907
  return { kind: "static", value: "" };
@@ -5903,7 +5913,7 @@ function Hi(e) {
5903
5913
  return { kind: e, path: "" };
5904
5914
  }
5905
5915
  }
5906
- function qi({
5916
+ function ji({
5907
5917
  fields: e,
5908
5918
  setFields: t,
5909
5919
  envelope: n,
@@ -5912,7 +5922,7 @@ function qi({
5912
5922
  }) {
5913
5923
  const s = X(() => {
5914
5924
  try {
5915
- return JSON.stringify(Fi(e, n, r), null, 2);
5925
+ return JSON.stringify(Ri(e, n, r), null, 2);
5916
5926
  } catch (i) {
5917
5927
  return `// ${i instanceof Error ? i.message : "preview failed"}`;
5918
5928
  }
@@ -5953,13 +5963,13 @@ function qi({
5953
5963
  ] }) }),
5954
5964
  /* @__PURE__ */ o("tbody", { children: e.map((i, c) => /* @__PURE__ */ b("tr", { children: [
5955
5965
  /* @__PURE__ */ o("td", { children: /* @__PURE__ */ o("input", { value: i.key, onChange: (l) => u(c, { key: l.target.value }), "aria-label": "key", className: "int-cell-input" }) }),
5956
- /* @__PURE__ */ o("td", { children: /* @__PURE__ */ o("select", { value: i.source.kind, onChange: (l) => u(c, { source: Hi(l.target.value) }), "aria-label": "source kind", children: Oi.map((l) => /* @__PURE__ */ o("option", { children: l }, l)) }) }),
5966
+ /* @__PURE__ */ o("td", { children: /* @__PURE__ */ o("select", { value: i.source.kind, onChange: (l) => u(c, { source: Gi(l.target.value) }), "aria-label": "source kind", children: _i.map((l) => /* @__PURE__ */ o("option", { children: l }, l)) }) }),
5957
5967
  /* @__PURE__ */ o("td", { children: /* @__PURE__ */ o(
5958
5968
  "input",
5959
5969
  {
5960
- value: Bi(i.source),
5970
+ value: Hi(i.source),
5961
5971
  disabled: i.source.kind === "callback",
5962
- onChange: (l) => u(c, { source: _i(i.source, l.target.value) }),
5972
+ onChange: (l) => u(c, { source: qi(i.source, l.target.value) }),
5963
5973
  "aria-label": "source value",
5964
5974
  className: "int-cell-input"
5965
5975
  }
@@ -5990,7 +6000,7 @@ function qi({
5990
6000
  ] })
5991
6001
  ] });
5992
6002
  }
5993
- function Gi(e, t) {
6003
+ function Vi(e, t) {
5994
6004
  const n = {};
5995
6005
  for (const a of He) {
5996
6006
  const r = e.endpoints[a];
@@ -6004,10 +6014,10 @@ function Gi(e, t) {
6004
6014
  retry: e.retry,
6005
6015
  upload: e.upload,
6006
6016
  offlineQueue: { enabled: !0, storage: "memory", maxItems: 200, flushOn: "manual" },
6007
- getAuth: t ? async () => da(e.auth.strategy, e.auth.headerName, await t()) : void 0
6017
+ getAuth: t ? async () => ma(e.auth.strategy, e.auth.headerName, await t()) : void 0
6008
6018
  };
6009
6019
  }
6010
- function ji({ cfg: e, getToken: t }) {
6020
+ function Yi({ cfg: e, getToken: t }) {
6011
6021
  const [n, a] = M({ loading: !1 }), [r, s] = M("save");
6012
6022
  return /* @__PURE__ */ b("div", { children: [
6013
6023
  /* @__PURE__ */ b("div", { className: "grid two", children: [
@@ -6015,11 +6025,11 @@ function ji({ cfg: e, getToken: t }) {
6015
6025
  /* @__PURE__ */ o("div", { className: "field", style: { display: "flex", alignItems: "flex-end" }, children: /* @__PURE__ */ o("button", { type: "button", className: "icon-btn", onClick: async () => {
6016
6026
  a({ loading: !0 });
6017
6027
  const m = e.endpoints[r], d = qe(e.baseUrl, m.path).replace(/:id\b/, "sample-id"), i = { "content-type": "application/json", "X-FinCalc-Test": "1" };
6018
- t && Object.assign(i, da(e.auth.strategy, e.auth.headerName, await t()));
6028
+ t && Object.assign(i, ma(e.auth.strategy, e.auth.headerName, await t()));
6019
6029
  const c = performance.now();
6020
6030
  try {
6021
6031
  const l = await fetch(d, { method: m.method, headers: i, credentials: e.credentials }), p = await l.text(), h = {};
6022
- l.headers.forEach((f, y) => h[y] = f), a({ loading: !1, ok: l.ok, status: l.status, ms: Math.round(performance.now() - c), headers: h, body: Wi(p), sent: { url: d, method: m.method, headers: $t(i) } });
6032
+ l.headers.forEach((f, y) => h[y] = f), a({ loading: !1, ok: l.ok, status: l.status, ms: Math.round(performance.now() - c), headers: h, body: Ji(p), sent: { url: d, method: m.method, headers: $t(i) } });
6023
6033
  } catch (l) {
6024
6034
  a({ loading: !1, ok: !1, ms: Math.round(performance.now() - c), error: l instanceof Error ? l.message : "request failed", sent: { url: d, method: m.method, headers: $t(i) } });
6025
6035
  }
@@ -6049,9 +6059,9 @@ ${JSON.stringify(n.sent.headers, null, 2)}` })
6049
6059
  ] })
6050
6060
  ] });
6051
6061
  }
6052
- function Vi({ cfg: e }) {
6062
+ function Ki({ cfg: e }) {
6053
6063
  const [t, n] = M(!1), [a, r] = M("save"), s = e.endpoints[a], u = qe(e.baseUrl, s.path).replace(/:id\b/, "sample-id"), m = { "content-type": "application/json" };
6054
- ca.includes(e.auth.strategy) && (m[e.auth.strategy === "apiKeyHeader" || e.auth.strategy === "custom" ? e.auth.headerName || "X-API-Key" : "Authorization"] = t ? "<token>" : "***");
6064
+ ua.includes(e.auth.strategy) && (m[e.auth.strategy === "apiKeyHeader" || e.auth.strategy === "custom" ? e.auth.headerName || "X-API-Key" : "Authorization"] = t ? "<token>" : "***");
6055
6065
  const d = [`curl -X ${s.method} '${u}'`];
6056
6066
  for (const [c, l] of Object.entries(m)) d.push(` -H '${c}: ${l}'`);
6057
6067
  ["POST", "PUT", "PATCH"].includes(s.method) && d.push(` -d '{"example":"body"}'`);
@@ -6072,8 +6082,8 @@ function Vi({ cfg: e }) {
6072
6082
  }, children: "Copy" })
6073
6083
  ] });
6074
6084
  }
6075
- function 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());
6085
+ function Wi({ cfg: e, getToken: t }) {
6086
+ const n = X(() => gi(Vi(e, t)), [e, t]), [a, r] = M(() => n.queue.list()), [s, u] = M(""), m = () => r(n.queue.list());
6077
6087
  return /* @__PURE__ */ b("div", { children: [
6078
6088
  /* @__PURE__ */ b("div", { className: "actions-row", style: { marginTop: 0 }, children: [
6079
6089
  /* @__PURE__ */ o("button", { type: "button", className: "icon-btn", onClick: m, children: "Refresh" }),
@@ -6102,7 +6112,7 @@ function Yi({ cfg: e, getToken: t }) {
6102
6112
  ] }) })
6103
6113
  ] });
6104
6114
  }
6105
- function Ki({ cfg: e, setCfg: t }) {
6115
+ function zi({ cfg: e, setCfg: t }) {
6106
6116
  const [n, a] = M(""), [r, s] = M("");
6107
6117
  return /* @__PURE__ */ b("div", { className: "accordion", style: { marginTop: 20 }, children: [
6108
6118
  /* @__PURE__ */ o("span", { className: "lbl", children: "Import / export config (JSON)" }),
@@ -6116,7 +6126,7 @@ function Ki({ cfg: e, setCfg: t }) {
6116
6126
  const d = JSON.parse(n);
6117
6127
  for (const i of ["token", "apiKey", "getAuth", "authorization"])
6118
6128
  i in d && (delete d[i], s(`Refused to import "${i}" — the panel never persists a secret.`));
6119
- t(() => ({ ...ua(), ...d })), r || s("Imported.");
6129
+ t(() => ({ ...da(), ...d })), r || s("Imported.");
6120
6130
  } catch {
6121
6131
  s("Invalid JSON.");
6122
6132
  }
@@ -6125,16 +6135,16 @@ function Ki({ cfg: e, setCfg: t }) {
6125
6135
  r && /* @__PURE__ */ o("div", { className: "int-note", children: r })
6126
6136
  ] });
6127
6137
  }
6128
- function Wi(e) {
6138
+ function Ji(e) {
6129
6139
  try {
6130
6140
  return JSON.stringify(JSON.parse(e), null, 2);
6131
6141
  } catch {
6132
6142
  return e;
6133
6143
  }
6134
6144
  }
6135
- const 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 = () => {
6145
+ const Zi = "1234567.891";
6146
+ function Xi() {
6147
+ const { settings: e, update: t, setRegion: n, reset: a, replace: r } = ue(), s = de(null), u = Sn(e).money(g(Zi)), m = () => {
6138
6148
  const i = new Blob([JSON.stringify(e, null, 2)], { type: "application/json" }), c = URL.createObjectURL(i), l = document.createElement("a");
6139
6149
  l.href = c, l.download = "calcsuite-settings.json", l.click(), URL.revokeObjectURL(c);
6140
6150
  }, d = (i) => {
@@ -6225,7 +6235,7 @@ function Ji() {
6225
6235
  options: [["system", "System"], ["light", "Light"], ["dark", "Dark"], ["highContrast", "High contrast"]]
6226
6236
  }
6227
6237
  ) }),
6228
- /* @__PURE__ */ o(W, { label: "Accent colour", children: /* @__PURE__ */ o("div", { className: "swatches", children: wa.map((i) => {
6238
+ /* @__PURE__ */ o(W, { label: "Accent colour", children: /* @__PURE__ */ o("div", { className: "swatches", children: Cn.map((i) => {
6229
6239
  const c = e.ui.accent.toLowerCase() === i.main.toLowerCase();
6230
6240
  return /* @__PURE__ */ o(
6231
6241
  "button",
@@ -6246,7 +6256,7 @@ function Ji() {
6246
6256
  {
6247
6257
  value: e.ui.fontFamily,
6248
6258
  onChange: (i) => t({ ui: { fontFamily: i } }),
6249
- options: Cn.map((i) => [i.id, i.label])
6259
+ options: Pn.map((i) => [i.id, i.label])
6250
6260
  }
6251
6261
  ) }),
6252
6262
  /* @__PURE__ */ o(W, { label: "Density", children: /* @__PURE__ */ o(
@@ -6269,7 +6279,7 @@ function Ji() {
6269
6279
  " — so exports (PDF/CSV/…) and saved calculations post directly to your own server. No secret is ever stored by the app."
6270
6280
  ] })
6271
6281
  ] }),
6272
- e.features.integrationPanel && /* @__PURE__ */ o(ma, {}),
6282
+ e.features.integrationPanel && /* @__PURE__ */ o(pa, {}),
6273
6283
  /* @__PURE__ */ b("div", { className: "actions-row", children: [
6274
6284
  /* @__PURE__ */ o("button", { className: "icon-btn", onClick: m, children: "Export settings" }),
6275
6285
  /* @__PURE__ */ o("button", { className: "icon-btn", onClick: () => {
@@ -6302,7 +6312,7 @@ function he({ value: e, onChange: t, options: n }) {
6302
6312
  function Le({ on: e, onClick: t }) {
6303
6313
  return /* @__PURE__ */ o("button", { type: "button", role: "switch", "aria-checked": e, className: `toggle ${e ? "on" : ""}`, onClick: t, children: /* @__PURE__ */ o("span", { className: "knob" }) });
6304
6314
  }
6305
- function Zi({
6315
+ function Qi({
6306
6316
  items: e,
6307
6317
  onRestore: t,
6308
6318
  onClear: n
@@ -6331,7 +6341,7 @@ function wn(e, t) {
6331
6341
  for (let s = 0; s < n.length && r < e.length; s++) n[s] === e[r] && r++;
6332
6342
  return r === e.length ? 10 : -1;
6333
6343
  }
6334
- function Xi({
6344
+ function es({
6335
6345
  calculators: e,
6336
6346
  actions: t,
6337
6347
  onPick: n,
@@ -6341,7 +6351,7 @@ function Xi({
6341
6351
  Q(() => {
6342
6352
  var l;
6343
6353
  return (l = d.current) == null ? void 0 : l.focus();
6344
- }, []), Q(() => (Sa(), () => Ca()), []);
6354
+ }, []), Q(() => (Pa(), () => Ta()), []);
6345
6355
  const i = X(() => {
6346
6356
  const l = e.map((y) => ({
6347
6357
  key: `calc:${y.id}`,
@@ -6391,7 +6401,7 @@ function Xi({
6391
6401
  ] })
6392
6402
  ] }) });
6393
6403
  }
6394
- const dt = (e) => ({
6404
+ const Ge = (e) => ({
6395
6405
  width: e,
6396
6406
  height: e,
6397
6407
  viewBox: "0 0 24 24",
@@ -6402,31 +6412,44 @@ const dt = (e) => ({
6402
6412
  strokeLinejoin: "round",
6403
6413
  "aria-hidden": !0
6404
6414
  });
6405
- function Qi({ size: e = 17 }) {
6406
- return /* @__PURE__ */ b("svg", { ...dt(e), children: [
6415
+ function ts({ size: e = 17 }) {
6416
+ return /* @__PURE__ */ b("svg", { ...Ge(e), children: [
6407
6417
  /* @__PURE__ */ o("circle", { cx: "12", cy: "12", r: "3" }),
6408
6418
  /* @__PURE__ */ o("path", { d: "M19.4 15a1.65 1.65 0 0 0 .33 1.82l.06.06a2 2 0 1 1-2.83 2.83l-.06-.06a1.65 1.65 0 0 0-1.82-.33 1.65 1.65 0 0 0-1 1.51V21a2 2 0 0 1-4 0v-.09A1.65 1.65 0 0 0 9 19.4a1.65 1.65 0 0 0-1.82.33l-.06.06a2 2 0 1 1-2.83-2.83l.06-.06a1.65 1.65 0 0 0 .33-1.82 1.65 1.65 0 0 0-1.51-1H3a2 2 0 0 1 0-4h.09A1.65 1.65 0 0 0 4.6 9a1.65 1.65 0 0 0-.33-1.82l-.06-.06a2 2 0 1 1 2.83-2.83l.06.06a1.65 1.65 0 0 0 1.82.33H9a1.65 1.65 0 0 0 1-1.51V3a2 2 0 0 1 4 0v.09a1.65 1.65 0 0 0 1 1.51 1.65 1.65 0 0 0 1.82-.33l.06-.06a2 2 0 1 1 2.83 2.83l-.06.06a1.65 1.65 0 0 0-.33 1.82V9a1.65 1.65 0 0 0 1.51 1H21a2 2 0 0 1 0 4h-.09a1.65 1.65 0 0 0-1.51 1Z" })
6409
6419
  ] });
6410
6420
  }
6411
- function es({ size: e = 17 }) {
6412
- return /* @__PURE__ */ b("svg", { ...dt(e), children: [
6421
+ function ns({ size: e = 17 }) {
6422
+ return /* @__PURE__ */ b("svg", { ...Ge(e), children: [
6413
6423
  /* @__PURE__ */ o("circle", { cx: "12", cy: "12", r: "4" }),
6414
6424
  /* @__PURE__ */ o("path", { d: "M12 2v2M12 20v2M4.93 4.93l1.41 1.41M17.66 17.66l1.41 1.41M2 12h2M20 12h2M6.34 17.66l-1.41 1.41M19.07 4.93l-1.41 1.41" })
6415
6425
  ] });
6416
6426
  }
6417
- function 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" }) });
6427
+ function as({ size: e = 17 }) {
6428
+ return /* @__PURE__ */ o("svg", { ...Ge(e), children: /* @__PURE__ */ o("path", { d: "M12 3a6 6 0 0 0 9 9 9 9 0 1 1-9-9Z" }) });
6429
+ }
6430
+ function ha({ size: e = 17 }) {
6431
+ return /* @__PURE__ */ b("svg", { ...Ge(e), children: [
6432
+ /* @__PURE__ */ o("rect", { x: "4", y: "2", width: "16", height: "20", rx: "2" }),
6433
+ /* @__PURE__ */ o("line", { x1: "8", y1: "6", x2: "16", y2: "6" }),
6434
+ /* @__PURE__ */ o("line", { x1: "8", y1: "10", x2: "8", y2: "10" }),
6435
+ /* @__PURE__ */ o("line", { x1: "12", y1: "10", x2: "12", y2: "10" }),
6436
+ /* @__PURE__ */ o("line", { x1: "16", y1: "10", x2: "16", y2: "10" }),
6437
+ /* @__PURE__ */ o("line", { x1: "8", y1: "14", x2: "8", y2: "14" }),
6438
+ /* @__PURE__ */ o("line", { x1: "12", y1: "14", x2: "12", y2: "14" }),
6439
+ /* @__PURE__ */ o("line", { x1: "16", y1: "14", x2: "16", y2: "14" }),
6440
+ /* @__PURE__ */ o("line", { x1: "8", y1: "18", x2: "12", y2: "18" })
6441
+ ] });
6419
6442
  }
6420
- function ns({ size: e = 17 }) {
6421
- return /* @__PURE__ */ b("svg", { ...dt(e), children: [
6443
+ function rs({ size: e = 17 }) {
6444
+ return /* @__PURE__ */ b("svg", { ...Ge(e), children: [
6422
6445
  /* @__PURE__ */ o("path", { d: "M3 3v5h5" }),
6423
6446
  /* @__PURE__ */ o("path", { d: "M3.05 13A9 9 0 1 0 6 5.3L3 8" }),
6424
6447
  /* @__PURE__ */ o("path", { d: "M12 7v5l4 2" })
6425
6448
  ] });
6426
6449
  }
6427
- const 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();
6450
+ const os = { "loan.emi": Jn, scientific: Xn, currency: oa };
6451
+ function is({ onClose: e }) {
6452
+ const { settings: t, setRegion: n, update: a, resolvedTheme: r } = ue(), s = t.region, u = X(() => Xr(s), [s]), [m, d] = M("loan.emi"), [i, c] = M("calc"), [l, p] = M(void 0), [h, f] = M(!1), { items: y, clear: w } = Uo();
6430
6453
  Q(() => {
6431
6454
  const x = () => {
6432
6455
  const T = new URLSearchParams(location.hash.replace(/^#/, "") || location.search), $ = T.get("fincalc");
@@ -6469,8 +6492,11 @@ function rs({ onClose: e }) {
6469
6492
  return /* @__PURE__ */ b("div", { className: "fc-shell", onKeyDown: k, children: [
6470
6493
  /* @__PURE__ */ b("header", { className: "fc-topbar", children: [
6471
6494
  /* @__PURE__ */ b("div", { className: "brand fc-brand", children: [
6472
- /* @__PURE__ */ o("strong", { children: "CalcSuite" }),
6473
- /* @__PURE__ */ o("a", { className: "fc-brand-sub", href: "https://acecbm.com", target: "_blank", rel: "noopener noreferrer", children: "an AceCBM product ↗" })
6495
+ /* @__PURE__ */ o("span", { className: "fc-brand-mark", "aria-hidden": "true", children: /* @__PURE__ */ o(ha, { size: 22 }) }),
6496
+ /* @__PURE__ */ b("div", { className: "fc-brand-text", children: [
6497
+ /* @__PURE__ */ o("strong", { children: "CalcSuite" }),
6498
+ /* @__PURE__ */ o("a", { className: "fc-brand-sub", href: "https://acecbm.com", target: "_blank", rel: "noopener noreferrer", children: "an AceCBM product ↗" })
6499
+ ] })
6474
6500
  ] }),
6475
6501
  /* @__PURE__ */ b("div", { className: "fc-top-actions", children: [
6476
6502
  /* @__PURE__ */ o("button", { className: "icon-btn", onClick: () => f(!0), "aria-label": "Search", children: "⌘K Search" }),
@@ -6478,17 +6504,17 @@ function rs({ onClose: e }) {
6478
6504
  /* @__PURE__ */ o("button", { "aria-pressed": s === "IN", onClick: () => n("IN"), children: "🇮🇳" }),
6479
6505
  /* @__PURE__ */ o("button", { "aria-pressed": s === "US", onClick: () => n("US"), children: "🇺🇸" })
6480
6506
  ] }),
6481
- /* @__PURE__ */ o("button", { className: "icon-btn icon-only", onClick: () => a({ ui: { theme: r === "dark" ? "light" : "dark" } }), "aria-label": r === "dark" ? "Switch to light mode" : "Switch to dark mode", children: r === "dark" ? /* @__PURE__ */ o(es, {}) : /* @__PURE__ */ o(ts, {}) }),
6507
+ /* @__PURE__ */ o("button", { className: "icon-btn icon-only", onClick: () => a({ ui: { theme: r === "dark" ? "light" : "dark" } }), "aria-label": r === "dark" ? "Switch to light mode" : "Switch to dark mode", children: r === "dark" ? /* @__PURE__ */ o(ns, {}) : /* @__PURE__ */ o(as, {}) }),
6482
6508
  /* @__PURE__ */ b("button", { className: "icon-btn", "aria-label": "History", onClick: () => c("history"), children: [
6483
- /* @__PURE__ */ o(ns, {}),
6509
+ /* @__PURE__ */ o(rs, {}),
6484
6510
  " History"
6485
6511
  ] }),
6486
- /* @__PURE__ */ o("button", { className: "icon-btn icon-only", "aria-label": "Settings", onClick: () => c("settings"), children: /* @__PURE__ */ o(Qi, {}) }),
6512
+ /* @__PURE__ */ o("button", { className: "icon-btn icon-only", "aria-label": "Settings", onClick: () => c("settings"), children: /* @__PURE__ */ o(ts, {}) }),
6487
6513
  e && /* @__PURE__ */ o("button", { className: "icon-btn icon-only", "aria-label": "Close", onClick: e, children: "✕" })
6488
6514
  ] })
6489
6515
  ] }),
6490
6516
  /* @__PURE__ */ b("div", { className: "fc-body", children: [
6491
- /* @__PURE__ */ o("nav", { className: "fc-rail", "aria-label": "Calculators", children: Zr.map((x) => {
6517
+ /* @__PURE__ */ o("nav", { className: "fc-rail", "aria-label": "Calculators", children: Qr.map((x) => {
6492
6518
  const T = u.filter(($) => $.group === x.id);
6493
6519
  return T.length === 0 ? null : /* @__PURE__ */ b("div", { className: "rail-group", children: [
6494
6520
  /* @__PURE__ */ o("div", { className: "rail-group-label", children: x.label }),
@@ -6504,24 +6530,24 @@ function rs({ onClose: e }) {
6504
6530
  ] }, x.id);
6505
6531
  }) }),
6506
6532
  /* @__PURE__ */ o("main", { className: "fc-main", children: /* @__PURE__ */ b("div", { className: "fc-anim-in", children: [
6507
- i === "settings" && /* @__PURE__ */ o(Ji, {}),
6508
- i === "history" && /* @__PURE__ */ o(Zi, { items: y, onRestore: P, onClear: w }),
6509
- i === "integration" && /* @__PURE__ */ o(ma, {}),
6533
+ i === "settings" && /* @__PURE__ */ o(Xi, {}),
6534
+ i === "history" && /* @__PURE__ */ o(Qi, { items: y, onRestore: P, onClear: w }),
6535
+ i === "integration" && /* @__PURE__ */ o(pa, {}),
6510
6536
  i === "calc" && /* @__PURE__ */ o(
6511
- ci,
6537
+ di,
6512
6538
  {
6513
6539
  def: F,
6514
6540
  seed: l,
6515
- customRegistry: as,
6541
+ customRegistry: os,
6516
6542
  actions: (x, T) => x ? /* @__PURE__ */ b(re, { children: [
6517
6543
  /* @__PURE__ */ o(
6518
- Wn,
6544
+ zn,
6519
6545
  {
6520
6546
  item: { id: F.id, title: `${F.title} — ${x.primary.value}`, primary: x.primary.value, values: T }
6521
6547
  }
6522
6548
  ),
6523
6549
  /* @__PURE__ */ o(
6524
- jn,
6550
+ Vn,
6525
6551
  {
6526
6552
  payload: {
6527
6553
  calculatorId: F.id,
@@ -6538,37 +6564,11 @@ function rs({ onClose: e }) {
6538
6564
  )
6539
6565
  ] }, i === "calc" ? `calc:${F.id}` : i) })
6540
6566
  ] }),
6541
- h && /* @__PURE__ */ o(Xi, { calculators: u, actions: N, onPick: S, onClose: () => f(!1) })
6567
+ h && /* @__PURE__ */ o(es, { calculators: u, actions: N, onPick: S, onClose: () => f(!1) })
6542
6568
  ] });
6543
6569
  }
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({
6570
+ const Nn = ({ size: e = 22 }) => /* @__PURE__ */ o(ha, { size: e });
6571
+ function ws({
6572
6572
  variant: e = "fab",
6573
6573
  position: t = "bottom-right",
6574
6574
  hotkey: n = "mod+shift+k",
@@ -6605,12 +6605,12 @@ function vs({
6605
6605
  /* @__PURE__ */ o("span", { "aria-hidden": !0, style: { marginRight: 6, display: "inline-flex", alignItems: "center" }, children: m ?? /* @__PURE__ */ o(Nn, { size: 16 }) }),
6606
6606
  u
6607
6607
  ] }),
6608
- /* @__PURE__ */ o(Fa, { open: k, onClose: F.close, title: h, size: p, children: /* @__PURE__ */ o(rs, { onClose: F.close }) })
6608
+ /* @__PURE__ */ o(Ra, { open: k, onClose: F.close, title: h, size: p, children: /* @__PURE__ */ o(is, { onClose: F.close }) })
6609
6609
  ] });
6610
6610
  }
6611
- const 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();
6611
+ const ss = 60 * 60 * 1e3, Nt = (e, t) => `${e}|${[...t].sort().join(",")}`;
6612
+ function Ns(e, t = {}) {
6613
+ const n = t.ttlMs ?? ss, a = t.now ?? Date.now, r = /* @__PURE__ */ new Map();
6614
6614
  let s = null;
6615
6615
  function u(i) {
6616
6616
  var l;
@@ -6656,71 +6656,71 @@ function ks(e, t = {}) {
6656
6656
  clear: () => r.clear()
6657
6657
  };
6658
6658
  }
6659
- const ws = { solve: Ie, REGIONS: me };
6659
+ const xs = { solve: Ie, REGIONS: me };
6660
6660
  export {
6661
- ci as CalculatorPanel,
6662
- io as Chart,
6663
- Xi as CommandPalette,
6664
- ra as CurrencyConverter,
6661
+ di as CalculatorPanel,
6662
+ lo as Chart,
6663
+ es as CommandPalette,
6664
+ oa as CurrencyConverter,
6665
6665
  g as D,
6666
- bs as DEFAULT_ENVELOPE,
6667
- Xe as DEFAULT_SETTINGS,
6666
+ vs as DEFAULT_ENVELOPE,
6667
+ Qe as DEFAULT_SETTINGS,
6668
6668
  H as Decimal,
6669
- Fa as Dialog,
6670
- so as EXPORT_FORMATS,
6671
- jn as ExportMenu,
6672
- Qr as Field,
6673
- Fa as FinCalcDialog,
6669
+ Ra as Dialog,
6670
+ co as EXPORT_FORMATS,
6671
+ Vn as ExportMenu,
6672
+ to as Field,
6673
+ Ra as FinCalcDialog,
6674
6674
  se as FinCalcError,
6675
- 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,
6675
+ ws as FinCalcLauncher,
6676
+ fs as FinCalcProvider,
6677
+ is as FinCalcRoot,
6678
+ Qr as GROUPS,
6679
+ Qi as HistoryPanel,
6680
+ pa as IntegrationPanel,
6681
+ ws as Launcher,
6682
+ Jn as LoanEmiPanel,
6683
+ ka as POLICY_DEFAULT,
6684
+ ro as ResultCard,
6685
+ zn as SaveButton,
6686
+ so as ScheduleTable,
6687
+ Xn as SciCalculator,
6688
+ Xi as SettingsPanel,
6689
+ fs as SettingsProvider,
6690
+ is as Shell,
6691
+ Un as allCalculators,
6692
6692
  ye as boolval,
6693
- ia as buildFilename,
6694
- Fi as buildPayload,
6695
- gs as buildSavePayload,
6693
+ sa as buildFilename,
6694
+ Ri as buildPayload,
6695
+ ks as buildSavePayload,
6696
6696
  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,
6697
+ Xr as calculatorsForRegion,
6698
+ Lo as clearHistory,
6699
+ Mo as createExporter,
6700
+ Ns as createFxCache,
6701
+ gi as createTransport,
6702
+ gs as currency,
6703
6703
  D as dmoney,
6704
- us as eq,
6704
+ ms as eq,
6705
6705
  on as evalExpression,
6706
- ei as evaluateExpression,
6707
- ri as fetchLiveRate,
6708
- hs as finance,
6709
- ds as gt,
6706
+ ni as evaluateExpression,
6707
+ ii as fetchLiveRate,
6708
+ ys as finance,
6709
+ ps as gt,
6710
6710
  ce as isZeroish,
6711
- ws as loan,
6712
- ms as lt,
6711
+ xs as loan,
6712
+ hs as lt,
6713
6713
  Sn as makeFormatter,
6714
6714
  v as metric,
6715
6715
  C as numval,
6716
- Wo as parseExpression,
6716
+ Jo as parseExpression,
6717
6717
  xt as regionDefaults,
6718
- fs as registerCalculator,
6719
- hi as sanitizeFilename,
6720
- Kn as saveHistory,
6718
+ bs as registerCalculator,
6719
+ yi as sanitizeFilename,
6720
+ Wn as saveHistory,
6721
6721
  Ie as solveLoan,
6722
6722
  _ as strval,
6723
6723
  ue as useFinCalc,
6724
- Do as useHistory,
6724
+ Uo as useHistory,
6725
6725
  ue as useSettings
6726
6726
  };