@pyverret/ratejs 1.1.1 → 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/README.md +30 -16
- package/dist/index.cjs +12 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +12 -1
- package/dist/index.js.map +1 -1
- package/package.json +6 -2
package/README.md
CHANGED
|
@@ -8,9 +8,15 @@ Lightweight, dependency-free TypeScript financial math library providing pure ca
|
|
|
8
8
|
npm i @pyverret/ratejs
|
|
9
9
|
```
|
|
10
10
|
|
|
11
|
+
## Validate Before Push
|
|
12
|
+
|
|
13
|
+
```bash
|
|
14
|
+
npm run validate
|
|
15
|
+
```
|
|
16
|
+
|
|
11
17
|
## Live Demo
|
|
12
18
|
|
|
13
|
-
- GitHub Pages URL:
|
|
19
|
+
- GitHub Pages URL: [https://pyverret.github.io/ratejs/](https://pyverret.github.io/ratejs/)
|
|
14
20
|
- Demo source: [`demo/`](./demo)
|
|
15
21
|
|
|
16
22
|
Run locally:
|
|
@@ -44,16 +50,19 @@ const payment = pmt({
|
|
|
44
50
|
ratePerPeriod: 0.06 / 12,
|
|
45
51
|
periods: 360,
|
|
46
52
|
presentValue: 250000,
|
|
47
|
-
futureValue: 0,
|
|
48
|
-
timing: "end",
|
|
53
|
+
futureValue: 0, // optional
|
|
54
|
+
timing: "end", // optional
|
|
49
55
|
});
|
|
50
56
|
|
|
51
57
|
const impliedRate = rate({
|
|
52
58
|
periods: 360,
|
|
53
59
|
payment,
|
|
54
60
|
presentValue: 250000,
|
|
55
|
-
futureValue: 0,
|
|
56
|
-
timing: "end",
|
|
61
|
+
futureValue: 0, // optional
|
|
62
|
+
timing: "end", // optional
|
|
63
|
+
guess: 0.1, // optional
|
|
64
|
+
maxIterations: 100, // optional
|
|
65
|
+
tolerance: 1e-10, // optional
|
|
57
66
|
lowerBound: -0.99, // optional
|
|
58
67
|
upperBound: 10, // optional
|
|
59
68
|
});
|
|
@@ -89,11 +98,11 @@ presentValue({ futureValue: 5000, rate: 0.06, timesPerYear: 12, years: 5 });
|
|
|
89
98
|
```ts
|
|
90
99
|
investmentGrowth({
|
|
91
100
|
initial: 1000,
|
|
92
|
-
contributionPerPeriod: 100,
|
|
101
|
+
contributionPerPeriod: 100, // optional
|
|
93
102
|
rate: 0.06,
|
|
94
103
|
timesPerYear: 12,
|
|
95
104
|
years: 2,
|
|
96
|
-
contributionTiming: "end", //
|
|
105
|
+
contributionTiming: "end", // optional ("end" | "begin")
|
|
97
106
|
});
|
|
98
107
|
```
|
|
99
108
|
|
|
@@ -112,7 +121,8 @@ periodsToReachGoal({
|
|
|
112
121
|
rate: 0.06,
|
|
113
122
|
timesPerYear: 12,
|
|
114
123
|
contributionPerPeriod: 0, // optional
|
|
115
|
-
contributionTiming: "end",
|
|
124
|
+
contributionTiming: "end", // optional
|
|
125
|
+
maxPeriods: 100000, // optional
|
|
116
126
|
});
|
|
117
127
|
```
|
|
118
128
|
|
|
@@ -120,6 +130,7 @@ Edge cases:
|
|
|
120
130
|
- Returns `Infinity` when the goal is unreachable.
|
|
121
131
|
- Throws `RangeError` when `rate / timesPerYear <= -1`.
|
|
122
132
|
- Throws `RangeError` when `maxPeriods` is exceeded for contribution-based iteration.
|
|
133
|
+
- Throws `RangeError` when `contributionTiming` is not `"end"` or `"begin"`.
|
|
123
134
|
|
|
124
135
|
- **`rateToReachGoal`** - Rate per period required to reach a target future value in a given number of periods.
|
|
125
136
|
|
|
@@ -128,8 +139,10 @@ rateToReachGoal({
|
|
|
128
139
|
principal: 1000,
|
|
129
140
|
targetFutureValue: 1500,
|
|
130
141
|
periods: 24,
|
|
131
|
-
contributionPerPeriod: 0,
|
|
132
|
-
contributionTiming: "end",
|
|
142
|
+
contributionPerPeriod: 0, // optional
|
|
143
|
+
contributionTiming: "end", // optional
|
|
144
|
+
maxIterations: 100, // optional
|
|
145
|
+
tolerance: 1e-10, // optional
|
|
133
146
|
lowerBound: -0.99, // optional
|
|
134
147
|
upperBound: 10, // optional
|
|
135
148
|
});
|
|
@@ -137,6 +150,7 @@ rateToReachGoal({
|
|
|
137
150
|
|
|
138
151
|
Edge cases:
|
|
139
152
|
- Throws `RangeError` when no root is found within search bounds.
|
|
153
|
+
- Throws `RangeError` when `contributionTiming` is not `"end"` or `"begin"`.
|
|
140
154
|
|
|
141
155
|
- **`ruleOf72`** - Approximate years to double a lump sum at a given annual rate. Optional `constant: 69` for rule of 69.
|
|
142
156
|
|
|
@@ -158,8 +172,8 @@ cagr({ startValue: 1000, endValue: 2000, years: 10 });
|
|
|
158
172
|
```ts
|
|
159
173
|
irr({
|
|
160
174
|
cashFlows: [-1000, 300, 400, 500],
|
|
161
|
-
guess: 0.1,
|
|
162
|
-
maxIterations: 100,
|
|
175
|
+
guess: 0.1, // optional
|
|
176
|
+
maxIterations: 100, // optional
|
|
163
177
|
lowerBound: -0.99, // optional
|
|
164
178
|
upperBound: 10, // optional
|
|
165
179
|
});
|
|
@@ -204,7 +218,7 @@ presentValueOfAnnuity({
|
|
|
204
218
|
paymentPerPeriod: 100,
|
|
205
219
|
ratePerPeriod: 0.01,
|
|
206
220
|
periods: 36,
|
|
207
|
-
timing: "end",
|
|
221
|
+
timing: "end", // optional
|
|
208
222
|
});
|
|
209
223
|
```
|
|
210
224
|
|
|
@@ -215,7 +229,7 @@ paymentFromPresentValue({
|
|
|
215
229
|
presentValue: 100000,
|
|
216
230
|
ratePerPeriod: 0.005,
|
|
217
231
|
periods: 360,
|
|
218
|
-
timing: "end",
|
|
232
|
+
timing: "end", // optional
|
|
219
233
|
});
|
|
220
234
|
```
|
|
221
235
|
|
|
@@ -243,7 +257,7 @@ amortizationSchedule({
|
|
|
243
257
|
annualRate: 0.06,
|
|
244
258
|
paymentsPerYear: 12,
|
|
245
259
|
years: 30,
|
|
246
|
-
extraPaymentPerPeriod: 50,
|
|
260
|
+
extraPaymentPerPeriod: 50, // optional
|
|
247
261
|
});
|
|
248
262
|
```
|
|
249
263
|
|
|
@@ -280,7 +294,7 @@ Edge cases:
|
|
|
280
294
|
|
|
281
295
|
```ts
|
|
282
296
|
roundToCurrency({ value: 2.125 }); // 2.13
|
|
283
|
-
roundToCurrency({ value: 2.125, decimals: 2, mode: "half-even" });
|
|
297
|
+
roundToCurrency({ value: 2.125, decimals: 2, mode: "half-even" }); // decimals/mode optional
|
|
284
298
|
```
|
|
285
299
|
|
|
286
300
|
## Design
|
package/dist/index.cjs
CHANGED
|
@@ -301,6 +301,11 @@ function paymentFromPresentValue(params) {
|
|
|
301
301
|
}
|
|
302
302
|
|
|
303
303
|
// src/interest/periodsToReachGoal.ts
|
|
304
|
+
function assertContributionTiming(value, name) {
|
|
305
|
+
if (value !== "end" && value !== "begin") {
|
|
306
|
+
throw new RangeError(`${name} must be "end" or "begin"`);
|
|
307
|
+
}
|
|
308
|
+
}
|
|
304
309
|
function periodsToReachGoal(params) {
|
|
305
310
|
const {
|
|
306
311
|
principal,
|
|
@@ -317,6 +322,7 @@ function periodsToReachGoal(params) {
|
|
|
317
322
|
assertPositive(timesPerYear, "timesPerYear");
|
|
318
323
|
assertNonNegative(contributionPerPeriod, "contributionPerPeriod");
|
|
319
324
|
assertPositive(maxPeriods, "maxPeriods");
|
|
325
|
+
assertContributionTiming(contributionTiming, "contributionTiming");
|
|
320
326
|
if (targetFutureValue <= principal) return 0;
|
|
321
327
|
const r = rate2 / timesPerYear;
|
|
322
328
|
if (r <= -1) {
|
|
@@ -372,6 +378,11 @@ function presentValueOfAnnuity(params) {
|
|
|
372
378
|
}
|
|
373
379
|
|
|
374
380
|
// src/interest/rateToReachGoal.ts
|
|
381
|
+
function assertContributionTiming2(value, name) {
|
|
382
|
+
if (value !== "end" && value !== "begin") {
|
|
383
|
+
throw new RangeError(`${name} must be "end" or "begin"`);
|
|
384
|
+
}
|
|
385
|
+
}
|
|
375
386
|
function rateToReachGoal(params) {
|
|
376
387
|
const {
|
|
377
388
|
principal,
|
|
@@ -392,13 +403,13 @@ function rateToReachGoal(params) {
|
|
|
392
403
|
assertFiniteNumber(upperBound, "upperBound");
|
|
393
404
|
assertFiniteNumber(maxIterations, "maxIterations");
|
|
394
405
|
assertFiniteNumber(tolerance, "tolerance");
|
|
406
|
+
assertContributionTiming2(contributionTiming, "contributionTiming");
|
|
395
407
|
if (lowerBound <= -1) throw new RangeError("lowerBound must be > -1");
|
|
396
408
|
if (upperBound <= lowerBound) throw new RangeError("upperBound must be greater than lowerBound");
|
|
397
409
|
if (!Number.isInteger(maxIterations) || maxIterations <= 0) {
|
|
398
410
|
throw new RangeError("maxIterations must be a positive integer");
|
|
399
411
|
}
|
|
400
412
|
if (tolerance <= 0) throw new RangeError("tolerance must be > 0");
|
|
401
|
-
if (periods === 0) return 0;
|
|
402
413
|
if (targetFutureValue <= principal && contributionPerPeriod === 0) return 0;
|
|
403
414
|
if (contributionPerPeriod === 0) {
|
|
404
415
|
if (targetFutureValue <= principal) return 0;
|
package/dist/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/utils/assertions.ts","../src/interest/cagr.ts","../src/interest/compound.ts","../src/interest/effectiveAnnualRate.ts","../src/interest/futureValue.ts","../src/interest/inflationAdjustedAmount.ts","../src/interest/investmentGrowth.ts","../src/utils/solvers.ts","../src/interest/irr.ts","../src/interest/npv.ts","../src/interest/paymentFromPresentValue.ts","../src/interest/periodsToReachGoal.ts","../src/interest/presentValue.ts","../src/interest/presentValueOfAnnuity.ts","../src/interest/rateToReachGoal.ts","../src/interest/realReturn.ts","../src/interest/ruleOf72.ts","../src/interest/tvom.ts","../src/loans/loanPayment.ts","../src/loans/amortizationSchedule.ts","../src/loans/payoffPeriodWithExtra.ts","../src/loans/remainingBalance.ts","../src/utils/roundToCurrency.ts"],"names":["rate","presentValue","futureValue","pmt","fv","pv","findBracket"],"mappings":";;;AAAO,SAAS,kBAAA,CAAmB,OAAe,IAAA,EAAoB;AACpE,EAAA,IAAI,CAAC,MAAA,CAAO,QAAA,CAAS,KAAK,CAAA,EAAG;AAC3B,IAAA,MAAM,IAAI,UAAA,CAAW,CAAA,EAAG,IAAI,CAAA,wBAAA,CAA0B,CAAA;AAAA,EACxD;AACF;AAEO,SAAS,iBAAA,CAAkB,OAAe,IAAA,EAAoB;AACnE,EAAA,kBAAA,CAAmB,OAAO,IAAI,CAAA;AAC9B,EAAA,IAAI,QAAQ,CAAA,EAAG;AACb,IAAA,MAAM,IAAI,UAAA,CAAW,CAAA,EAAG,IAAI,CAAA,aAAA,CAAe,CAAA;AAAA,EAC7C;AACF;AAEO,SAAS,cAAA,CAAe,OAAe,IAAA,EAAoB;AAChE,EAAA,kBAAA,CAAmB,OAAO,IAAI,CAAA;AAC9B,EAAA,IAAI,SAAS,CAAA,EAAG;AACd,IAAA,MAAM,IAAI,UAAA,CAAW,CAAA,EAAG,IAAI,CAAA,YAAA,CAAc,CAAA;AAAA,EAC5C;AACF;;;ACNO,SAAS,KAAK,MAAA,EAA4B;AAC/C,EAAA,MAAM,EAAE,UAAA,EAAY,QAAA,EAAU,KAAA,EAAM,GAAI,MAAA;AACxC,EAAA,cAAA,CAAe,YAAY,YAAY,CAAA;AACvC,EAAA,cAAA,CAAe,OAAO,OAAO,CAAA;AAC7B,EAAA,IAAI,QAAA,IAAY,GAAG,OAAO,EAAA;AAC1B,EAAA,OAAA,CAAQ,QAAA,GAAW,UAAA,MAAgB,CAAA,GAAI,KAAA,CAAA,GAAS,CAAA;AAClD;;;ACLO,SAAS,SAAS,MAAA,EAAgC;AACvD,EAAA,MAAM,EAAE,SAAA,EAAW,IAAA,EAAAA,KAAAA,EAAM,YAAA,EAAc,OAAM,GAAI,MAAA;AACjD,EAAA,iBAAA,CAAkB,WAAW,WAAW,CAAA;AACxC,EAAA,cAAA,CAAe,cAAc,cAAc,CAAA;AAC3C,EAAA,iBAAA,CAAkB,OAAO,OAAO,CAAA;AAEhC,EAAA,IAAIA,KAAAA,KAAS,CAAA,IAAK,KAAA,KAAU,CAAA,EAAG,OAAO,SAAA;AAEtC,EAAA,MAAM,CAAA,GAAI,YAAA;AACV,EAAA,MAAM,CAAA,GAAI,KAAA;AACV,EAAA,OAAO,SAAA,GAAA,CAAa,CAAA,GAAIA,KAAAA,GAAO,CAAA,MAAO,CAAA,GAAI,CAAA,CAAA;AAC5C;;;ACbO,SAAS,oBAAoB,MAAA,EAA2C;AAC7E,EAAA,MAAM,EAAE,WAAA,EAAa,YAAA,EAAa,GAAI,MAAA;AACtC,EAAA,kBAAA,CAAmB,aAAa,aAAa,CAAA;AAC7C,EAAA,cAAA,CAAe,cAAc,cAAc,CAAA;AAE3C,EAAA,MAAM,IAAI,WAAA,GAAc,YAAA;AACxB,EAAA,OAAA,CAAQ,CAAA,GAAI,MAAM,YAAA,GAAe,CAAA;AACnC;;;ACNO,SAAS,YAAY,MAAA,EAAmC;AAC7D,EAAA,MAAM,EAAE,YAAA,EAAAC,aAAAA,EAAc,MAAAD,KAAAA,EAAM,YAAA,EAAc,OAAM,GAAI,MAAA;AACpD,EAAA,iBAAA,CAAkBC,eAAc,cAAc,CAAA;AAC9C,EAAA,cAAA,CAAe,cAAc,cAAc,CAAA;AAC3C,EAAA,iBAAA,CAAkB,OAAO,OAAO,CAAA;AAEhC,EAAA,IAAID,KAAAA,KAAS,CAAA,IAAK,KAAA,KAAU,CAAA,EAAG,OAAOC,aAAAA;AAEtC,EAAA,MAAM,CAAA,GAAI,YAAA;AACV,EAAA,MAAM,CAAA,GAAI,KAAA;AACV,EAAA,OAAOA,aAAAA,GAAAA,CAAgB,CAAA,GAAID,KAAAA,GAAO,CAAA,MAAO,CAAA,GAAI,CAAA,CAAA;AAC/C;;;ACXO,SAAS,wBAAwB,MAAA,EAA+C;AACrF,EAAA,MAAM,EAAE,MAAA,EAAQ,mBAAA,EAAqB,KAAA,EAAO,WAAU,GAAI,MAAA;AAC1D,EAAA,kBAAA,CAAmB,QAAQ,QAAQ,CAAA;AACnC,EAAA,kBAAA,CAAmB,qBAAqB,qBAAqB,CAAA;AAC7D,EAAA,iBAAA,CAAkB,OAAO,OAAO,CAAA;AAChC,EAAA,MAAM,MAAA,GAAA,CAAU,IAAI,mBAAA,KAAwB,KAAA;AAC5C,EAAA,OAAO,SAAA,KAAc,QAAA,GAAW,MAAA,GAAS,MAAA,GAAS,MAAA,GAAS,MAAA;AAC7D;;;ACIO,SAAS,iBAAiB,MAAA,EAAwD;AACvF,EAAA,MAAM;AAAA,IACJ,OAAA;AAAA,IACA,qBAAA,GAAwB,CAAA;AAAA,IACxB,IAAA,EAAAA,KAAAA;AAAA,IACA,YAAA;AAAA,IACA,KAAA;AAAA,IACA,kBAAA,GAAqB;AAAA,GACvB,GAAI,MAAA;AAEJ,EAAA,iBAAA,CAAkB,SAAS,SAAS,CAAA;AACpC,EAAA,iBAAA,CAAkB,uBAAuB,uBAAuB,CAAA;AAChE,EAAA,cAAA,CAAe,cAAc,cAAc,CAAA;AAC3C,EAAA,iBAAA,CAAkB,OAAO,OAAO,CAAA;AAEhC,EAAA,MAAM,OAAA,GAAU,IAAA,CAAK,KAAA,CAAM,YAAA,GAAe,KAAK,CAAA;AAC/C,EAAA,IAAI,YAAY,CAAA,EAAG;AACjB,IAAA,OAAO;AAAA,MACL,WAAA,EAAa,OAAA;AAAA,MACb,kBAAA,EAAoB,CAAA;AAAA,MACpB,aAAA,EAAe;AAAA,KACjB;AAAA,EACF;AAEA,EAAA,MAAM,IAAIA,KAAAA,GAAO,YAAA;AAGjB,EAAA,MAAM,YAAYA,KAAAA,KAAS,CAAA,GAAI,OAAA,GAAU,OAAA,GAAA,CAAW,IAAI,CAAA,KAAM,OAAA;AAG9D,EAAA,IAAI,SAAA,GAAY,CAAA;AAChB,EAAA,IAAI,0BAA0B,CAAA,EAAG;AAC/B,IAAA,IAAIA,UAAS,CAAA,EAAG;AACd,MAAA,SAAA,GAAY,qBAAA,GAAwB,OAAA;AAAA,IACtC,CAAA,MAAO;AACL,MAAA,MAAM,QAAA,GAAW,qBAAA,IAAA,CAAA,CAA2B,CAAA,GAAI,CAAA,KAAM,UAAU,CAAA,IAAK,CAAA,CAAA;AACrE,MAAA,SAAA,GAAY,kBAAA,KAAuB,OAAA,GAAU,QAAA,IAAY,CAAA,GAAI,CAAA,CAAA,GAAK,QAAA;AAAA,IACpE;AAAA,EACF;AAEA,EAAA,MAAME,eAAc,SAAA,GAAY,SAAA;AAChC,EAAA,MAAM,qBAAqB,qBAAA,GAAwB,OAAA;AACnD,EAAA,MAAM,aAAA,GAAgBA,eAAc,OAAA,GAAU,kBAAA;AAE9C,EAAA,OAAO,EAAE,WAAA,EAAAA,YAAAA,EAAa,kBAAA,EAAoB,aAAA,EAAc;AAC1D;;;AC1DO,SAAS,cAAc,MAAA,EAAiD;AAC7E,EAAA,MAAM;AAAA,IACJ,YAAA;AAAA,IACA,EAAA;AAAA,IACA,UAAA;AAAA,IACA,SAAA,GAAY,KAAA;AAAA,IACZ,aAAA,GAAgB,GAAA;AAAA,IAChB,MAAM,MAAA,CAAO,iBAAA;AAAA,IACb,MAAM,MAAA,CAAO;AAAA,GACf,GAAI,MAAA;AAEJ,EAAA,IAAI,CAAA,GAAI,YAAA;AACR,EAAA,KAAA,IAAS,CAAA,GAAI,CAAA,EAAG,CAAA,GAAI,aAAA,EAAe,CAAA,EAAA,EAAK;AACtC,IAAA,MAAM,KAAA,GAAQ,GAAG,CAAC,CAAA;AAClB,IAAA,IAAI,CAAC,MAAA,CAAO,QAAA,CAAS,KAAK,GAAG,OAAO,MAAA;AACpC,IAAA,IAAI,IAAA,CAAK,GAAA,CAAI,KAAK,CAAA,IAAK,WAAW,OAAO,CAAA;AAEzC,IAAA,MAAM,KAAA,GAAQ,WAAW,CAAC,CAAA;AAC1B,IAAA,IAAI,CAAC,MAAA,CAAO,QAAA,CAAS,KAAK,CAAA,IAAK,KAAK,GAAA,CAAI,KAAK,CAAA,GAAI,KAAA,EAAO,OAAO,MAAA;AAE/D,IAAA,CAAA,IAAK,KAAA,GAAQ,KAAA;AACb,IAAA,IAAI,CAAA,GAAI,KAAK,CAAA,GAAI,GAAA;AACjB,IAAA,IAAI,CAAA,GAAI,KAAK,CAAA,GAAI,GAAA;AAAA,EACnB;AAEA,EAAA,OAAO,MAAA;AACT;AAUO,SAAS,UAAU,MAAA,EAA6C;AACrE,EAAA,MAAM,EAAE,IAAI,KAAA,EAAO,KAAA,EAAO,YAAY,KAAA,EAAO,aAAA,GAAgB,KAAI,GAAI,MAAA;AACrE,EAAA,IAAI,CAAA,GAAI,KAAA;AACR,EAAA,IAAI,CAAA,GAAI,KAAA;AACR,EAAA,IAAI,EAAA,GAAK,GAAG,CAAC,CAAA;AACb,EAAA,IAAI,EAAA,GAAK,GAAG,CAAC,CAAA;AAEb,EAAA,IAAI,CAAC,MAAA,CAAO,QAAA,CAAS,EAAE,CAAA,IAAK,CAAC,MAAA,CAAO,QAAA,CAAS,EAAE,CAAA,IAAK,EAAA,GAAK,EAAA,GAAK,GAAG,OAAO,MAAA;AACxE,EAAA,IAAI,IAAA,CAAK,GAAA,CAAI,EAAE,CAAA,IAAK,WAAW,OAAO,CAAA;AACtC,EAAA,IAAI,IAAA,CAAK,GAAA,CAAI,EAAE,CAAA,IAAK,WAAW,OAAO,CAAA;AAEtC,EAAA,KAAA,IAAS,CAAA,GAAI,CAAA,EAAG,CAAA,GAAI,aAAA,EAAe,CAAA,EAAA,EAAK;AACtC,IAAA,MAAM,CAAA,GAAA,CAAK,IAAI,CAAA,IAAK,CAAA;AACpB,IAAA,MAAM,EAAA,GAAK,GAAG,CAAC,CAAA;AACf,IAAA,IAAI,CAAC,MAAA,CAAO,QAAA,CAAS,EAAE,GAAG,OAAO,MAAA;AACjC,IAAA,IAAI,IAAA,CAAK,GAAA,CAAI,EAAE,CAAA,IAAK,SAAA,IAAa,IAAA,CAAK,GAAA,CAAI,CAAA,GAAI,CAAC,CAAA,IAAK,SAAA,EAAW,OAAO,CAAA;AAEtE,IAAA,IAAI,EAAA,GAAK,KAAK,CAAA,EAAG;AACf,MAAA,CAAA,GAAI,CAAA;AACJ,MAAA,EAAA,GAAK,EAAA;AAAA,IACP,CAAA,MAAO;AACL,MAAA,CAAA,GAAI,CAAA;AACJ,MAAA,EAAA,GAAK,EAAA;AAAA,IACP;AAAA,EACF;AAEA,EAAA,OAAA,CAAQ,IAAI,CAAA,IAAK,CAAA;AACnB;;;AC9DA,SAAS,KAAA,CAAMF,OAAc,SAAA,EAA6B;AACxD,EAAA,IAAI,GAAA,GAAM,CAAA;AACV,EAAA,KAAA,IAAS,CAAA,GAAI,CAAA,EAAG,CAAA,GAAI,SAAA,CAAU,QAAQ,CAAA,EAAA,EAAK;AACzC,IAAA,MAAM,EAAA,GAAK,UAAU,CAAC,CAAA;AACtB,IAAA,IAAI,EAAA,KAAO,MAAA,EAAW,GAAA,IAAO,EAAA,GAAA,CAAM,IAAIA,KAAAA,KAAS,CAAA;AAAA,EAClD;AACA,EAAA,OAAO,GAAA;AACT;AAEA,SAAS,eAAA,CAAgBA,OAAc,SAAA,EAA6B;AAClE,EAAA,IAAI,GAAA,GAAM,CAAA;AACV,EAAA,KAAA,IAAS,CAAA,GAAI,CAAA,EAAG,CAAA,GAAI,SAAA,CAAU,QAAQ,CAAA,EAAA,EAAK;AACzC,IAAA,MAAM,EAAA,GAAK,UAAU,CAAC,CAAA;AACtB,IAAA,IAAI,OAAO,MAAA,EAAW,GAAA,IAAQ,IAAI,EAAA,GAAA,CAAO,CAAA,GAAIA,WAAU,CAAA,GAAI,CAAA,CAAA;AAAA,EAC7D;AACA,EAAA,OAAO,GAAA;AACT;AAEA,SAAS,uBAAuB,SAAA,EAA8B;AAC5D,EAAA,IAAI,WAAA,GAAc,KAAA;AAClB,EAAA,IAAI,WAAA,GAAc,KAAA;AAClB,EAAA,KAAA,MAAW,MAAM,SAAA,EAAW;AAC1B,IAAA,IAAI,EAAA,GAAK,GAAG,WAAA,GAAc,IAAA;AAC1B,IAAA,IAAI,EAAA,GAAK,GAAG,WAAA,GAAc,IAAA;AAC1B,IAAA,IAAI,WAAA,IAAe,aAAa,OAAO,IAAA;AAAA,EACzC;AACA,EAAA,OAAO,KAAA;AACT;AAEA,SAAS,WAAA,CACP,EAAA,EACA,UAAA,EACA,UAAA,EAC8C;AAC9C,EAAA,MAAM,IAAA,GAAO,CACX,KAAA,EACA,GAAA,EACA,WAAW,GAAA,KACsC;AACjD,IAAA,IAAI,KAAA;AACJ,IAAA,IAAI,SAAA;AACJ,IAAA,KAAA,IAAS,CAAA,GAAI,CAAA,EAAG,CAAA,IAAK,QAAA,EAAU,CAAA,EAAA,EAAK;AAClC,MAAA,MAAM,CAAA,GAAI,KAAA,GAAA,CAAU,GAAA,GAAM,KAAA,IAAS,CAAA,GAAK,QAAA;AACxC,MAAA,MAAM,KAAA,GAAQ,GAAG,CAAC,CAAA;AAClB,MAAA,IAAI,CAAC,MAAA,CAAO,QAAA,CAAS,KAAK,CAAA,EAAG;AAC7B,MAAA,IAAI,UAAU,CAAA,EAAG,OAAO,EAAE,KAAA,EAAO,CAAA,EAAG,OAAO,CAAA,EAAE;AAC7C,MAAA,IAAI,UAAU,MAAA,IAAa,SAAA,KAAc,MAAA,IAAa,SAAA,GAAY,QAAQ,CAAA,EAAG;AAC3E,QAAA,OAAO,EAAE,KAAA,EAAO,KAAA,EAAO,KAAA,EAAO,CAAA,EAAE;AAAA,MAClC;AACA,MAAA,KAAA,GAAQ,CAAA;AACR,MAAA,SAAA,GAAY,KAAA;AAAA,IACd;AACA,IAAA,OAAO,MAAA;AAAA,EACT,CAAA;AAEA,EAAA,IAAI,KAAA,GAAQ,UAAA;AACZ,EAAA,IAAI,KAAA,GAAQ,UAAA;AACZ,EAAA,KAAA,IAAS,CAAA,GAAI,CAAA,EAAG,CAAA,GAAI,EAAA,EAAI,CAAA,EAAA,EAAK;AAC3B,IAAA,MAAM,OAAA,GAAU,IAAA,CAAK,KAAA,EAAO,KAAK,CAAA;AACjC,IAAA,IAAI,OAAA,KAAY,QAAW,OAAO,OAAA;AAClC,IAAA,KAAA,GAAQ,IAAA,CAAK,GAAA,CAAI,YAAA,EAAA,CAAe,KAAA,GAAQ,KAAK,CAAC,CAAA;AAC9C,IAAA,KAAA,GAAQ,QAAQ,CAAA,GAAI,CAAA;AAAA,EACtB;AAEA,EAAA,OAAO,IAAA,CAAK,KAAA,EAAO,KAAA,EAAO,GAAG,CAAA;AAC/B;AAEO,SAAS,IAAI,MAAA,EAA2B;AAC7C,EAAA,MAAM;AAAA,IACJ,SAAA;AAAA,IACA,KAAA,GAAQ,GAAA;AAAA,IACR,aAAA,GAAgB,GAAA;AAAA,IAChB,UAAA,GAAa,KAAA;AAAA,IACb,UAAA,GAAa;AAAA,GACf,GAAI,MAAA;AACJ,EAAA,IAAI,SAAA,CAAU,WAAW,CAAA,EAAG;AAC1B,IAAA,MAAM,IAAI,WAAW,2CAA2C,CAAA;AAAA,EAClE;AACA,EAAA,kBAAA,CAAmB,OAAO,OAAO,CAAA;AACjC,EAAA,kBAAA,CAAmB,eAAe,eAAe,CAAA;AACjD,EAAA,kBAAA,CAAmB,YAAY,YAAY,CAAA;AAC3C,EAAA,kBAAA,CAAmB,YAAY,YAAY,CAAA;AAC3C,EAAA,IAAI,iBAAiB,CAAA,IAAK,CAAC,MAAA,CAAO,SAAA,CAAU,aAAa,CAAA,EAAG;AAC1D,IAAA,MAAM,IAAI,WAAW,0CAA0C,CAAA;AAAA,EACjE;AACA,EAAA,IAAI,cAAc,EAAA,EAAI;AACpB,IAAA,MAAM,IAAI,WAAW,yBAAyB,CAAA;AAAA,EAChD;AACA,EAAA,IAAI,cAAc,UAAA,EAAY;AAC5B,IAAA,MAAM,IAAI,WAAW,4CAA4C,CAAA;AAAA,EACnE;AAEA,EAAA,KAAA,MAAW,EAAA,IAAM,SAAA,EAAW,kBAAA,CAAmB,EAAA,EAAI,aAAa,CAAA;AAChE,EAAA,IAAI,CAAC,sBAAA,CAAuB,SAAS,CAAA,EAAG;AACtC,IAAA,MAAM,IAAI,WAAW,qEAAqE,CAAA;AAAA,EAC5F;AAEA,EAAA,MAAM,EAAA,GAAK,CAACA,KAAAA,KAAiB,KAAA,CAAMA,OAAM,SAAS,CAAA;AAClD,EAAA,MAAM,UAAA,GAAa,CAACA,KAAAA,KAAiB,eAAA,CAAgBA,OAAM,SAAS,CAAA;AAEpE,EAAA,MAAM,SAAS,aAAA,CAAc;AAAA,IAC3B,YAAA,EAAc,KAAA;AAAA,IACd,EAAA;AAAA,IACA,UAAA;AAAA,IACA,SAAA,EAAW,KAAA;AAAA,IACX,aAAA;AAAA,IACA,GAAA,EAAK,UAAA;AAAA,IACL,GAAA,EAAK;AAAA,GACN,CAAA;AACD,EAAA,IAAI,MAAA,KAAW,QAAW,OAAO,MAAA;AAEjC,EAAA,MAAM,OAAA,GAAU,WAAA,CAAY,EAAA,EAAI,UAAA,EAAY,UAAU,CAAA;AACtD,EAAA,IAAI,YAAY,MAAA,EAAW;AACzB,IAAA,MAAM,IAAI,WAAW,2CAA2C,CAAA;AAAA,EAClE;AACA,EAAA,IAAI,OAAA,CAAQ,KAAA,KAAU,OAAA,CAAQ,KAAA,SAAc,OAAA,CAAQ,KAAA;AAEpD,EAAA,MAAM,WAAW,SAAA,CAAU;AAAA,IACzB,EAAA;AAAA,IACA,OAAO,OAAA,CAAQ,KAAA;AAAA,IACf,OAAO,OAAA,CAAQ,KAAA;AAAA,IACf,SAAA,EAAW,KAAA;AAAA,IACX,eAAe,aAAA,GAAgB;AAAA,GAChC,CAAA;AACD,EAAA,IAAI,QAAA,KAAa,QAAW,OAAO,QAAA;AAEnC,EAAA,MAAM,IAAI,WAAW,sBAAsB,CAAA;AAC7C;;;AC/HO,SAAS,IAAI,MAAA,EAA2B;AAC7C,EAAA,MAAM,EAAE,IAAA,EAAAA,KAAAA,EAAM,SAAA,EAAU,GAAI,MAAA;AAC5B,EAAA,kBAAA,CAAmBA,OAAM,MAAM,CAAA;AAC/B,EAAA,IAAIA,KAAAA,IAAQ,EAAA,EAAI,MAAM,IAAI,WAAW,mBAAmB,CAAA;AACxD,EAAA,IAAI,SAAA,CAAU,MAAA,KAAW,CAAA,EAAG,OAAO,CAAA;AAEnC,EAAA,IAAI,GAAA,GAAM,CAAA;AACV,EAAA,KAAA,IAAS,CAAA,GAAI,CAAA,EAAG,CAAA,GAAI,SAAA,CAAU,QAAQ,CAAA,EAAA,EAAK;AACzC,IAAA,MAAM,EAAA,GAAK,UAAU,CAAC,CAAA;AACtB,IAAA,IAAI,OAAO,MAAA,EAAW;AACtB,IAAA,kBAAA,CAAmB,EAAA,EAAI,CAAA,UAAA,EAAa,CAAC,CAAA,CAAA,CAAG,CAAA;AACxC,IAAA,GAAA,IAAO,EAAA,GAAA,CAAM,IAAIA,KAAAA,KAAS,CAAA;AAAA,EAC5B;AACA,EAAA,OAAO,GAAA;AACT;;;ACXO,SAAS,wBAAwB,MAAA,EAA+C;AACrF,EAAA,MAAM,EAAE,YAAA,EAAAC,aAAAA,EAAc,eAAe,OAAA,EAAS,MAAA,GAAS,OAAM,GAAI,MAAA;AACjE,EAAA,iBAAA,CAAkBA,eAAc,cAAc,CAAA;AAC9C,EAAA,iBAAA,CAAkB,SAAS,SAAS,CAAA;AAEpC,EAAA,IAAIA,aAAAA,KAAiB,CAAA,IAAK,OAAA,KAAY,CAAA,EAAG,OAAO,CAAA;AAChD,EAAA,IAAI,kBAAkB,CAAA,EAAG;AACvB,IAAA,MAAME,OAAMF,aAAAA,GAAe,OAAA;AAC3B,IAAA,OAAO,MAAA,KAAW,OAAA,GAAUE,IAAAA,IAAO,CAAA,GAAI,aAAA,CAAA,GAAiBA,IAAAA;AAAA,EAC1D;AACA,EAAA,IAAIA,OAAO,aAAA,GAAgBF,aAAAA,IAAiB,CAAA,GAAA,CAAK,CAAA,GAAI,kBAAkB,CAAC,OAAA,CAAA;AACxE,EAAA,IAAI,MAAA,KAAW,OAAA,EAASE,IAAAA,IAAO,CAAA,GAAI,aAAA;AACnC,EAAA,OAAOA,IAAAA;AACT;;;ACXO,SAAS,mBAAmB,MAAA,EAA0C;AAC3E,EAAA,MAAM;AAAA,IACJ,SAAA;AAAA,IACA,iBAAA;AAAA,IACA,IAAA,EAAAH,KAAAA;AAAA,IACA,YAAA;AAAA,IACA,qBAAA,GAAwB,CAAA;AAAA,IACxB,kBAAA,GAAqB,KAAA;AAAA,IACrB,UAAA,GAAa;AAAA,GACf,GAAI,MAAA;AAEJ,EAAA,iBAAA,CAAkB,WAAW,WAAW,CAAA;AACxC,EAAA,iBAAA,CAAkB,mBAAmB,mBAAmB,CAAA;AACxD,EAAA,kBAAA,CAAmBA,OAAM,MAAM,CAAA;AAC/B,EAAA,cAAA,CAAe,cAAc,cAAc,CAAA;AAC3C,EAAA,iBAAA,CAAkB,uBAAuB,uBAAuB,CAAA;AAChE,EAAA,cAAA,CAAe,YAAY,YAAY,CAAA;AAEvC,EAAA,IAAI,iBAAA,IAAqB,WAAW,OAAO,CAAA;AAE3C,EAAA,MAAM,IAAIA,KAAAA,GAAO,YAAA;AACjB,EAAA,IAAI,KAAK,EAAA,EAAI;AACX,IAAA,MAAM,IAAI,WAAW,kCAAkC,CAAA;AAAA,EACzD;AAEA,EAAA,IAAI,0BAA0B,CAAA,EAAG;AAC/B,IAAA,IAAI,SAAA,KAAc,CAAA,EAAG,OAAO,MAAA,CAAO,iBAAA;AACnC,IAAA,IAAIA,UAAS,CAAA,EAAG,OAAO,iBAAA,IAAqB,SAAA,GAAY,IAAI,MAAA,CAAO,iBAAA;AACnE,IAAA,IAAI,CAAA,GAAI,CAAA,EAAG,OAAO,MAAA,CAAO,iBAAA;AACzB,IAAA,MAAM,CAAA,GAAI,KAAK,GAAA,CAAI,iBAAA,GAAoB,SAAS,CAAA,GAAI,IAAA,CAAK,GAAA,CAAI,CAAA,GAAI,CAAC,CAAA;AAClE,IAAA,OAAO,MAAA,CAAO,QAAA,CAAS,CAAC,CAAA,IAAK,CAAA,IAAK,IAAI,IAAA,CAAK,IAAA,CAAK,CAAC,CAAA,GAAI,MAAA,CAAO,iBAAA;AAAA,EAC9D;AAEA,EAAA,IAAIA,UAAS,CAAA,EAAG;AACd,IAAA,MAAM,SAAS,iBAAA,GAAoB,SAAA;AACnC,IAAA,IAAI,MAAA,IAAU,GAAG,OAAO,CAAA;AACxB,IAAA,OAAO,IAAA,CAAK,IAAA,CAAK,MAAA,GAAS,qBAAqB,CAAA;AAAA,EACjD;AAGA,EAAA,IAAII,GAAAA,GAAK,SAAA;AACT,EAAA,IAAI,OAAA,GAAU,CAAA;AACd,EAAA,OAAOA,GAAAA,GAAK,iBAAA,IAAqB,OAAA,GAAU,UAAA,EAAY;AACrD,IAAA,IAAI,kBAAA,KAAuB,OAAA,EAASA,GAAAA,IAAM,qBAAA;AAC1C,IAAAA,MAAKA,GAAAA,IAAM,CAAA,GAAI,CAAA,CAAA,IAAM,kBAAA,KAAuB,QAAQ,qBAAA,GAAwB,CAAA,CAAA;AAC5E,IAAA,OAAA,EAAA;AAAA,EACF;AACA,EAAA,IAAIA,GAAAA,IAAM,mBAAmB,OAAO,OAAA;AACpC,EAAA,MAAM,IAAI,WAAW,4CAA4C,CAAA;AACnE;;;ACrDO,SAAS,aAAa,MAAA,EAAoC;AAC/D,EAAA,MAAM,EAAE,WAAA,EAAaA,GAAAA,EAAI,MAAAJ,KAAAA,EAAM,YAAA,EAAc,OAAM,GAAI,MAAA;AACvD,EAAA,iBAAA,CAAkBI,KAAI,aAAa,CAAA;AACnC,EAAA,cAAA,CAAe,cAAc,cAAc,CAAA;AAC3C,EAAA,iBAAA,CAAkB,OAAO,OAAO,CAAA;AAEhC,EAAA,IAAIJ,KAAAA,KAAS,CAAA,IAAK,KAAA,KAAU,CAAA,EAAG,OAAOI,GAAAA;AAEtC,EAAA,MAAM,CAAA,GAAI,YAAA;AACV,EAAA,MAAM,CAAA,GAAI,KAAA;AACV,EAAA,OAAOA,GAAAA,GAAAA,CAAM,CAAA,GAAIJ,KAAAA,GAAO,CAAA,MAAO,CAAA,GAAI,CAAA,CAAA;AACrC;;;ACXO,SAAS,sBAAsB,MAAA,EAA6C;AACjF,EAAA,MAAM,EAAE,gBAAA,EAAkB,aAAA,EAAe,OAAA,EAAS,MAAA,GAAS,OAAM,GAAI,MAAA;AACrE,EAAA,iBAAA,CAAkB,kBAAkB,kBAAkB,CAAA;AACtD,EAAA,iBAAA,CAAkB,SAAS,SAAS,CAAA;AAEpC,EAAA,IAAI,OAAA,KAAY,GAAG,OAAO,CAAA;AAC1B,EAAA,IAAI,kBAAkB,CAAA,EAAG;AACvB,IAAA,MAAMK,MAAK,gBAAA,GAAmB,OAAA;AAC9B,IAAA,OAAO,MAAA,KAAW,OAAA,GAAUA,GAAAA,IAAM,CAAA,GAAI,aAAA,CAAA,GAAiBA,GAAAA;AAAA,EACzD;AACA,EAAA,MAAMA,MAAM,gBAAA,IAAoB,CAAA,GAAA,CAAK,CAAA,GAAI,aAAA,KAAkB,CAAC,OAAA,CAAA,GAAY,aAAA;AACxE,EAAA,OAAO,MAAA,KAAW,OAAA,GAAUA,GAAAA,IAAM,CAAA,GAAI,aAAA,CAAA,GAAiBA,GAAAA;AACzD;;;ACLO,SAAS,gBAAgB,MAAA,EAAuC;AACrE,EAAA,MAAM;AAAA,IACJ,SAAA;AAAA,IACA,iBAAA;AAAA,IACA,OAAA;AAAA,IACA,qBAAA,GAAwB,CAAA;AAAA,IACxB,kBAAA,GAAqB,KAAA;AAAA,IACrB,UAAA,GAAa,KAAA;AAAA,IACb,UAAA,GAAa,EAAA;AAAA,IACb,aAAA,GAAgB,GAAA;AAAA,IAChB,SAAA,GAAY;AAAA,GACd,GAAI,MAAA;AAEJ,EAAA,iBAAA,CAAkB,WAAW,WAAW,CAAA;AACxC,EAAA,iBAAA,CAAkB,mBAAmB,mBAAmB,CAAA;AACxD,EAAA,cAAA,CAAe,SAAS,SAAS,CAAA;AACjC,EAAA,iBAAA,CAAkB,uBAAuB,uBAAuB,CAAA;AAChE,EAAA,kBAAA,CAAmB,YAAY,YAAY,CAAA;AAC3C,EAAA,kBAAA,CAAmB,YAAY,YAAY,CAAA;AAC3C,EAAA,kBAAA,CAAmB,eAAe,eAAe,CAAA;AACjD,EAAA,kBAAA,CAAmB,WAAW,WAAW,CAAA;AACzC,EAAA,IAAI,UAAA,IAAc,EAAA,EAAI,MAAM,IAAI,WAAW,yBAAyB,CAAA;AACpE,EAAA,IAAI,UAAA,IAAc,UAAA,EAAY,MAAM,IAAI,WAAW,4CAA4C,CAAA;AAC/F,EAAA,IAAI,CAAC,MAAA,CAAO,SAAA,CAAU,aAAa,CAAA,IAAK,iBAAiB,CAAA,EAAG;AAC1D,IAAA,MAAM,IAAI,WAAW,0CAA0C,CAAA;AAAA,EACjE;AACA,EAAA,IAAI,SAAA,IAAa,CAAA,EAAG,MAAM,IAAI,WAAW,uBAAuB,CAAA;AAEhE,EAAA,IAAI,OAAA,KAAY,GAAG,OAAO,CAAA;AAC1B,EAAA,IAAI,iBAAA,IAAqB,SAAA,IAAa,qBAAA,KAA0B,CAAA,EAAG,OAAO,CAAA;AAE1E,EAAA,IAAI,0BAA0B,CAAA,EAAG;AAC/B,IAAA,IAAI,iBAAA,IAAqB,WAAW,OAAO,CAAA;AAC3C,IAAA,IAAI,cAAc,CAAA,EAAG;AACnB,MAAA,MAAM,IAAI,UAAA;AAAA,QACR;AAAA,OACF;AAAA,IACF;AACA,IAAA,OAAA,CAAQ,iBAAA,GAAoB,SAAA,MAAe,CAAA,GAAI,OAAA,CAAA,GAAW,CAAA;AAAA,EAC5D;AAEA,EAAA,MAAM,SAAA,GAAY,kBAAA,KAAuB,OAAA,GAAU,CAAA,GAAI,CAAA;AACvD,EAAA,MAAM,EAAA,GAAK,CAAC,CAAA,KAAc;AACxB,IAAA,MAAM,WAAW,CAAA,GAAI,CAAA;AACrB,IAAA,MAAM,YAAY,QAAA,IAAY,OAAA;AAC9B,IAAA,MAAM,SAAS,SAAA,GAAY,SAAA;AAC3B,IAAA,MAAM,WAAA,GAAc,CAAA,KAAM,CAAA,GAAI,OAAA,GAAA,CAAW,YAAY,CAAA,IAAK,CAAA;AAC1D,IAAA,MAAM,SAAA,GAAY,qBAAA,GAAwB,WAAA,IAAe,CAAA,GAAI,SAAA,GAAY,CAAA,CAAA;AACzE,IAAA,OAAO,SAAS,SAAA,GAAY,iBAAA;AAAA,EAC9B,CAAA;AACA,EAAA,MAAM,UAAA,GAAa,CAAC,CAAA,KAAc;AAChC,IAAA,MAAM,KAAA,GAAQ,IAAA,CAAK,GAAA,CAAI,CAAC,CAAA,GAAI,OAAO,IAAA,CAAK,GAAA,CAAI,CAAC,CAAA,GAAI,IAAA,GAAO,IAAA;AACxD,IAAA,OAAA,CAAQ,EAAA,CAAG,IAAI,KAAK,CAAA,GAAI,GAAG,CAAA,GAAI,KAAK,MAAM,CAAA,GAAI,KAAA,CAAA;AAAA,EAChD,CAAA;AAEA,EAAA,MAAM,gBACH,iBAAA,IAAqB,SAAA,GAAY,qBAAA,GAAwB,OAAA,CAAA,MAAc,IAAI,OAAA,CAAA,GAAW,CAAA;AAEzF,EAAA,MAAM,SAAS,aAAA,CAAc;AAAA,IAC3B,YAAA,EAAc,OAAO,QAAA,CAAS,YAAY,IAAI,IAAA,CAAK,GAAA,CAAI,YAAA,EAAc,UAAU,CAAA,GAAI,IAAA;AAAA,IACnF,EAAA;AAAA,IACA,UAAA;AAAA,IACA,SAAA;AAAA,IACA,aAAA;AAAA,IACA,GAAA,EAAK,UAAA;AAAA,IACL,GAAA,EAAK;AAAA,GACN,CAAA;AACD,EAAA,IAAI,MAAA,KAAW,QAAW,OAAO,MAAA;AAEjC,EAAA,MAAM,OAAA,GAAUC,YAAAA,CAAY,EAAA,EAAI,UAAA,EAAY,UAAU,CAAA;AACtD,EAAA,IAAI,YAAY,MAAA,EAAW;AACzB,IAAA,MAAM,IAAI,WAAW,uDAAuD,CAAA;AAAA,EAC9E;AACA,EAAA,IAAI,OAAA,CAAQ,KAAA,KAAU,OAAA,CAAQ,KAAA,SAAc,OAAA,CAAQ,KAAA;AAEpD,EAAA,MAAM,WAAW,SAAA,CAAU;AAAA,IACzB,EAAA;AAAA,IACA,OAAO,OAAA,CAAQ,KAAA;AAAA,IACf,OAAO,OAAA,CAAQ,KAAA;AAAA,IACf,SAAA;AAAA,IACA,eAAe,aAAA,GAAgB;AAAA,GAChC,CAAA;AACD,EAAA,IAAI,QAAA,KAAa,QAAW,OAAO,QAAA;AACnC,EAAA,MAAM,IAAI,WAAW,kCAAkC,CAAA;AACzD;AAEA,SAASA,YAAAA,CACP,EAAA,EACA,UAAA,EACA,UAAA,EAC8C;AAC9C,EAAA,MAAM,IAAA,GAAO,CACX,KAAA,EACA,GAAA,EACA,WAAW,GAAA,KACsC;AACjD,IAAA,IAAI,KAAA;AACJ,IAAA,IAAI,SAAA;AACJ,IAAA,KAAA,IAAS,CAAA,GAAI,CAAA,EAAG,CAAA,IAAK,QAAA,EAAU,CAAA,EAAA,EAAK;AAClC,MAAA,MAAM,CAAA,GAAI,KAAA,GAAA,CAAU,GAAA,GAAM,KAAA,IAAS,CAAA,GAAK,QAAA;AACxC,MAAA,MAAM,KAAA,GAAQ,GAAG,CAAC,CAAA;AAClB,MAAA,IAAI,CAAC,MAAA,CAAO,QAAA,CAAS,KAAK,CAAA,EAAG;AAC7B,MAAA,IAAI,UAAU,CAAA,EAAG,OAAO,EAAE,KAAA,EAAO,CAAA,EAAG,OAAO,CAAA,EAAE;AAC7C,MAAA,IAAI,UAAU,MAAA,IAAa,SAAA,KAAc,MAAA,IAAa,SAAA,GAAY,QAAQ,CAAA,EAAG;AAC3E,QAAA,OAAO,EAAE,KAAA,EAAO,KAAA,EAAO,KAAA,EAAO,CAAA,EAAE;AAAA,MAClC;AACA,MAAA,KAAA,GAAQ,CAAA;AACR,MAAA,SAAA,GAAY,KAAA;AAAA,IACd;AACA,IAAA,OAAO,MAAA;AAAA,EACT,CAAA;AAEA,EAAA,IAAI,KAAA,GAAQ,UAAA;AACZ,EAAA,IAAI,KAAA,GAAQ,UAAA;AACZ,EAAA,KAAA,IAAS,CAAA,GAAI,CAAA,EAAG,CAAA,GAAI,EAAA,EAAI,CAAA,EAAA,EAAK;AAC3B,IAAA,MAAM,OAAA,GAAU,IAAA,CAAK,KAAA,EAAO,KAAK,CAAA;AACjC,IAAA,IAAI,OAAA,KAAY,QAAW,OAAO,OAAA;AAClC,IAAA,KAAA,GAAQ,IAAA,CAAK,GAAA,CAAI,YAAA,EAAA,CAAe,KAAA,GAAQ,KAAK,CAAC,CAAA;AAC9C,IAAA,KAAA,GAAQ,QAAQ,CAAA,GAAI,CAAA;AAAA,EACtB;AAEA,EAAA,OAAO,IAAA,CAAK,KAAA,EAAO,KAAA,EAAO,GAAG,CAAA;AAC/B;;;ACzIO,SAAS,WAAW,MAAA,EAAkC;AAC3D,EAAA,MAAM,EAAE,aAAA,EAAe,aAAA,EAAc,GAAI,MAAA;AACzC,EAAA,kBAAA,CAAmB,eAAe,eAAe,CAAA;AACjD,EAAA,kBAAA,CAAmB,eAAe,eAAe,CAAA;AACjD,EAAA,IAAI,aAAA,IAAiB,IAAI,OAAO,GAAA;AAChC,EAAA,OAAA,CAAQ,CAAA,GAAI,aAAA,KAAkB,CAAA,GAAI,aAAA,CAAA,GAAiB,CAAA;AACrD;;;ACEO,SAAS,SAAS,MAAA,EAAgC;AACvD,EAAA,MAAM,EAAE,IAAA,EAAAN,KAAAA,EAAM,QAAA,GAAW,IAAG,GAAI,MAAA;AAChC,EAAA,kBAAA,CAAmBA,OAAM,MAAM,CAAA;AAC/B,EAAA,cAAA,CAAeA,OAAM,MAAM,CAAA;AAC3B,EAAA,OAAO,WAAW,GAAA,GAAMA,KAAAA;AAC1B;;;ACZA,SAAS,YAAA,CAAa,OAAsB,IAAA,EAAoB;AAC9D,EAAA,IAAI,KAAA,KAAU,KAAA,IAAS,KAAA,KAAU,OAAA,EAAS;AACxC,IAAA,MAAM,IAAI,UAAA,CAAW,CAAA,EAAG,IAAI,CAAA,yBAAA,CAA2B,CAAA;AAAA,EACzD;AACF;AAEA,SAAS,gBAAA,CAAiB,eAAuB,MAAA,EAA+B;AAC9E,EAAA,OAAO,MAAA,KAAW,OAAA,GAAU,CAAA,GAAI,aAAA,GAAgB,CAAA;AAClD;AAEA,SAAS,wBAAA,CACP,aAAA,EACA,OAAA,EACA,OAAA,EACAC,eACA,MAAA,EACQ;AACR,EAAA,IAAI,+BAAA,CAAgC,aAAa,CAAA,EAAG;AAClD,IAAA,MAAM,IAAI,WAAW,4BAA4B,CAAA;AAAA,EACnD;AACA,EAAA,IAAI,aAAA,KAAkB,CAAA,EAAG,OAAO,EAAEA,gBAAe,OAAA,GAAU,OAAA,CAAA;AAE3D,EAAA,MAAM,MAAA,GAAA,CAAU,IAAI,aAAA,KAAkB,OAAA;AACtC,EAAA,IAAI,CAAC,OAAO,QAAA,CAAS,MAAM,KAAK,MAAA,IAAU,CAAA,SAAU,MAAA,CAAO,GAAA;AAC3D,EAAA,MAAM,YACJ,OAAA,IAAA,CAAY,MAAA,GAAS,KAAK,aAAA,CAAA,GAAiB,gBAAA,CAAiB,eAAe,MAAM,CAAA;AACnF,EAAA,OAAO,EAAEA,gBAAe,MAAA,GAAS,SAAA,CAAA;AACnC;AAaO,SAAS,GAAG,MAAA,EAA0B;AAC3C,EAAA,MAAM,EAAE,eAAe,OAAA,EAAS,OAAA,GAAU,GAAG,YAAA,EAAAA,aAAAA,EAAc,MAAA,GAAS,KAAA,EAAM,GAAI,MAAA;AAC9E,EAAA,kBAAA,CAAmB,eAAe,eAAe,CAAA;AACjD,EAAA,cAAA,CAAe,SAAS,SAAS,CAAA;AACjC,EAAA,kBAAA,CAAmB,SAAS,SAAS,CAAA;AACrC,EAAA,kBAAA,CAAmBA,eAAc,cAAc,CAAA;AAC/C,EAAA,YAAA,CAAa,QAAQ,QAAQ,CAAA;AAE7B,EAAA,MAAM,QAAQ,wBAAA,CAAyB,aAAA,EAAe,OAAA,EAAS,OAAA,EAASA,eAAc,MAAM,CAAA;AAC5F,EAAA,IAAI,CAAC,MAAA,CAAO,QAAA,CAAS,KAAK,CAAA,EAAG;AAC3B,IAAA,MAAM,IAAI,WAAW,wCAAwC,CAAA;AAAA,EAC/D;AACA,EAAA,OAAO,KAAA;AACT;AAaO,SAAS,GAAG,MAAA,EAA0B;AAC3C,EAAA,MAAM,EAAE,aAAA,EAAe,OAAA,EAAS,OAAA,GAAU,CAAA,EAAG,aAAAC,YAAAA,GAAc,CAAA,EAAG,MAAA,GAAS,KAAA,EAAM,GAAI,MAAA;AACjF,EAAA,kBAAA,CAAmB,eAAe,eAAe,CAAA;AACjD,EAAA,cAAA,CAAe,SAAS,SAAS,CAAA;AACjC,EAAA,kBAAA,CAAmB,SAAS,SAAS,CAAA;AACrC,EAAA,kBAAA,CAAmBA,cAAa,aAAa,CAAA;AAC7C,EAAA,YAAA,CAAa,QAAQ,QAAQ,CAAA;AAC7B,EAAA,IAAI,+BAAA,CAAgC,aAAa,CAAA,EAAG;AAClD,IAAA,MAAM,IAAI,WAAW,4BAA4B,CAAA;AAAA,EACnD;AAEA,EAAA,IAAI,aAAA,KAAkB,CAAA,EAAG,OAAO,EAAEA,eAAc,OAAA,GAAU,OAAA,CAAA;AAE1D,EAAA,MAAM,MAAA,GAAA,CAAU,IAAI,aAAA,KAAkB,OAAA;AACtC,EAAA,IAAI,CAAC,MAAA,CAAO,QAAA,CAAS,MAAM,CAAA,IAAK,UAAU,CAAA,EAAG;AAC3C,IAAA,MAAM,IAAI,WAAW,uDAAuD,CAAA;AAAA,EAC9E;AACA,EAAA,MAAM,SAAA,GACF,WAAW,CAAA,GAAI,CAAA,GAAI,UAAW,aAAA,GAAiB,gBAAA,CAAiB,eAAe,MAAM,CAAA;AACzF,EAAA,MAAM,KAAA,GAAQ,CAACA,YAAAA,GAAc,MAAA,GAAS,SAAA;AACtC,EAAA,IAAI,CAAC,MAAA,CAAO,QAAA,CAAS,KAAK,CAAA,EAAG;AAC3B,IAAA,MAAM,IAAI,WAAW,wCAAwC,CAAA;AAAA,EAC/D;AACA,EAAA,OAAO,KAAA;AACT;AAaO,SAAS,IAAI,MAAA,EAA2B;AAC7C,EAAA,MAAM,EAAE,aAAA,EAAe,OAAA,EAAS,YAAA,EAAAD,aAAAA,EAAc,aAAAC,YAAAA,GAAc,CAAA,EAAG,MAAA,GAAS,KAAA,EAAM,GAAI,MAAA;AAClF,EAAA,kBAAA,CAAmB,eAAe,eAAe,CAAA;AACjD,EAAA,cAAA,CAAe,SAAS,SAAS,CAAA;AACjC,EAAA,kBAAA,CAAmBD,eAAc,cAAc,CAAA;AAC/C,EAAA,kBAAA,CAAmBC,cAAa,aAAa,CAAA;AAC7C,EAAA,YAAA,CAAa,QAAQ,QAAQ,CAAA;AAC7B,EAAA,IAAI,+BAAA,CAAgC,aAAa,CAAA,EAAG;AAClD,IAAA,MAAM,IAAI,WAAW,4BAA4B,CAAA;AAAA,EACnD;AAEA,EAAA,IAAI,aAAA,KAAkB,CAAA,EAAG,OAAO,EAAED,gBAAeC,YAAAA,CAAAA,GAAe,OAAA;AAEhE,EAAA,MAAM,MAAA,GAAA,CAAU,IAAI,aAAA,KAAkB,OAAA;AACtC,EAAA,IAAI,CAAC,MAAA,CAAO,QAAA,CAAS,MAAM,CAAA,IAAK,UAAU,CAAA,EAAG;AAC3C,IAAA,MAAM,IAAI,WAAW,uDAAuD,CAAA;AAAA,EAC9E;AACA,EAAA,MAAM,SAAA,GAAY,EAAEA,YAAAA,GAAcD,aAAAA,GAAe,MAAA,CAAA,GAAU,aAAA;AAC3D,EAAA,MAAM,WAAA,GAAA,CAAe,MAAA,GAAS,CAAA,IAAK,gBAAA,CAAiB,eAAe,MAAM,CAAA;AACzE,EAAA,MAAM,QAAQ,SAAA,GAAY,WAAA;AAC1B,EAAA,IAAI,CAAC,MAAA,CAAO,QAAA,CAAS,KAAK,CAAA,EAAG;AAC3B,IAAA,MAAM,IAAI,WAAW,wCAAwC,CAAA;AAAA,EAC/D;AACA,EAAA,OAAO,KAAA;AACT;AAaO,SAAS,KAAK,MAAA,EAA4B;AAC/C,EAAA,MAAM,EAAE,aAAA,EAAe,OAAA,EAAS,YAAA,EAAAA,aAAAA,EAAc,aAAAC,YAAAA,GAAc,CAAA,EAAG,MAAA,GAAS,KAAA,EAAM,GAAI,MAAA;AAClF,EAAA,kBAAA,CAAmB,eAAe,eAAe,CAAA;AACjD,EAAA,kBAAA,CAAmB,SAAS,SAAS,CAAA;AACrC,EAAA,kBAAA,CAAmBD,eAAc,cAAc,CAAA;AAC/C,EAAA,kBAAA,CAAmBC,cAAa,aAAa,CAAA;AAC7C,EAAA,YAAA,CAAa,QAAQ,QAAQ,CAAA;AAC7B,EAAA,IAAI,+BAAA,CAAgC,aAAa,CAAA,EAAG;AAClD,IAAA,MAAM,IAAI,WAAW,4BAA4B,CAAA;AAAA,EACnD;AAEA,EAAA,IAAI,kBAAkB,CAAA,EAAG;AACvB,IAAA,MAAM,MAAA,GAAS,EAAED,aAAAA,GAAeC,YAAAA,CAAAA,GAAe,OAAA;AAC/C,IAAA,OAAO,OAAO,QAAA,CAAS,MAAM,KAAK,MAAA,IAAU,CAAA,GAAI,SAAS,MAAA,CAAO,GAAA;AAAA,EAClE;AAEA,EAAA,MAAM,eAAA,GAAkB,OAAA,GAAU,gBAAA,CAAiB,aAAA,EAAe,MAAM,CAAA;AACxE,EAAA,MAAM,SAAA,GAAY,kBAAkBA,YAAAA,GAAc,aAAA;AAClD,EAAA,MAAM,WAAA,GAAc,kBAAkBD,aAAAA,GAAe,aAAA;AACrD,EAAA,IAAI,SAAA,KAAc,CAAA,IAAK,WAAA,KAAgB,CAAA,SAAU,MAAA,CAAO,GAAA;AACxD,EAAA,MAAM,QAAQ,SAAA,GAAY,WAAA;AAC1B,EAAA,IAAI,KAAA,IAAS,CAAA,EAAG,OAAO,MAAA,CAAO,GAAA;AAE9B,EAAA,MAAM,OAAA,GAAU,KAAK,GAAA,CAAI,KAAK,IAAI,IAAA,CAAK,GAAA,CAAI,IAAI,aAAa,CAAA;AAC5D,EAAA,OAAO,MAAA,CAAO,QAAA,CAAS,OAAO,CAAA,GAAI,UAAU,MAAA,CAAO,GAAA;AACrD;AAkBO,SAAS,KAAK,MAAA,EAA4B;AAC/C,EAAA,MAAM;AAAA,IACJ,OAAA;AAAA,IACA,OAAA;AAAA,IACA,YAAA,EAAAA,aAAAA;AAAA,IACA,aAAAC,YAAAA,GAAc,CAAA;AAAA,IACd,MAAA,GAAS,KAAA;AAAA,IACT,KAAA,GAAQ,GAAA;AAAA,IACR,SAAA,GAAY,KAAA;AAAA,IACZ,aAAA,GAAgB,GAAA;AAAA,IAChB,UAAA,GAAa,YAAA;AAAA,IACb,UAAA,GAAa;AAAA,GACf,GAAI,MAAA;AACJ,EAAA,cAAA,CAAe,SAAS,SAAS,CAAA;AACjC,EAAA,kBAAA,CAAmB,SAAS,SAAS,CAAA;AACrC,EAAA,kBAAA,CAAmBD,eAAc,cAAc,CAAA;AAC/C,EAAA,kBAAA,CAAmBC,cAAa,aAAa,CAAA;AAC7C,EAAA,kBAAA,CAAmB,OAAO,OAAO,CAAA;AACjC,EAAA,kBAAA,CAAmB,eAAe,eAAe,CAAA;AACjD,EAAA,kBAAA,CAAmB,YAAY,YAAY,CAAA;AAC3C,EAAA,kBAAA,CAAmB,YAAY,YAAY,CAAA;AAC3C,EAAA,YAAA,CAAa,QAAQ,QAAQ,CAAA;AAC7B,EAAA,IAAI,+BAAA,CAAgC,UAAU,CAAA,EAAG;AAC/C,IAAA,MAAM,IAAI,WAAW,yBAAyB,CAAA;AAAA,EAChD;AACA,EAAA,IAAI,cAAc,UAAA,EAAY;AAC5B,IAAA,MAAM,IAAI,WAAW,4CAA4C,CAAA;AAAA,EACnE;AACA,EAAA,IAAI,CAAC,MAAA,CAAO,SAAA,CAAU,aAAa,CAAA,IAAK,iBAAiB,CAAA,EAAG;AAC1D,IAAA,MAAM,IAAI,WAAW,0CAA0C,CAAA;AAAA,EACjE;AAEA,EAAA,MAAM,EAAA,GAAK,CAAC,CAAA,KACV,wBAAA,CAAyB,GAAG,OAAA,EAAS,OAAA,EAASD,aAAAA,EAAc,MAAM,CAAA,GAAIC,YAAAA;AACxE,EAAA,MAAM,UAAA,GAAa,CAAC,CAAA,KAAc;AAChC,IAAA,MAAM,KAAA,GAAQ,IAAA,CAAK,GAAA,CAAI,CAAC,CAAA,GAAI,OAAO,IAAA,CAAK,GAAA,CAAI,CAAC,CAAA,GAAI,IAAA,GAAO,IAAA;AACxD,IAAA,OAAA,CAAQ,EAAA,CAAG,IAAI,KAAK,CAAA,GAAI,GAAG,CAAA,GAAI,KAAK,MAAM,CAAA,GAAI,KAAA,CAAA;AAAA,EAChD,CAAA;AAEA,EAAA,MAAM,SAAS,aAAA,CAAc;AAAA,IAC3B,YAAA,EAAc,KAAA;AAAA,IACd,EAAA;AAAA,IACA,UAAA;AAAA,IACA,SAAA;AAAA,IACA,aAAA;AAAA,IACA,GAAA,EAAK,UAAA;AAAA,IACL,GAAA,EAAK;AAAA,GACN,CAAA;AACD,EAAA,IAAI,MAAA,KAAW,QAAW,OAAO,MAAA;AAEjC,EAAA,MAAM,OAAA,GAAU,eAAA,CAAgB,EAAA,EAAI,UAAA,EAAY,UAAU,CAAA;AAC1D,EAAA,IAAI,YAAY,MAAA,EAAW;AACzB,IAAA,MAAM,IAAI,WAAW,4CAA4C,CAAA;AAAA,EACnE;AACA,EAAA,IAAI,OAAA,CAAQ,KAAA,KAAU,OAAA,CAAQ,KAAA,SAAc,OAAA,CAAQ,KAAA;AAEpD,EAAA,MAAM,WAAW,SAAA,CAAU;AAAA,IACzB,EAAA;AAAA,IACA,OAAO,OAAA,CAAQ,KAAA;AAAA,IACf,OAAO,OAAA,CAAQ,KAAA;AAAA,IACf,SAAA;AAAA,IACA,eAAe,aAAA,GAAgB;AAAA,GAChC,CAAA;AACD,EAAA,IAAI,QAAA,KAAa,QAAW,OAAO,QAAA;AAEnC,EAAA,MAAM,IAAI,WAAW,uBAAuB,CAAA;AAC9C;AAEA,SAAS,gCAAgC,aAAA,EAAgC;AACvE,EAAA,OAAO,aAAA,IAAiB,EAAA;AAC1B;AAEA,SAAS,eAAA,CACP,EAAA,EACA,UAAA,EACA,UAAA,EAC8C;AAC9C,EAAA,MAAM,IAAA,GAAO,CACX,KAAA,EACA,GAAA,EACA,WAAW,GAAA,KACsC;AACjD,IAAA,IAAI,KAAA;AACJ,IAAA,IAAI,SAAA;AACJ,IAAA,KAAA,IAAS,CAAA,GAAI,CAAA,EAAG,CAAA,IAAK,QAAA,EAAU,CAAA,EAAA,EAAK;AAClC,MAAA,MAAM,CAAA,GAAI,KAAA,GAAA,CAAU,GAAA,GAAM,KAAA,IAAS,CAAA,GAAK,QAAA;AACxC,MAAA,MAAM,KAAA,GAAQ,GAAG,CAAC,CAAA;AAClB,MAAA,IAAI,CAAC,MAAA,CAAO,QAAA,CAAS,KAAK,CAAA,EAAG;AAC7B,MAAA,IAAI,UAAU,CAAA,EAAG,OAAO,EAAE,KAAA,EAAO,CAAA,EAAG,OAAO,CAAA,EAAE;AAC7C,MAAA,IAAI,cAAc,MAAA,IAAa,KAAA,KAAU,MAAA,IAAa,SAAA,GAAY,QAAQ,CAAA,EAAG;AAC3E,QAAA,OAAO,EAAE,KAAA,EAAO,KAAA,EAAO,KAAA,EAAO,CAAA,EAAE;AAAA,MAClC;AACA,MAAA,KAAA,GAAQ,CAAA;AACR,MAAA,SAAA,GAAY,KAAA;AAAA,IACd;AACA,IAAA,OAAO,MAAA;AAAA,EACT,CAAA;AAEA,EAAA,IAAI,KAAA,GAAQ,UAAA;AACZ,EAAA,IAAI,KAAA,GAAQ,UAAA;AACZ,EAAA,KAAA,IAAS,CAAA,GAAI,CAAA,EAAG,CAAA,GAAI,EAAA,EAAI,CAAA,EAAA,EAAK;AAC3B,IAAA,MAAM,OAAA,GAAU,IAAA,CAAK,KAAA,EAAO,KAAK,CAAA;AACjC,IAAA,IAAI,OAAA,KAAY,QAAW,OAAO,OAAA;AAClC,IAAA,KAAA,GAAQ,IAAA,CAAK,GAAA,CAAI,YAAA,EAAA,CAAe,KAAA,GAAQ,KAAK,CAAC,CAAA;AAC9C,IAAA,KAAA,GAAQ,QAAQ,CAAA,GAAI,CAAA;AAAA,EACtB;AAEA,EAAA,OAAO,IAAA,CAAK,KAAA,EAAO,KAAA,EAAO,GAAG,CAAA;AAC/B;;;ACzRO,SAAS,YAAY,MAAA,EAAmC;AAC7D,EAAA,MAAM,EAAE,SAAA,EAAW,UAAA,EAAY,eAAA,EAAiB,OAAM,GAAI,MAAA;AAC1D,EAAA,iBAAA,CAAkB,WAAW,WAAW,CAAA;AACxC,EAAA,kBAAA,CAAmB,YAAY,YAAY,CAAA;AAC3C,EAAA,cAAA,CAAe,iBAAiB,iBAAiB,CAAA;AACjD,EAAA,iBAAA,CAAkB,OAAO,OAAO,CAAA;AAEhC,EAAA,MAAM,CAAA,GAAI,IAAA,CAAK,KAAA,CAAM,eAAA,GAAkB,KAAK,CAAA;AAC5C,EAAA,IAAI,CAAA,KAAM,GAAG,OAAO,CAAA;AAEpB,EAAA,MAAM,IAAI,UAAA,GAAa,eAAA;AACvB,EAAA,IAAI,KAAK,EAAA,EAAI;AACX,IAAA,MAAM,IAAI,WAAW,2CAA2C,CAAA;AAAA,EAClE;AACA,EAAA,IAAI,CAAA,KAAM,CAAA,EAAG,OAAO,SAAA,GAAY,CAAA;AAEhC,EAAA,MAAM,QAAS,CAAA,GAAI,SAAA,IAAc,CAAA,GAAA,CAAK,CAAA,GAAI,MAAM,CAAC,CAAA,CAAA;AACjD,EAAA,IAAI,CAAC,MAAA,CAAO,QAAA,CAAS,KAAK,CAAA,EAAG;AAC3B,IAAA,MAAM,IAAI,WAAW,wCAAwC,CAAA;AAAA,EAC/D;AACA,EAAA,OAAO,KAAA;AACT;;;ACVO,SAAS,qBACd,MAAA,EAC4B;AAC5B,EAAA,MAAM,EAAE,SAAA,EAAW,UAAA,EAAY,iBAAiB,KAAA,EAAO,qBAAA,GAAwB,GAAE,GAAI,MAAA;AACrF,EAAA,iBAAA,CAAkB,WAAW,WAAW,CAAA;AACxC,EAAA,cAAA,CAAe,iBAAiB,iBAAiB,CAAA;AACjD,EAAA,iBAAA,CAAkB,OAAO,OAAO,CAAA;AAChC,EAAA,iBAAA,CAAkB,uBAAuB,uBAAuB,CAAA;AAEhE,EAAA,MAAM,UAAA,GAAa,IAAA,CAAK,KAAA,CAAM,eAAA,GAAkB,KAAK,CAAA;AACrD,EAAA,IAAI,UAAA,KAAe,CAAA,IAAK,SAAA,KAAc,CAAA,EAAG;AACvC,IAAA,OAAO,EAAE,kBAAkB,CAAA,EAAG,QAAA,EAAU,EAAC,EAAG,SAAA,EAAW,CAAA,EAAG,aAAA,EAAe,CAAA,EAAE;AAAA,EAC7E;AAEA,EAAA,MAAM,cAAc,WAAA,CAAY,EAAE,WAAW,UAAA,EAAY,eAAA,EAAiB,OAAO,CAAA;AACjF,EAAA,MAAM,IAAI,UAAA,GAAa,eAAA;AAEvB,EAAA,MAAM,WAA8B,EAAC;AACrC,EAAA,IAAI,OAAA,GAAU,SAAA;AACd,EAAA,IAAI,SAAA,GAAY,CAAA;AAChB,EAAA,IAAI,aAAA,GAAgB,CAAA;AAEpB,EAAA,KAAA,IAAS,SAAS,CAAA,EAAG,MAAA,IAAU,UAAA,IAAc,OAAA,GAAU,GAAG,MAAA,EAAA,EAAU;AAClE,IAAA,MAAM,eAAA,GAAkB,CAAA,KAAM,CAAA,GAAI,CAAA,GAAI,OAAA,GAAU,CAAA;AAChD,IAAA,IAAI,UAAU,WAAA,GAAc,qBAAA;AAC5B,IAAA,IAAI,mBAAmB,OAAA,GAAU,eAAA;AAEjC,IAAA,IAAI,mBAAmB,OAAA,EAAS;AAC9B,MAAA,gBAAA,GAAmB,OAAA;AACnB,MAAA,OAAA,GAAU,gBAAA,GAAmB,eAAA;AAAA,IAC/B;AAEA,IAAA,OAAA,GAAU,OAAA,GAAU,gBAAA;AACpB,IAAA,IAAI,IAAA,CAAK,GAAA,CAAI,OAAO,CAAA,GAAI,OAAO,OAAA,GAAU,CAAA;AAEzC,IAAA,SAAA,IAAa,OAAA;AACb,IAAA,aAAA,IAAiB,eAAA;AAEjB,IAAA,QAAA,CAAS,IAAA,CAAK;AAAA,MACZ,MAAA;AAAA,MACA,OAAA;AAAA,MACA,gBAAA;AAAA,MACA,eAAA;AAAA,MACA;AAAA,KACD,CAAA;AAAA,EACH;AAEA,EAAA,OAAO;AAAA,IACL,gBAAA,EAAkB,WAAA;AAAA,IAClB,QAAA;AAAA,IACA,SAAA;AAAA,IACA;AAAA,GACF;AACF;;;AClEO,SAAS,sBAAsB,MAAA,EAA6C;AACjF,EAAA,MAAM,EAAE,SAAA,EAAW,UAAA,EAAY,eAAA,EAAiB,oBAAA,EAAsB,uBAAsB,GAC1F,MAAA;AAEF,EAAA,iBAAA,CAAkB,WAAW,WAAW,CAAA;AACxC,EAAA,kBAAA,CAAmB,YAAY,YAAY,CAAA;AAC3C,EAAA,cAAA,CAAe,iBAAiB,iBAAiB,CAAA;AACjD,EAAA,iBAAA,CAAkB,sBAAsB,sBAAsB,CAAA;AAC9D,EAAA,iBAAA,CAAkB,uBAAuB,uBAAuB,CAAA;AAEhE,EAAA,IAAI,SAAA,IAAa,GAAG,OAAO,CAAA;AAC3B,EAAA,MAAM,UAAU,oBAAA,GAAuB,qBAAA;AACvC,EAAA,IAAI,OAAA,IAAW,CAAA,EAAG,OAAO,MAAA,CAAO,iBAAA;AAEhC,EAAA,MAAM,IAAI,UAAA,GAAa,eAAA;AACvB,EAAA,IAAI,OAAA,GAAU,SAAA;AACd,EAAA,IAAI,MAAA,GAAS,CAAA;AAEb,EAAA,OAAO,OAAA,GAAU,KAAA,IAAS,MAAA,GAAS,GAAA,EAAQ;AACzC,IAAA,MAAM,QAAA,GAAW,CAAA,GAAI,CAAA,GAAI,OAAA,GAAU,CAAA,GAAI,CAAA;AACvC,IAAA,IAAI,OAAA,IAAW,QAAA,EAAU,OAAO,MAAA,CAAO,iBAAA;AACvC,IAAA,MAAM,aAAA,GAAgB,IAAA,CAAK,GAAA,CAAI,OAAA,GAAU,UAAU,OAAO,CAAA;AAC1D,IAAA,OAAA,IAAW,aAAA;AACX,IAAA,MAAA,EAAA;AAAA,EACF;AACA,EAAA,OAAO,OAAA,IAAW,KAAA,GAAQ,MAAA,GAAS,MAAA,CAAO,iBAAA;AAC5C;;;ACzBO,SAAS,iBAAiB,MAAA,EAAwC;AACvE,EAAA,MAAM,EAAE,SAAA,EAAW,UAAA,EAAY,eAAA,EAAiB,KAAA,EAAO,mBAAkB,GAAI,MAAA;AAC7E,EAAA,iBAAA,CAAkB,WAAW,WAAW,CAAA;AACxC,EAAA,cAAA,CAAe,iBAAiB,iBAAiB,CAAA;AACjD,EAAA,iBAAA,CAAkB,OAAO,OAAO,CAAA;AAChC,EAAA,iBAAA,CAAkB,mBAAmB,mBAAmB,CAAA;AAExD,EAAA,MAAM,CAAA,GAAI,IAAA,CAAK,KAAA,CAAM,eAAA,GAAkB,KAAK,CAAA;AAC5C,EAAA,IAAI,CAAA,KAAM,CAAA,IAAK,iBAAA,IAAqB,CAAA,EAAG,OAAO,CAAA;AAC9C,EAAA,IAAI,iBAAA,IAAqB,GAAG,OAAO,SAAA;AAEnC,EAAA,MAAM,UAAU,WAAA,CAAY,EAAE,WAAW,UAAA,EAAY,eAAA,EAAiB,OAAO,CAAA;AAC7E,EAAA,MAAM,IAAI,UAAA,GAAa,eAAA;AACvB,EAAA,MAAM,CAAA,GAAI,iBAAA;AAEV,EAAA,IAAI,CAAA,KAAM,GAAG,OAAO,IAAA,CAAK,IAAI,CAAA,EAAG,SAAA,GAAY,UAAU,CAAC,CAAA;AACvD,EAAA,MAAM,OAAA,GAAU,aAAa,CAAA,GAAI,CAAA,KAAM,IAAI,OAAA,IAAA,CAAA,CAAa,CAAA,GAAI,CAAA,KAAM,CAAA,GAAI,CAAA,IAAK,CAAA,CAAA;AAC3E,EAAA,OAAO,IAAA,CAAK,GAAA,CAAI,CAAA,EAAG,OAAO,CAAA;AAC5B;;;ACnBO,SAAS,gBAAgB,MAAA,EAAuC;AACrE,EAAA,MAAM,EAAE,KAAA,EAAO,QAAA,GAAW,CAAA,EAAG,IAAA,GAAO,WAAU,GAAI,MAAA;AAClD,EAAA,kBAAA,CAAmB,OAAO,OAAO,CAAA;AACjC,EAAA,MAAM,IAAI,IAAA,CAAK,GAAA,CAAI,GAAG,IAAA,CAAK,KAAA,CAAM,QAAQ,CAAC,CAAA;AAC1C,EAAA,MAAM,SAAS,EAAA,IAAM,CAAA;AACrB,EAAA,IAAI,SAAS,WAAA,EAAa;AACxB,IAAA,MAAM,SAAS,KAAA,GAAQ,MAAA;AACvB,IAAA,MAAM,IAAA,GAAO,MAAA,GAAS,CAAA,GAAI,EAAA,GAAK,CAAA;AAC/B,IAAA,MAAM,SAAA,GAAY,IAAA,CAAK,GAAA,CAAI,MAAM,CAAA;AACjC,IAAA,MAAM,QAAA,GAAW,IAAA,CAAK,KAAA,CAAM,SAAS,CAAA;AACrC,IAAA,MAAM,WAAW,SAAA,GAAY,QAAA;AAC7B,IAAA,MAAM,OAAA,GAAU,KAAA;AAChB,IAAA,IAAI,IAAA,CAAK,GAAA,CAAI,QAAA,GAAW,GAAG,KAAK,OAAA,EAAS;AACvC,MAAA,MAAM,WAAA,GAAc,QAAA,GAAW,CAAA,KAAM,CAAA,GAAI,WAAW,QAAA,GAAW,CAAA;AAC/D,MAAA,OAAQ,OAAO,WAAA,GAAe,MAAA;AAAA,IAChC;AACA,IAAA,OAAO,IAAA,CAAK,KAAA,CAAM,MAAM,CAAA,GAAI,MAAA;AAAA,EAC9B;AACA,EAAA,OAAO,IAAA,CAAK,KAAA,CAAM,KAAA,GAAQ,MAAM,CAAA,GAAI,MAAA;AACtC","file":"index.cjs","sourcesContent":["export function assertFiniteNumber(value: number, name: string): void {\n if (!Number.isFinite(value)) {\n throw new RangeError(`${name} must be a finite number`);\n }\n}\n\nexport function assertNonNegative(value: number, name: string): void {\n assertFiniteNumber(value, name);\n if (value < 0) {\n throw new RangeError(`${name} must be >= 0`);\n }\n}\n\nexport function assertPositive(value: number, name: string): void {\n assertFiniteNumber(value, name);\n if (value <= 0) {\n throw new RangeError(`${name} must be > 0`);\n }\n}\n","import { assertPositive } from \"../utils/assertions.js\";\n\nexport type CagrParams = {\n startValue: number;\n endValue: number;\n years: number;\n};\n\n/**\n * Compound annual growth rate (CAGR) between start and end value over the given years.\n * CAGR = (endValue/startValue)^(1/years) - 1\n */\nexport function cagr(params: CagrParams): number {\n const { startValue, endValue, years } = params;\n assertPositive(startValue, \"startValue\");\n assertPositive(years, \"years\");\n if (endValue <= 0) return -1;\n return (endValue / startValue) ** (1 / years) - 1;\n}\n","import { assertNonNegative, assertPositive } from \"../utils/assertions.js\";\n\nexport type CompoundParams = {\n principal: number;\n rate: number;\n timesPerYear: number;\n years: number;\n};\n\n/**\n * Computes compound growth using nominal annual `rate` compounded `timesPerYear`.\n * Returns the final amount (principal + interest).\n */\nexport function compound(params: CompoundParams): number {\n const { principal, rate, timesPerYear, years } = params;\n assertNonNegative(principal, \"principal\");\n assertPositive(timesPerYear, \"timesPerYear\");\n assertNonNegative(years, \"years\");\n\n if (rate === 0 || years === 0) return principal;\n\n const n = timesPerYear;\n const t = years;\n return principal * (1 + rate / n) ** (n * t);\n}\n","import { assertFiniteNumber, assertPositive } from \"../utils/assertions.js\";\n\nexport type EffectiveAnnualRateParams = {\n nominalRate: number;\n timesPerYear: number;\n};\n\n/**\n * Converts a nominal annual rate to effective annual rate (EAR).\n * EAR = (1 + nominalRate/timesPerYear)^timesPerYear - 1\n */\nexport function effectiveAnnualRate(params: EffectiveAnnualRateParams): number {\n const { nominalRate, timesPerYear } = params;\n assertFiniteNumber(nominalRate, \"nominalRate\");\n assertPositive(timesPerYear, \"timesPerYear\");\n\n const r = nominalRate / timesPerYear;\n return (1 + r) ** timesPerYear - 1;\n}\n","import { assertNonNegative, assertPositive } from \"../utils/assertions.js\";\n\nexport type FutureValueParams = {\n presentValue: number;\n rate: number;\n timesPerYear: number;\n years: number;\n};\n\n/**\n * Future value of a lump sum using nominal annual `rate` compounded `timesPerYear`.\n */\nexport function futureValue(params: FutureValueParams): number {\n const { presentValue, rate, timesPerYear, years } = params;\n assertNonNegative(presentValue, \"presentValue\");\n assertPositive(timesPerYear, \"timesPerYear\");\n assertNonNegative(years, \"years\");\n\n if (rate === 0 || years === 0) return presentValue;\n\n const n = timesPerYear;\n const t = years;\n return presentValue * (1 + rate / n) ** (n * t);\n}\n","import { assertFiniteNumber, assertNonNegative } from \"../utils/assertions.js\";\n\nexport type InflationAdjustedAmountParams = {\n amount: number;\n annualInflationRate: number;\n years: number;\n direction: \"toPast\" | \"toFuture\";\n};\n\n/**\n * Purchasing power across time. toPast: amount/(1+rate)^years. toFuture: amount*(1+rate)^years.\n */\nexport function inflationAdjustedAmount(params: InflationAdjustedAmountParams): number {\n const { amount, annualInflationRate, years, direction } = params;\n assertFiniteNumber(amount, \"amount\");\n assertFiniteNumber(annualInflationRate, \"annualInflationRate\");\n assertNonNegative(years, \"years\");\n const factor = (1 + annualInflationRate) ** years;\n return direction === \"toPast\" ? amount / factor : amount * factor;\n}\n","import { assertNonNegative, assertPositive } from \"../utils/assertions.js\";\n\nexport type InvestmentGrowthParams = {\n initial: number;\n contributionPerPeriod?: number;\n rate: number;\n timesPerYear: number;\n years: number;\n contributionTiming?: \"end\" | \"begin\";\n};\n\nexport type InvestmentGrowthResult = {\n futureValue: number;\n totalContributions: number;\n totalInterest: number;\n};\n\n/**\n * Future value of an investment with optional periodic contributions.\n *\n * - `rate` is nominal annual rate (e.g. 0.05 for 5%)\n * - contributions occur each compounding period (`timesPerYear`)\n */\nexport function investmentGrowth(params: InvestmentGrowthParams): InvestmentGrowthResult {\n const {\n initial,\n contributionPerPeriod = 0,\n rate,\n timesPerYear,\n years,\n contributionTiming = \"end\",\n } = params;\n\n assertNonNegative(initial, \"initial\");\n assertNonNegative(contributionPerPeriod, \"contributionPerPeriod\");\n assertPositive(timesPerYear, \"timesPerYear\");\n assertNonNegative(years, \"years\");\n\n const periods = Math.round(timesPerYear * years);\n if (periods === 0) {\n return {\n futureValue: initial,\n totalContributions: 0,\n totalInterest: 0,\n };\n }\n\n const r = rate / timesPerYear;\n\n // Lump sum growth\n const fvInitial = rate === 0 ? initial : initial * (1 + r) ** periods;\n\n // Annuity future value (ordinary vs due)\n let fvContrib = 0;\n if (contributionPerPeriod !== 0) {\n if (rate === 0) {\n fvContrib = contributionPerPeriod * periods;\n } else {\n const ordinary = contributionPerPeriod * (((1 + r) ** periods - 1) / r);\n fvContrib = contributionTiming === \"begin\" ? ordinary * (1 + r) : ordinary;\n }\n }\n\n const futureValue = fvInitial + fvContrib;\n const totalContributions = contributionPerPeriod * periods;\n const totalInterest = futureValue - initial - totalContributions;\n\n return { futureValue, totalContributions, totalInterest };\n}\n","export type NewtonRaphsonParams = {\n initialGuess: number;\n fn: (x: number) => number;\n derivative: (x: number) => number;\n tolerance?: number;\n maxIterations?: number;\n min?: number;\n max?: number;\n};\n\nexport function newtonRaphson(params: NewtonRaphsonParams): number | undefined {\n const {\n initialGuess,\n fn,\n derivative,\n tolerance = 1e-10,\n maxIterations = 100,\n min = Number.NEGATIVE_INFINITY,\n max = Number.POSITIVE_INFINITY,\n } = params;\n\n let x = initialGuess;\n for (let i = 0; i < maxIterations; i++) {\n const value = fn(x);\n if (!Number.isFinite(value)) return undefined;\n if (Math.abs(value) <= tolerance) return x;\n\n const slope = derivative(x);\n if (!Number.isFinite(slope) || Math.abs(slope) < 1e-14) return undefined;\n\n x -= value / slope;\n if (x < min) x = min;\n if (x > max) x = max;\n }\n\n return undefined;\n}\n\nexport type BisectionParams = {\n fn: (x: number) => number;\n lower: number;\n upper: number;\n tolerance?: number;\n maxIterations?: number;\n};\n\nexport function bisection(params: BisectionParams): number | undefined {\n const { fn, lower, upper, tolerance = 1e-10, maxIterations = 200 } = params;\n let a = lower;\n let b = upper;\n let fa = fn(a);\n let fb = fn(b);\n\n if (!Number.isFinite(fa) || !Number.isFinite(fb) || fa * fb > 0) return undefined;\n if (Math.abs(fa) <= tolerance) return a;\n if (Math.abs(fb) <= tolerance) return b;\n\n for (let i = 0; i < maxIterations; i++) {\n const c = (a + b) / 2;\n const fc = fn(c);\n if (!Number.isFinite(fc)) return undefined;\n if (Math.abs(fc) <= tolerance || Math.abs(b - a) <= tolerance) return c;\n\n if (fa * fc < 0) {\n b = c;\n fb = fc;\n } else {\n a = c;\n fa = fc;\n }\n }\n\n return (a + b) / 2;\n}\n","import { assertFiniteNumber } from \"../utils/assertions.js\";\nimport { bisection, newtonRaphson } from \"../utils/solvers.js\";\n\nexport type IrrParams = {\n cashFlows: number[];\n guess?: number;\n maxIterations?: number;\n lowerBound?: number;\n upperBound?: number;\n};\n\nfunction npvAt(rate: number, cashFlows: number[]): number {\n let sum = 0;\n for (let t = 0; t < cashFlows.length; t++) {\n const cf = cashFlows[t];\n if (cf !== undefined) sum += cf / (1 + rate) ** t;\n }\n return sum;\n}\n\nfunction npvDerivativeAt(rate: number, cashFlows: number[]): number {\n let sum = 0;\n for (let t = 1; t < cashFlows.length; t++) {\n const cf = cashFlows[t];\n if (cf !== undefined) sum -= (t * cf) / (1 + rate) ** (t + 1);\n }\n return sum;\n}\n\nfunction hasPositiveAndNegative(cashFlows: number[]): boolean {\n let hasPositive = false;\n let hasNegative = false;\n for (const cf of cashFlows) {\n if (cf > 0) hasPositive = true;\n if (cf < 0) hasNegative = true;\n if (hasPositive && hasNegative) return true;\n }\n return false;\n}\n\nfunction findBracket(\n fn: (x: number) => number,\n lowerBound: number,\n upperBound: number,\n): { lower: number; upper: number } | undefined {\n const scan = (\n start: number,\n end: number,\n segments = 200,\n ): { lower: number; upper: number } | undefined => {\n let prevX: number | undefined;\n let prevValue: number | undefined;\n for (let i = 0; i <= segments; i++) {\n const x = start + ((end - start) * i) / segments;\n const value = fn(x);\n if (!Number.isFinite(value)) continue;\n if (value === 0) return { lower: x, upper: x };\n if (prevX !== undefined && prevValue !== undefined && prevValue * value < 0) {\n return { lower: prevX, upper: x };\n }\n prevX = x;\n prevValue = value;\n }\n return undefined;\n };\n\n let lower = lowerBound;\n let upper = upperBound;\n for (let i = 0; i < 20; i++) {\n const bracket = scan(lower, upper);\n if (bracket !== undefined) return bracket;\n lower = Math.max(-0.999999999, (lower - 1) / 2);\n upper = upper * 2 + 1;\n }\n\n return scan(lower, upper, 400);\n}\n\nexport function irr(params: IrrParams): number {\n const {\n cashFlows,\n guess = 0.1,\n maxIterations = 100,\n lowerBound = -0.99,\n upperBound = 10,\n } = params;\n if (cashFlows.length === 0) {\n throw new RangeError(\"cashFlows must contain at least one value\");\n }\n assertFiniteNumber(guess, \"guess\");\n assertFiniteNumber(maxIterations, \"maxIterations\");\n assertFiniteNumber(lowerBound, \"lowerBound\");\n assertFiniteNumber(upperBound, \"upperBound\");\n if (maxIterations <= 0 || !Number.isInteger(maxIterations)) {\n throw new RangeError(\"maxIterations must be a positive integer\");\n }\n if (lowerBound <= -1) {\n throw new RangeError(\"lowerBound must be > -1\");\n }\n if (upperBound <= lowerBound) {\n throw new RangeError(\"upperBound must be greater than lowerBound\");\n }\n\n for (const cf of cashFlows) assertFiniteNumber(cf, \"cashFlows[]\");\n if (!hasPositiveAndNegative(cashFlows)) {\n throw new RangeError(\"cashFlows must include at least one positive and one negative value\");\n }\n\n const fn = (rate: number) => npvAt(rate, cashFlows);\n const derivative = (rate: number) => npvDerivativeAt(rate, cashFlows);\n\n const newton = newtonRaphson({\n initialGuess: guess,\n fn,\n derivative,\n tolerance: 1e-10,\n maxIterations,\n min: lowerBound,\n max: upperBound,\n });\n if (newton !== undefined) return newton;\n\n const bracket = findBracket(fn, lowerBound, upperBound);\n if (bracket === undefined) {\n throw new RangeError(\"IRR did not converge within search bounds\");\n }\n if (bracket.lower === bracket.upper) return bracket.lower;\n\n const bisected = bisection({\n fn,\n lower: bracket.lower,\n upper: bracket.upper,\n tolerance: 1e-10,\n maxIterations: maxIterations * 2,\n });\n if (bisected !== undefined) return bisected;\n\n throw new RangeError(\"IRR did not converge\");\n}\n","import { assertFiniteNumber } from \"../utils/assertions.js\";\n\nexport type NpvParams = {\n rate: number;\n cashFlows: number[];\n};\n\n/**\n * Net present value at a discount `rate`.\n * cashFlows[0] is the period-0 cash flow.\n */\nexport function npv(params: NpvParams): number {\n const { rate, cashFlows } = params;\n assertFiniteNumber(rate, \"rate\");\n if (rate <= -1) throw new RangeError(\"rate must be > -1\");\n if (cashFlows.length === 0) return 0;\n\n let sum = 0;\n for (let t = 0; t < cashFlows.length; t++) {\n const cf = cashFlows[t];\n if (cf === undefined) continue;\n assertFiniteNumber(cf, `cashFlows[${t}]`);\n sum += cf / (1 + rate) ** t;\n }\n return sum;\n}\n","import { assertNonNegative } from \"../utils/assertions.js\";\n\nexport type PaymentFromPresentValueParams = {\n presentValue: number;\n ratePerPeriod: number;\n periods: number;\n /** Payment at start of each period (annuity due). Default end (ordinary). */\n timing?: \"end\" | \"begin\";\n};\n\n/**\n * Periodic payment required to pay off a present value (e.g. loan) over periods.\n * PMT = PV * r / (1 - (1+r)^-n). For due: divide by (1+r).\n */\nexport function paymentFromPresentValue(params: PaymentFromPresentValueParams): number {\n const { presentValue, ratePerPeriod, periods, timing = \"end\" } = params;\n assertNonNegative(presentValue, \"presentValue\");\n assertNonNegative(periods, \"periods\");\n\n if (presentValue === 0 || periods === 0) return 0;\n if (ratePerPeriod === 0) {\n const pmt = presentValue / periods;\n return timing === \"begin\" ? pmt / (1 + ratePerPeriod) : pmt;\n }\n let pmt = (ratePerPeriod * presentValue) / (1 - (1 + ratePerPeriod) ** -periods);\n if (timing === \"begin\") pmt /= 1 + ratePerPeriod;\n return pmt;\n}\n","import { assertFiniteNumber, assertNonNegative, assertPositive } from \"../utils/assertions.js\";\n\nexport type PeriodsToReachGoalParams = {\n principal: number;\n targetFutureValue: number;\n rate: number;\n timesPerYear: number;\n contributionPerPeriod?: number;\n contributionTiming?: \"end\" | \"begin\";\n maxPeriods?: number;\n};\n\n/**\n * Number of compounding periods until future value reaches the goal.\n * With no contributions: closed form. With contributions: iterative.\n */\nexport function periodsToReachGoal(params: PeriodsToReachGoalParams): number {\n const {\n principal,\n targetFutureValue,\n rate,\n timesPerYear,\n contributionPerPeriod = 0,\n contributionTiming = \"end\",\n maxPeriods = 100000,\n } = params;\n\n assertNonNegative(principal, \"principal\");\n assertNonNegative(targetFutureValue, \"targetFutureValue\");\n assertFiniteNumber(rate, \"rate\");\n assertPositive(timesPerYear, \"timesPerYear\");\n assertNonNegative(contributionPerPeriod, \"contributionPerPeriod\");\n assertPositive(maxPeriods, \"maxPeriods\");\n\n if (targetFutureValue <= principal) return 0;\n\n const r = rate / timesPerYear;\n if (r <= -1) {\n throw new RangeError(\"rate / timesPerYear must be > -1\");\n }\n\n if (contributionPerPeriod === 0) {\n if (principal === 0) return Number.POSITIVE_INFINITY;\n if (rate === 0) return targetFutureValue <= principal ? 0 : Number.POSITIVE_INFINITY;\n if (r < 0) return Number.POSITIVE_INFINITY;\n const n = Math.log(targetFutureValue / principal) / Math.log(1 + r);\n return Number.isFinite(n) && n >= 0 ? Math.ceil(n) : Number.POSITIVE_INFINITY;\n }\n\n if (rate === 0) {\n const needed = targetFutureValue - principal;\n if (needed <= 0) return 0;\n return Math.ceil(needed / contributionPerPeriod);\n }\n\n // With contributions: iterate until FV >= target\n let fv = principal;\n let periods = 0;\n while (fv < targetFutureValue && periods < maxPeriods) {\n if (contributionTiming === \"begin\") fv += contributionPerPeriod;\n fv = fv * (1 + r) + (contributionTiming === \"end\" ? contributionPerPeriod : 0);\n periods++;\n }\n if (fv >= targetFutureValue) return periods;\n throw new RangeError(\"maxPeriods exceeded before reaching target\");\n}\n","import { assertNonNegative, assertPositive } from \"../utils/assertions.js\";\n\nexport type PresentValueParams = {\n futureValue: number;\n rate: number;\n timesPerYear: number;\n years: number;\n};\n\n/**\n * Present value of a lump sum using nominal annual `rate` compounded `timesPerYear`.\n */\nexport function presentValue(params: PresentValueParams): number {\n const { futureValue: fv, rate, timesPerYear, years } = params;\n assertNonNegative(fv, \"futureValue\");\n assertPositive(timesPerYear, \"timesPerYear\");\n assertNonNegative(years, \"years\");\n\n if (rate === 0 || years === 0) return fv;\n\n const n = timesPerYear;\n const t = years;\n return fv / (1 + rate / n) ** (n * t);\n}\n","import { assertNonNegative } from \"../utils/assertions.js\";\n\nexport type PresentValueOfAnnuityParams = {\n paymentPerPeriod: number;\n ratePerPeriod: number;\n periods: number;\n timing?: \"end\" | \"begin\";\n};\n\n/**\n * Present value of an annuity. PV = PMT * (1 - (1+r)^-n) / r. Due: multiply by (1+r).\n */\nexport function presentValueOfAnnuity(params: PresentValueOfAnnuityParams): number {\n const { paymentPerPeriod, ratePerPeriod, periods, timing = \"end\" } = params;\n assertNonNegative(paymentPerPeriod, \"paymentPerPeriod\");\n assertNonNegative(periods, \"periods\");\n\n if (periods === 0) return 0;\n if (ratePerPeriod === 0) {\n const pv = paymentPerPeriod * periods;\n return timing === \"begin\" ? pv * (1 + ratePerPeriod) : pv;\n }\n const pv = (paymentPerPeriod * (1 - (1 + ratePerPeriod) ** -periods)) / ratePerPeriod;\n return timing === \"begin\" ? pv * (1 + ratePerPeriod) : pv;\n}\n","import { assertFiniteNumber, assertNonNegative, assertPositive } from \"../utils/assertions.js\";\nimport { bisection, newtonRaphson } from \"../utils/solvers.js\";\n\nexport type RateToReachGoalParams = {\n principal: number;\n targetFutureValue: number;\n periods: number;\n contributionPerPeriod?: number;\n contributionTiming?: \"end\" | \"begin\";\n lowerBound?: number;\n upperBound?: number;\n maxIterations?: number;\n tolerance?: number;\n};\n\n/**\n * Rate per period required to reach target future value in given periods.\n * Uses Newton-Raphson when contributions are present; closed form for lump sum.\n */\nexport function rateToReachGoal(params: RateToReachGoalParams): number {\n const {\n principal,\n targetFutureValue,\n periods,\n contributionPerPeriod = 0,\n contributionTiming = \"end\",\n lowerBound = -0.99,\n upperBound = 10,\n maxIterations = 100,\n tolerance = 1e-10,\n } = params;\n\n assertNonNegative(principal, \"principal\");\n assertNonNegative(targetFutureValue, \"targetFutureValue\");\n assertPositive(periods, \"periods\");\n assertNonNegative(contributionPerPeriod, \"contributionPerPeriod\");\n assertFiniteNumber(lowerBound, \"lowerBound\");\n assertFiniteNumber(upperBound, \"upperBound\");\n assertFiniteNumber(maxIterations, \"maxIterations\");\n assertFiniteNumber(tolerance, \"tolerance\");\n if (lowerBound <= -1) throw new RangeError(\"lowerBound must be > -1\");\n if (upperBound <= lowerBound) throw new RangeError(\"upperBound must be greater than lowerBound\");\n if (!Number.isInteger(maxIterations) || maxIterations <= 0) {\n throw new RangeError(\"maxIterations must be a positive integer\");\n }\n if (tolerance <= 0) throw new RangeError(\"tolerance must be > 0\");\n\n if (periods === 0) return 0;\n if (targetFutureValue <= principal && contributionPerPeriod === 0) return 0;\n\n if (contributionPerPeriod === 0) {\n if (targetFutureValue <= principal) return 0;\n if (principal === 0) {\n throw new RangeError(\n \"rateToReachGoal is undefined when principal is 0 and contributions are 0\",\n );\n }\n return (targetFutureValue / principal) ** (1 / periods) - 1;\n }\n\n const dueFactor = contributionTiming === \"begin\" ? 1 : 0;\n const fn = (r: number) => {\n const onePlusR = 1 + r;\n const onePlusRN = onePlusR ** periods;\n const fvLump = principal * onePlusRN;\n const annuityBase = r === 0 ? periods : (onePlusRN - 1) / r;\n const fvAnnuity = contributionPerPeriod * annuityBase * (1 + dueFactor * r);\n return fvLump + fvAnnuity - targetFutureValue;\n };\n const derivative = (r: number) => {\n const delta = Math.abs(r) > 1e-6 ? Math.abs(r) * 1e-6 : 1e-6;\n return (fn(r + delta) - fn(r - delta)) / (2 * delta);\n };\n\n const initialGuess =\n (targetFutureValue / (principal + contributionPerPeriod * periods)) ** (1 / periods) - 1;\n\n const newton = newtonRaphson({\n initialGuess: Number.isFinite(initialGuess) ? Math.max(initialGuess, lowerBound) : 0.01,\n fn,\n derivative,\n tolerance,\n maxIterations,\n min: lowerBound,\n max: upperBound,\n });\n if (newton !== undefined) return newton;\n\n const bracket = findBracket(fn, lowerBound, upperBound);\n if (bracket === undefined) {\n throw new RangeError(\"rateToReachGoal did not converge within search bounds\");\n }\n if (bracket.lower === bracket.upper) return bracket.lower;\n\n const bisected = bisection({\n fn,\n lower: bracket.lower,\n upper: bracket.upper,\n tolerance,\n maxIterations: maxIterations * 2,\n });\n if (bisected !== undefined) return bisected;\n throw new RangeError(\"rateToReachGoal did not converge\");\n}\n\nfunction findBracket(\n fn: (x: number) => number,\n lowerBound: number,\n upperBound: number,\n): { lower: number; upper: number } | undefined {\n const scan = (\n start: number,\n end: number,\n segments = 200,\n ): { lower: number; upper: number } | undefined => {\n let prevX: number | undefined;\n let prevValue: number | undefined;\n for (let i = 0; i <= segments; i++) {\n const x = start + ((end - start) * i) / segments;\n const value = fn(x);\n if (!Number.isFinite(value)) continue;\n if (value === 0) return { lower: x, upper: x };\n if (prevX !== undefined && prevValue !== undefined && prevValue * value < 0) {\n return { lower: prevX, upper: x };\n }\n prevX = x;\n prevValue = value;\n }\n return undefined;\n };\n\n let lower = lowerBound;\n let upper = upperBound;\n for (let i = 0; i < 20; i++) {\n const bracket = scan(lower, upper);\n if (bracket !== undefined) return bracket;\n lower = Math.max(-0.999999999, (lower - 1) / 2);\n upper = upper * 2 + 1;\n }\n\n return scan(lower, upper, 400);\n}\n","import { assertFiniteNumber } from \"../utils/assertions.js\";\n\nexport type RealReturnParams = { nominalReturn: number; inflationRate: number };\n\nexport function realReturn(params: RealReturnParams): number {\n const { nominalReturn, inflationRate } = params;\n assertFiniteNumber(nominalReturn, \"nominalReturn\");\n assertFiniteNumber(inflationRate, \"inflationRate\");\n if (inflationRate <= -1) return NaN;\n return (1 + nominalReturn) / (1 + inflationRate) - 1;\n}\n","import { assertFiniteNumber, assertPositive } from \"../utils/assertions.js\";\n\nexport type RuleOf72Params = {\n rate: number;\n /** Use 69 for continuous-ish approximation (e.g. daily compounding). Default 72. */\n constant?: 72 | 69;\n};\n\n/**\n * Approximate years to double a lump sum at the given annual rate.\n * rate is decimal (e.g. 0.07 for 7%). Uses rule of 72 by default, or 69 if specified.\n */\nexport function ruleOf72(params: RuleOf72Params): number {\n const { rate, constant = 72 } = params;\n assertFiniteNumber(rate, \"rate\");\n assertPositive(rate, \"rate\");\n return constant / 100 / rate;\n}\n","import { assertFiniteNumber, assertPositive } from \"../utils/assertions.js\";\nimport { bisection, newtonRaphson } from \"../utils/solvers.js\";\n\ntype PaymentTiming = \"end\" | \"begin\";\n\nfunction assertTiming(value: PaymentTiming, name: string): void {\n if (value !== \"end\" && value !== \"begin\") {\n throw new RangeError(`${name} must be \"end\" or \"begin\"`);\n }\n}\n\nfunction annuityDueFactor(ratePerPeriod: number, timing: PaymentTiming): number {\n return timing === \"begin\" ? 1 + ratePerPeriod : 1;\n}\n\nfunction futureValueFromCashFlows(\n ratePerPeriod: number,\n periods: number,\n payment: number,\n presentValue: number,\n timing: PaymentTiming,\n): number {\n if (ratePerPeriodIsInvalidForDomain(ratePerPeriod)) {\n throw new RangeError(\"ratePerPeriod must be > -1\");\n }\n if (ratePerPeriod === 0) return -(presentValue + payment * periods);\n\n const growth = (1 + ratePerPeriod) ** periods;\n if (!Number.isFinite(growth) || growth <= 0) return Number.NaN;\n const paymentFv =\n payment * ((growth - 1) / ratePerPeriod) * annuityDueFactor(ratePerPeriod, timing);\n return -(presentValue * growth + paymentFv);\n}\n\nexport type FvParams = {\n ratePerPeriod: number;\n periods: number;\n payment?: number;\n presentValue: number;\n timing?: PaymentTiming;\n};\n\n/**\n * Excel FV equivalent.\n */\nexport function fv(params: FvParams): number {\n const { ratePerPeriod, periods, payment = 0, presentValue, timing = \"end\" } = params;\n assertFiniteNumber(ratePerPeriod, \"ratePerPeriod\");\n assertPositive(periods, \"periods\");\n assertFiniteNumber(payment, \"payment\");\n assertFiniteNumber(presentValue, \"presentValue\");\n assertTiming(timing, \"timing\");\n\n const value = futureValueFromCashFlows(ratePerPeriod, periods, payment, presentValue, timing);\n if (!Number.isFinite(value)) {\n throw new RangeError(\"Numerical instability for given inputs\");\n }\n return value;\n}\n\nexport type PvParams = {\n ratePerPeriod: number;\n periods: number;\n payment?: number;\n futureValue?: number;\n timing?: PaymentTiming;\n};\n\n/**\n * Excel PV equivalent.\n */\nexport function pv(params: PvParams): number {\n const { ratePerPeriod, periods, payment = 0, futureValue = 0, timing = \"end\" } = params;\n assertFiniteNumber(ratePerPeriod, \"ratePerPeriod\");\n assertPositive(periods, \"periods\");\n assertFiniteNumber(payment, \"payment\");\n assertFiniteNumber(futureValue, \"futureValue\");\n assertTiming(timing, \"timing\");\n if (ratePerPeriodIsInvalidForDomain(ratePerPeriod)) {\n throw new RangeError(\"ratePerPeriod must be > -1\");\n }\n\n if (ratePerPeriod === 0) return -(futureValue + payment * periods);\n\n const growth = (1 + ratePerPeriod) ** periods;\n if (!Number.isFinite(growth) || growth <= 0) {\n throw new RangeError(\"Numerical instability for given ratePerPeriod/periods\");\n }\n const paymentPv =\n ((payment * (1 - 1 / growth)) / ratePerPeriod) * annuityDueFactor(ratePerPeriod, timing);\n const value = -futureValue / growth - paymentPv;\n if (!Number.isFinite(value)) {\n throw new RangeError(\"Numerical instability for given inputs\");\n }\n return value;\n}\n\nexport type PmtParams = {\n ratePerPeriod: number;\n periods: number;\n presentValue: number;\n futureValue?: number;\n timing?: PaymentTiming;\n};\n\n/**\n * Excel PMT equivalent.\n */\nexport function pmt(params: PmtParams): number {\n const { ratePerPeriod, periods, presentValue, futureValue = 0, timing = \"end\" } = params;\n assertFiniteNumber(ratePerPeriod, \"ratePerPeriod\");\n assertPositive(periods, \"periods\");\n assertFiniteNumber(presentValue, \"presentValue\");\n assertFiniteNumber(futureValue, \"futureValue\");\n assertTiming(timing, \"timing\");\n if (ratePerPeriodIsInvalidForDomain(ratePerPeriod)) {\n throw new RangeError(\"ratePerPeriod must be > -1\");\n }\n\n if (ratePerPeriod === 0) return -(presentValue + futureValue) / periods;\n\n const growth = (1 + ratePerPeriod) ** periods;\n if (!Number.isFinite(growth) || growth <= 0) {\n throw new RangeError(\"Numerical instability for given ratePerPeriod/periods\");\n }\n const numerator = -(futureValue + presentValue * growth) * ratePerPeriod;\n const denominator = (growth - 1) * annuityDueFactor(ratePerPeriod, timing);\n const value = numerator / denominator;\n if (!Number.isFinite(value)) {\n throw new RangeError(\"Numerical instability for given inputs\");\n }\n return value;\n}\n\nexport type NperParams = {\n ratePerPeriod: number;\n payment: number;\n presentValue: number;\n futureValue?: number;\n timing?: PaymentTiming;\n};\n\n/**\n * Excel NPER equivalent.\n */\nexport function nper(params: NperParams): number {\n const { ratePerPeriod, payment, presentValue, futureValue = 0, timing = \"end\" } = params;\n assertFiniteNumber(ratePerPeriod, \"ratePerPeriod\");\n assertFiniteNumber(payment, \"payment\");\n assertFiniteNumber(presentValue, \"presentValue\");\n assertFiniteNumber(futureValue, \"futureValue\");\n assertTiming(timing, \"timing\");\n if (ratePerPeriodIsInvalidForDomain(ratePerPeriod)) {\n throw new RangeError(\"ratePerPeriod must be > -1\");\n }\n\n if (ratePerPeriod === 0) {\n const linear = -(presentValue + futureValue) / payment;\n return Number.isFinite(linear) && linear >= 0 ? linear : Number.NaN;\n }\n\n const adjustedPayment = payment * annuityDueFactor(ratePerPeriod, timing);\n const numerator = adjustedPayment - futureValue * ratePerPeriod;\n const denominator = adjustedPayment + presentValue * ratePerPeriod;\n if (numerator === 0 || denominator === 0) return Number.NaN;\n const ratio = numerator / denominator;\n if (ratio <= 0) return Number.NaN;\n\n const periods = Math.log(ratio) / Math.log(1 + ratePerPeriod);\n return Number.isFinite(periods) ? periods : Number.NaN;\n}\n\nexport type RateParams = {\n periods: number;\n payment: number;\n presentValue: number;\n futureValue?: number;\n timing?: PaymentTiming;\n guess?: number;\n tolerance?: number;\n maxIterations?: number;\n lowerBound?: number;\n upperBound?: number;\n};\n\n/**\n * Excel RATE equivalent.\n */\nexport function rate(params: RateParams): number {\n const {\n periods,\n payment,\n presentValue,\n futureValue = 0,\n timing = \"end\",\n guess = 0.1,\n tolerance = 1e-10,\n maxIterations = 100,\n lowerBound = -0.999999999,\n upperBound = 10,\n } = params;\n assertPositive(periods, \"periods\");\n assertFiniteNumber(payment, \"payment\");\n assertFiniteNumber(presentValue, \"presentValue\");\n assertFiniteNumber(futureValue, \"futureValue\");\n assertFiniteNumber(guess, \"guess\");\n assertFiniteNumber(maxIterations, \"maxIterations\");\n assertFiniteNumber(lowerBound, \"lowerBound\");\n assertFiniteNumber(upperBound, \"upperBound\");\n assertTiming(timing, \"timing\");\n if (ratePerPeriodIsInvalidForDomain(lowerBound)) {\n throw new RangeError(\"lowerBound must be > -1\");\n }\n if (upperBound <= lowerBound) {\n throw new RangeError(\"upperBound must be greater than lowerBound\");\n }\n if (!Number.isInteger(maxIterations) || maxIterations <= 0) {\n throw new RangeError(\"maxIterations must be a positive integer\");\n }\n\n const fn = (r: number) =>\n futureValueFromCashFlows(r, periods, payment, presentValue, timing) - futureValue;\n const derivative = (r: number) => {\n const delta = Math.abs(r) > 1e-5 ? Math.abs(r) * 1e-6 : 1e-6;\n return (fn(r + delta) - fn(r - delta)) / (2 * delta);\n };\n\n const newton = newtonRaphson({\n initialGuess: guess,\n fn,\n derivative,\n tolerance,\n maxIterations,\n min: lowerBound,\n max: upperBound,\n });\n if (newton !== undefined) return newton;\n\n const bracket = findRateBracket(fn, lowerBound, upperBound);\n if (bracket === undefined) {\n throw new RangeError(\"RATE did not converge within search bounds\");\n }\n if (bracket.lower === bracket.upper) return bracket.lower;\n\n const bisected = bisection({\n fn,\n lower: bracket.lower,\n upper: bracket.upper,\n tolerance,\n maxIterations: maxIterations * 2,\n });\n if (bisected !== undefined) return bisected;\n\n throw new RangeError(\"RATE did not converge\");\n}\n\nfunction ratePerPeriodIsInvalidForDomain(ratePerPeriod: number): boolean {\n return ratePerPeriod <= -1;\n}\n\nfunction findRateBracket(\n fn: (x: number) => number,\n lowerBound: number,\n upperBound: number,\n): { lower: number; upper: number } | undefined {\n const scan = (\n start: number,\n end: number,\n segments = 200,\n ): { lower: number; upper: number } | undefined => {\n let prevX: number | undefined;\n let prevValue: number | undefined;\n for (let i = 0; i <= segments; i++) {\n const x = start + ((end - start) * i) / segments;\n const value = fn(x);\n if (!Number.isFinite(value)) continue;\n if (value === 0) return { lower: x, upper: x };\n if (prevValue !== undefined && prevX !== undefined && prevValue * value < 0) {\n return { lower: prevX, upper: x };\n }\n prevX = x;\n prevValue = value;\n }\n return undefined;\n };\n\n let lower = lowerBound;\n let upper = upperBound;\n for (let i = 0; i < 20; i++) {\n const bracket = scan(lower, upper);\n if (bracket !== undefined) return bracket;\n lower = Math.max(-0.999999999, (lower - 1) / 2);\n upper = upper * 2 + 1;\n }\n\n return scan(lower, upper, 400);\n}\n","import { assertFiniteNumber, assertNonNegative, assertPositive } from \"../utils/assertions.js\";\n\nexport type LoanPaymentParams = {\n principal: number;\n annualRate: number;\n paymentsPerYear: number;\n years: number;\n};\n\n/**\n * Fixed periodic payment for an amortizing loan.\n *\n * - `annualRate` is nominal annual rate (e.g. 0.06 for 6%)\n * - payment returned is per period (`paymentsPerYear`)\n */\nexport function loanPayment(params: LoanPaymentParams): number {\n const { principal, annualRate, paymentsPerYear, years } = params;\n assertNonNegative(principal, \"principal\");\n assertFiniteNumber(annualRate, \"annualRate\");\n assertPositive(paymentsPerYear, \"paymentsPerYear\");\n assertNonNegative(years, \"years\");\n\n const n = Math.round(paymentsPerYear * years);\n if (n === 0) return 0;\n\n const r = annualRate / paymentsPerYear;\n if (r <= -1) {\n throw new RangeError(\"annualRate / paymentsPerYear must be > -1\");\n }\n if (r === 0) return principal / n;\n\n const value = (r * principal) / (1 - (1 + r) ** -n);\n if (!Number.isFinite(value)) {\n throw new RangeError(\"Numerical instability for given inputs\");\n }\n return value;\n}\n","import { assertNonNegative, assertPositive } from \"../utils/assertions.js\";\nimport { loanPayment } from \"./loanPayment.js\";\n\nexport type AmortizationScheduleParams = {\n principal: number;\n annualRate: number;\n paymentsPerYear: number;\n years: number;\n extraPaymentPerPeriod?: number;\n};\n\nexport type AmortizationRow = {\n period: number;\n payment: number;\n principalPayment: number;\n interestPayment: number;\n balance: number;\n};\n\nexport type AmortizationScheduleResult = {\n paymentPerPeriod: number;\n schedule: AmortizationRow[];\n totalPaid: number;\n totalInterest: number;\n};\n\nexport function amortizationSchedule(\n params: AmortizationScheduleParams,\n): AmortizationScheduleResult {\n const { principal, annualRate, paymentsPerYear, years, extraPaymentPerPeriod = 0 } = params;\n assertNonNegative(principal, \"principal\");\n assertPositive(paymentsPerYear, \"paymentsPerYear\");\n assertNonNegative(years, \"years\");\n assertNonNegative(extraPaymentPerPeriod, \"extraPaymentPerPeriod\");\n\n const scheduledN = Math.round(paymentsPerYear * years);\n if (scheduledN === 0 || principal === 0) {\n return { paymentPerPeriod: 0, schedule: [], totalPaid: 0, totalInterest: 0 };\n }\n\n const basePayment = loanPayment({ principal, annualRate, paymentsPerYear, years });\n const r = annualRate / paymentsPerYear;\n\n const schedule: AmortizationRow[] = [];\n let balance = principal;\n let totalPaid = 0;\n let totalInterest = 0;\n\n for (let period = 1; period <= scheduledN && balance > 0; period++) {\n const interestPayment = r === 0 ? 0 : balance * r;\n let payment = basePayment + extraPaymentPerPeriod;\n let principalPayment = payment - interestPayment;\n\n if (principalPayment > balance) {\n principalPayment = balance;\n payment = principalPayment + interestPayment;\n }\n\n balance = balance - principalPayment;\n if (Math.abs(balance) < 1e-12) balance = 0;\n\n totalPaid += payment;\n totalInterest += interestPayment;\n\n schedule.push({\n period,\n payment,\n principalPayment,\n interestPayment,\n balance,\n });\n }\n\n return {\n paymentPerPeriod: basePayment,\n schedule,\n totalPaid,\n totalInterest,\n };\n}\n","import { assertFiniteNumber, assertNonNegative, assertPositive } from \"../utils/assertions.js\";\n\nexport type PayoffPeriodWithExtraParams = {\n principal: number;\n annualRate: number;\n paymentsPerYear: number;\n basePaymentPerPeriod: number;\n extraPaymentPerPeriod: number;\n};\n\n/**\n * Number of periods until the loan is paid off with the given base + extra payment.\n */\nexport function payoffPeriodWithExtra(params: PayoffPeriodWithExtraParams): number {\n const { principal, annualRate, paymentsPerYear, basePaymentPerPeriod, extraPaymentPerPeriod } =\n params;\n\n assertNonNegative(principal, \"principal\");\n assertFiniteNumber(annualRate, \"annualRate\");\n assertPositive(paymentsPerYear, \"paymentsPerYear\");\n assertNonNegative(basePaymentPerPeriod, \"basePaymentPerPeriod\");\n assertNonNegative(extraPaymentPerPeriod, \"extraPaymentPerPeriod\");\n\n if (principal <= 0) return 0;\n const payment = basePaymentPerPeriod + extraPaymentPerPeriod;\n if (payment <= 0) return Number.POSITIVE_INFINITY;\n\n const r = annualRate / paymentsPerYear;\n let balance = principal;\n let period = 0;\n\n while (balance > 1e-12 && period < 100000) {\n const interest = r > 0 ? balance * r : 0;\n if (payment <= interest) return Number.POSITIVE_INFINITY;\n const principalPaid = Math.min(payment - interest, balance);\n balance -= principalPaid;\n period++;\n }\n return balance <= 1e-12 ? period : Number.POSITIVE_INFINITY;\n}\n","import { assertNonNegative, assertPositive } from \"../utils/assertions.js\";\nimport { loanPayment } from \"./loanPayment.js\";\n\nexport type RemainingBalanceParams = {\n principal: number;\n annualRate: number;\n paymentsPerYear: number;\n years: number;\n afterPeriodNumber: number;\n};\n\n/**\n * Remaining balance after a given number of payments on an amortizing loan.\n */\nexport function remainingBalance(params: RemainingBalanceParams): number {\n const { principal, annualRate, paymentsPerYear, years, afterPeriodNumber } = params;\n assertNonNegative(principal, \"principal\");\n assertPositive(paymentsPerYear, \"paymentsPerYear\");\n assertNonNegative(years, \"years\");\n assertNonNegative(afterPeriodNumber, \"afterPeriodNumber\");\n\n const n = Math.round(paymentsPerYear * years);\n if (n === 0 || afterPeriodNumber >= n) return 0;\n if (afterPeriodNumber <= 0) return principal;\n\n const payment = loanPayment({ principal, annualRate, paymentsPerYear, years });\n const r = annualRate / paymentsPerYear;\n const k = afterPeriodNumber;\n\n if (r === 0) return Math.max(0, principal - payment * k);\n const balance = principal * (1 + r) ** k - payment * (((1 + r) ** k - 1) / r);\n return Math.max(0, balance);\n}\n","import { assertFiniteNumber } from \"./assertions.js\";\n\nexport type RoundToCurrencyParams = {\n value: number;\n /** Decimal places. Default 2. */\n decimals?: number;\n /** 'half-up': 0.5 rounds up. 'half-even': banker's rounding. Default 'half-up'. */\n mode?: \"half-up\" | \"half-even\";\n};\n\n/**\n * Rounds a number to currency (default 2 decimals). half-up: 2.125 -> 2.13. half-even: 2.125 -> 2.12.\n */\nexport function roundToCurrency(params: RoundToCurrencyParams): number {\n const { value, decimals = 2, mode = \"half-up\" } = params;\n assertFiniteNumber(value, \"value\");\n const d = Math.max(0, Math.floor(decimals));\n const factor = 10 ** d;\n if (mode === \"half-even\") {\n const scaled = value * factor;\n const sign = scaled < 0 ? -1 : 1;\n const absScaled = Math.abs(scaled);\n const floorAbs = Math.floor(absScaled);\n const fraction = absScaled - floorAbs;\n const epsilon = 1e-12;\n if (Math.abs(fraction - 0.5) <= epsilon) {\n const nearestEven = floorAbs % 2 === 0 ? floorAbs : floorAbs + 1;\n return (sign * nearestEven) / factor;\n }\n return Math.round(scaled) / factor;\n }\n return Math.round(value * factor) / factor;\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/utils/assertions.ts","../src/interest/cagr.ts","../src/interest/compound.ts","../src/interest/effectiveAnnualRate.ts","../src/interest/futureValue.ts","../src/interest/inflationAdjustedAmount.ts","../src/interest/investmentGrowth.ts","../src/utils/solvers.ts","../src/interest/irr.ts","../src/interest/npv.ts","../src/interest/paymentFromPresentValue.ts","../src/interest/periodsToReachGoal.ts","../src/interest/presentValue.ts","../src/interest/presentValueOfAnnuity.ts","../src/interest/rateToReachGoal.ts","../src/interest/realReturn.ts","../src/interest/ruleOf72.ts","../src/interest/tvom.ts","../src/loans/loanPayment.ts","../src/loans/amortizationSchedule.ts","../src/loans/payoffPeriodWithExtra.ts","../src/loans/remainingBalance.ts","../src/utils/roundToCurrency.ts"],"names":["rate","presentValue","futureValue","pmt","fv","pv","assertContributionTiming","findBracket"],"mappings":"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","file":"index.cjs","sourcesContent":["export function assertFiniteNumber(value: number, name: string): void {\n if (!Number.isFinite(value)) {\n throw new RangeError(`${name} must be a finite number`);\n }\n}\n\nexport function assertNonNegative(value: number, name: string): void {\n assertFiniteNumber(value, name);\n if (value < 0) {\n throw new RangeError(`${name} must be >= 0`);\n }\n}\n\nexport function assertPositive(value: number, name: string): void {\n assertFiniteNumber(value, name);\n if (value <= 0) {\n throw new RangeError(`${name} must be > 0`);\n }\n}\n","import { assertPositive } from \"../utils/assertions.js\";\n\nexport type CagrParams = {\n startValue: number;\n endValue: number;\n years: number;\n};\n\n/**\n * Compound annual growth rate (CAGR) between start and end value over the given years.\n * CAGR = (endValue/startValue)^(1/years) - 1\n */\nexport function cagr(params: CagrParams): number {\n const { startValue, endValue, years } = params;\n assertPositive(startValue, \"startValue\");\n assertPositive(years, \"years\");\n if (endValue <= 0) return -1;\n return (endValue / startValue) ** (1 / years) - 1;\n}\n","import { assertNonNegative, assertPositive } from \"../utils/assertions.js\";\n\nexport type CompoundParams = {\n principal: number;\n rate: number;\n timesPerYear: number;\n years: number;\n};\n\n/**\n * Computes compound growth using nominal annual `rate` compounded `timesPerYear`.\n * Returns the final amount (principal + interest).\n */\nexport function compound(params: CompoundParams): number {\n const { principal, rate, timesPerYear, years } = params;\n assertNonNegative(principal, \"principal\");\n assertPositive(timesPerYear, \"timesPerYear\");\n assertNonNegative(years, \"years\");\n\n if (rate === 0 || years === 0) return principal;\n\n const n = timesPerYear;\n const t = years;\n return principal * (1 + rate / n) ** (n * t);\n}\n","import { assertFiniteNumber, assertPositive } from \"../utils/assertions.js\";\n\nexport type EffectiveAnnualRateParams = {\n nominalRate: number;\n timesPerYear: number;\n};\n\n/**\n * Converts a nominal annual rate to effective annual rate (EAR).\n * EAR = (1 + nominalRate/timesPerYear)^timesPerYear - 1\n */\nexport function effectiveAnnualRate(params: EffectiveAnnualRateParams): number {\n const { nominalRate, timesPerYear } = params;\n assertFiniteNumber(nominalRate, \"nominalRate\");\n assertPositive(timesPerYear, \"timesPerYear\");\n\n const r = nominalRate / timesPerYear;\n return (1 + r) ** timesPerYear - 1;\n}\n","import { assertNonNegative, assertPositive } from \"../utils/assertions.js\";\n\nexport type FutureValueParams = {\n presentValue: number;\n rate: number;\n timesPerYear: number;\n years: number;\n};\n\n/**\n * Future value of a lump sum using nominal annual `rate` compounded `timesPerYear`.\n */\nexport function futureValue(params: FutureValueParams): number {\n const { presentValue, rate, timesPerYear, years } = params;\n assertNonNegative(presentValue, \"presentValue\");\n assertPositive(timesPerYear, \"timesPerYear\");\n assertNonNegative(years, \"years\");\n\n if (rate === 0 || years === 0) return presentValue;\n\n const n = timesPerYear;\n const t = years;\n return presentValue * (1 + rate / n) ** (n * t);\n}\n","import { assertFiniteNumber, assertNonNegative } from \"../utils/assertions.js\";\n\nexport type InflationAdjustedAmountParams = {\n amount: number;\n annualInflationRate: number;\n years: number;\n direction: \"toPast\" | \"toFuture\";\n};\n\n/**\n * Purchasing power across time. toPast: amount/(1+rate)^years. toFuture: amount*(1+rate)^years.\n */\nexport function inflationAdjustedAmount(params: InflationAdjustedAmountParams): number {\n const { amount, annualInflationRate, years, direction } = params;\n assertFiniteNumber(amount, \"amount\");\n assertFiniteNumber(annualInflationRate, \"annualInflationRate\");\n assertNonNegative(years, \"years\");\n const factor = (1 + annualInflationRate) ** years;\n return direction === \"toPast\" ? amount / factor : amount * factor;\n}\n","import { assertNonNegative, assertPositive } from \"../utils/assertions.js\";\n\nexport type InvestmentGrowthParams = {\n initial: number;\n contributionPerPeriod?: number;\n rate: number;\n timesPerYear: number;\n years: number;\n contributionTiming?: \"end\" | \"begin\";\n};\n\nexport type InvestmentGrowthResult = {\n futureValue: number;\n totalContributions: number;\n totalInterest: number;\n};\n\n/**\n * Future value of an investment with optional periodic contributions.\n *\n * - `rate` is nominal annual rate (e.g. 0.05 for 5%)\n * - contributions occur each compounding period (`timesPerYear`)\n */\nexport function investmentGrowth(params: InvestmentGrowthParams): InvestmentGrowthResult {\n const {\n initial,\n contributionPerPeriod = 0,\n rate,\n timesPerYear,\n years,\n contributionTiming = \"end\",\n } = params;\n\n assertNonNegative(initial, \"initial\");\n assertNonNegative(contributionPerPeriod, \"contributionPerPeriod\");\n assertPositive(timesPerYear, \"timesPerYear\");\n assertNonNegative(years, \"years\");\n\n const periods = Math.round(timesPerYear * years);\n if (periods === 0) {\n return {\n futureValue: initial,\n totalContributions: 0,\n totalInterest: 0,\n };\n }\n\n const r = rate / timesPerYear;\n\n // Lump sum growth\n const fvInitial = rate === 0 ? initial : initial * (1 + r) ** periods;\n\n // Annuity future value (ordinary vs due)\n let fvContrib = 0;\n if (contributionPerPeriod !== 0) {\n if (rate === 0) {\n fvContrib = contributionPerPeriod * periods;\n } else {\n const ordinary = contributionPerPeriod * (((1 + r) ** periods - 1) / r);\n fvContrib = contributionTiming === \"begin\" ? ordinary * (1 + r) : ordinary;\n }\n }\n\n const futureValue = fvInitial + fvContrib;\n const totalContributions = contributionPerPeriod * periods;\n const totalInterest = futureValue - initial - totalContributions;\n\n return { futureValue, totalContributions, totalInterest };\n}\n","export type NewtonRaphsonParams = {\n initialGuess: number;\n fn: (x: number) => number;\n derivative: (x: number) => number;\n tolerance?: number;\n maxIterations?: number;\n min?: number;\n max?: number;\n};\n\nexport function newtonRaphson(params: NewtonRaphsonParams): number | undefined {\n const {\n initialGuess,\n fn,\n derivative,\n tolerance = 1e-10,\n maxIterations = 100,\n min = Number.NEGATIVE_INFINITY,\n max = Number.POSITIVE_INFINITY,\n } = params;\n\n let x = initialGuess;\n for (let i = 0; i < maxIterations; i++) {\n const value = fn(x);\n if (!Number.isFinite(value)) return undefined;\n if (Math.abs(value) <= tolerance) return x;\n\n const slope = derivative(x);\n if (!Number.isFinite(slope) || Math.abs(slope) < 1e-14) return undefined;\n\n x -= value / slope;\n if (x < min) x = min;\n if (x > max) x = max;\n }\n\n return undefined;\n}\n\nexport type BisectionParams = {\n fn: (x: number) => number;\n lower: number;\n upper: number;\n tolerance?: number;\n maxIterations?: number;\n};\n\nexport function bisection(params: BisectionParams): number | undefined {\n const { fn, lower, upper, tolerance = 1e-10, maxIterations = 200 } = params;\n let a = lower;\n let b = upper;\n let fa = fn(a);\n let fb = fn(b);\n\n if (!Number.isFinite(fa) || !Number.isFinite(fb) || fa * fb > 0) return undefined;\n if (Math.abs(fa) <= tolerance) return a;\n if (Math.abs(fb) <= tolerance) return b;\n\n for (let i = 0; i < maxIterations; i++) {\n const c = (a + b) / 2;\n const fc = fn(c);\n if (!Number.isFinite(fc)) return undefined;\n if (Math.abs(fc) <= tolerance || Math.abs(b - a) <= tolerance) return c;\n\n if (fa * fc < 0) {\n b = c;\n fb = fc;\n } else {\n a = c;\n fa = fc;\n }\n }\n\n return (a + b) / 2;\n}\n","import { assertFiniteNumber } from \"../utils/assertions.js\";\nimport { bisection, newtonRaphson } from \"../utils/solvers.js\";\n\nexport type IrrParams = {\n cashFlows: number[];\n guess?: number;\n maxIterations?: number;\n lowerBound?: number;\n upperBound?: number;\n};\n\nfunction npvAt(rate: number, cashFlows: number[]): number {\n let sum = 0;\n for (let t = 0; t < cashFlows.length; t++) {\n const cf = cashFlows[t];\n if (cf !== undefined) sum += cf / (1 + rate) ** t;\n }\n return sum;\n}\n\nfunction npvDerivativeAt(rate: number, cashFlows: number[]): number {\n let sum = 0;\n for (let t = 1; t < cashFlows.length; t++) {\n const cf = cashFlows[t];\n if (cf !== undefined) sum -= (t * cf) / (1 + rate) ** (t + 1);\n }\n return sum;\n}\n\nfunction hasPositiveAndNegative(cashFlows: number[]): boolean {\n let hasPositive = false;\n let hasNegative = false;\n for (const cf of cashFlows) {\n if (cf > 0) hasPositive = true;\n if (cf < 0) hasNegative = true;\n if (hasPositive && hasNegative) return true;\n }\n return false;\n}\n\nfunction findBracket(\n fn: (x: number) => number,\n lowerBound: number,\n upperBound: number,\n): { lower: number; upper: number } | undefined {\n const scan = (\n start: number,\n end: number,\n segments = 200,\n ): { lower: number; upper: number } | undefined => {\n let prevX: number | undefined;\n let prevValue: number | undefined;\n for (let i = 0; i <= segments; i++) {\n const x = start + ((end - start) * i) / segments;\n const value = fn(x);\n if (!Number.isFinite(value)) continue;\n if (value === 0) return { lower: x, upper: x };\n if (prevX !== undefined && prevValue !== undefined && prevValue * value < 0) {\n return { lower: prevX, upper: x };\n }\n prevX = x;\n prevValue = value;\n }\n return undefined;\n };\n\n let lower = lowerBound;\n let upper = upperBound;\n for (let i = 0; i < 20; i++) {\n const bracket = scan(lower, upper);\n if (bracket !== undefined) return bracket;\n lower = Math.max(-0.999999999, (lower - 1) / 2);\n upper = upper * 2 + 1;\n }\n\n return scan(lower, upper, 400);\n}\n\nexport function irr(params: IrrParams): number {\n const {\n cashFlows,\n guess = 0.1,\n maxIterations = 100,\n lowerBound = -0.99,\n upperBound = 10,\n } = params;\n if (cashFlows.length === 0) {\n throw new RangeError(\"cashFlows must contain at least one value\");\n }\n assertFiniteNumber(guess, \"guess\");\n assertFiniteNumber(maxIterations, \"maxIterations\");\n assertFiniteNumber(lowerBound, \"lowerBound\");\n assertFiniteNumber(upperBound, \"upperBound\");\n if (maxIterations <= 0 || !Number.isInteger(maxIterations)) {\n throw new RangeError(\"maxIterations must be a positive integer\");\n }\n if (lowerBound <= -1) {\n throw new RangeError(\"lowerBound must be > -1\");\n }\n if (upperBound <= lowerBound) {\n throw new RangeError(\"upperBound must be greater than lowerBound\");\n }\n\n for (const cf of cashFlows) assertFiniteNumber(cf, \"cashFlows[]\");\n if (!hasPositiveAndNegative(cashFlows)) {\n throw new RangeError(\"cashFlows must include at least one positive and one negative value\");\n }\n\n const fn = (rate: number) => npvAt(rate, cashFlows);\n const derivative = (rate: number) => npvDerivativeAt(rate, cashFlows);\n\n const newton = newtonRaphson({\n initialGuess: guess,\n fn,\n derivative,\n tolerance: 1e-10,\n maxIterations,\n min: lowerBound,\n max: upperBound,\n });\n if (newton !== undefined) return newton;\n\n const bracket = findBracket(fn, lowerBound, upperBound);\n if (bracket === undefined) {\n throw new RangeError(\"IRR did not converge within search bounds\");\n }\n if (bracket.lower === bracket.upper) return bracket.lower;\n\n const bisected = bisection({\n fn,\n lower: bracket.lower,\n upper: bracket.upper,\n tolerance: 1e-10,\n maxIterations: maxIterations * 2,\n });\n if (bisected !== undefined) return bisected;\n\n throw new RangeError(\"IRR did not converge\");\n}\n","import { assertFiniteNumber } from \"../utils/assertions.js\";\n\nexport type NpvParams = {\n rate: number;\n cashFlows: number[];\n};\n\n/**\n * Net present value at a discount `rate`.\n * cashFlows[0] is the period-0 cash flow.\n */\nexport function npv(params: NpvParams): number {\n const { rate, cashFlows } = params;\n assertFiniteNumber(rate, \"rate\");\n if (rate <= -1) throw new RangeError(\"rate must be > -1\");\n if (cashFlows.length === 0) return 0;\n\n let sum = 0;\n for (let t = 0; t < cashFlows.length; t++) {\n const cf = cashFlows[t];\n if (cf === undefined) continue;\n assertFiniteNumber(cf, `cashFlows[${t}]`);\n sum += cf / (1 + rate) ** t;\n }\n return sum;\n}\n","import { assertNonNegative } from \"../utils/assertions.js\";\n\nexport type PaymentFromPresentValueParams = {\n presentValue: number;\n ratePerPeriod: number;\n periods: number;\n /** Payment at start of each period (annuity due). Default end (ordinary). */\n timing?: \"end\" | \"begin\";\n};\n\n/**\n * Periodic payment required to pay off a present value (e.g. loan) over periods.\n * PMT = PV * r / (1 - (1+r)^-n). For due: divide by (1+r).\n */\nexport function paymentFromPresentValue(params: PaymentFromPresentValueParams): number {\n const { presentValue, ratePerPeriod, periods, timing = \"end\" } = params;\n assertNonNegative(presentValue, \"presentValue\");\n assertNonNegative(periods, \"periods\");\n\n if (presentValue === 0 || periods === 0) return 0;\n if (ratePerPeriod === 0) {\n const pmt = presentValue / periods;\n return timing === \"begin\" ? pmt / (1 + ratePerPeriod) : pmt;\n }\n let pmt = (ratePerPeriod * presentValue) / (1 - (1 + ratePerPeriod) ** -periods);\n if (timing === \"begin\") pmt /= 1 + ratePerPeriod;\n return pmt;\n}\n","import { assertFiniteNumber, assertNonNegative, assertPositive } from \"../utils/assertions.js\";\n\nexport type PeriodsToReachGoalParams = {\n principal: number;\n targetFutureValue: number;\n rate: number;\n timesPerYear: number;\n contributionPerPeriod?: number;\n contributionTiming?: \"end\" | \"begin\";\n maxPeriods?: number;\n};\n\nfunction assertContributionTiming(value: \"end\" | \"begin\", name: string): void {\n if (value !== \"end\" && value !== \"begin\") {\n throw new RangeError(`${name} must be \"end\" or \"begin\"`);\n }\n}\n\n/**\n * Number of compounding periods until future value reaches the goal.\n * With no contributions: closed form. With contributions: iterative.\n */\nexport function periodsToReachGoal(params: PeriodsToReachGoalParams): number {\n const {\n principal,\n targetFutureValue,\n rate,\n timesPerYear,\n contributionPerPeriod = 0,\n contributionTiming = \"end\",\n maxPeriods = 100000,\n } = params;\n\n assertNonNegative(principal, \"principal\");\n assertNonNegative(targetFutureValue, \"targetFutureValue\");\n assertFiniteNumber(rate, \"rate\");\n assertPositive(timesPerYear, \"timesPerYear\");\n assertNonNegative(contributionPerPeriod, \"contributionPerPeriod\");\n assertPositive(maxPeriods, \"maxPeriods\");\n assertContributionTiming(contributionTiming, \"contributionTiming\");\n\n if (targetFutureValue <= principal) return 0;\n\n const r = rate / timesPerYear;\n if (r <= -1) {\n throw new RangeError(\"rate / timesPerYear must be > -1\");\n }\n\n if (contributionPerPeriod === 0) {\n if (principal === 0) return Number.POSITIVE_INFINITY;\n if (rate === 0) return targetFutureValue <= principal ? 0 : Number.POSITIVE_INFINITY;\n if (r < 0) return Number.POSITIVE_INFINITY;\n const n = Math.log(targetFutureValue / principal) / Math.log(1 + r);\n return Number.isFinite(n) && n >= 0 ? Math.ceil(n) : Number.POSITIVE_INFINITY;\n }\n\n if (rate === 0) {\n const needed = targetFutureValue - principal;\n if (needed <= 0) return 0;\n return Math.ceil(needed / contributionPerPeriod);\n }\n\n // With contributions: iterate until FV >= target\n let fv = principal;\n let periods = 0;\n while (fv < targetFutureValue && periods < maxPeriods) {\n if (contributionTiming === \"begin\") fv += contributionPerPeriod;\n fv = fv * (1 + r) + (contributionTiming === \"end\" ? contributionPerPeriod : 0);\n periods++;\n }\n if (fv >= targetFutureValue) return periods;\n throw new RangeError(\"maxPeriods exceeded before reaching target\");\n}\n","import { assertNonNegative, assertPositive } from \"../utils/assertions.js\";\n\nexport type PresentValueParams = {\n futureValue: number;\n rate: number;\n timesPerYear: number;\n years: number;\n};\n\n/**\n * Present value of a lump sum using nominal annual `rate` compounded `timesPerYear`.\n */\nexport function presentValue(params: PresentValueParams): number {\n const { futureValue: fv, rate, timesPerYear, years } = params;\n assertNonNegative(fv, \"futureValue\");\n assertPositive(timesPerYear, \"timesPerYear\");\n assertNonNegative(years, \"years\");\n\n if (rate === 0 || years === 0) return fv;\n\n const n = timesPerYear;\n const t = years;\n return fv / (1 + rate / n) ** (n * t);\n}\n","import { assertNonNegative } from \"../utils/assertions.js\";\n\nexport type PresentValueOfAnnuityParams = {\n paymentPerPeriod: number;\n ratePerPeriod: number;\n periods: number;\n timing?: \"end\" | \"begin\";\n};\n\n/**\n * Present value of an annuity. PV = PMT * (1 - (1+r)^-n) / r. Due: multiply by (1+r).\n */\nexport function presentValueOfAnnuity(params: PresentValueOfAnnuityParams): number {\n const { paymentPerPeriod, ratePerPeriod, periods, timing = \"end\" } = params;\n assertNonNegative(paymentPerPeriod, \"paymentPerPeriod\");\n assertNonNegative(periods, \"periods\");\n\n if (periods === 0) return 0;\n if (ratePerPeriod === 0) {\n const pv = paymentPerPeriod * periods;\n return timing === \"begin\" ? pv * (1 + ratePerPeriod) : pv;\n }\n const pv = (paymentPerPeriod * (1 - (1 + ratePerPeriod) ** -periods)) / ratePerPeriod;\n return timing === \"begin\" ? pv * (1 + ratePerPeriod) : pv;\n}\n","import { assertFiniteNumber, assertNonNegative, assertPositive } from \"../utils/assertions.js\";\nimport { bisection, newtonRaphson } from \"../utils/solvers.js\";\n\nexport type RateToReachGoalParams = {\n principal: number;\n targetFutureValue: number;\n periods: number;\n contributionPerPeriod?: number;\n contributionTiming?: \"end\" | \"begin\";\n lowerBound?: number;\n upperBound?: number;\n maxIterations?: number;\n tolerance?: number;\n};\n\nfunction assertContributionTiming(value: \"end\" | \"begin\", name: string): void {\n if (value !== \"end\" && value !== \"begin\") {\n throw new RangeError(`${name} must be \"end\" or \"begin\"`);\n }\n}\n\n/**\n * Rate per period required to reach target future value in given periods.\n * Uses Newton-Raphson when contributions are present; closed form for lump sum.\n */\nexport function rateToReachGoal(params: RateToReachGoalParams): number {\n const {\n principal,\n targetFutureValue,\n periods,\n contributionPerPeriod = 0,\n contributionTiming = \"end\",\n lowerBound = -0.99,\n upperBound = 10,\n maxIterations = 100,\n tolerance = 1e-10,\n } = params;\n\n assertNonNegative(principal, \"principal\");\n assertNonNegative(targetFutureValue, \"targetFutureValue\");\n assertPositive(periods, \"periods\");\n assertNonNegative(contributionPerPeriod, \"contributionPerPeriod\");\n assertFiniteNumber(lowerBound, \"lowerBound\");\n assertFiniteNumber(upperBound, \"upperBound\");\n assertFiniteNumber(maxIterations, \"maxIterations\");\n assertFiniteNumber(tolerance, \"tolerance\");\n assertContributionTiming(contributionTiming, \"contributionTiming\");\n if (lowerBound <= -1) throw new RangeError(\"lowerBound must be > -1\");\n if (upperBound <= lowerBound) throw new RangeError(\"upperBound must be greater than lowerBound\");\n if (!Number.isInteger(maxIterations) || maxIterations <= 0) {\n throw new RangeError(\"maxIterations must be a positive integer\");\n }\n if (tolerance <= 0) throw new RangeError(\"tolerance must be > 0\");\n\n if (targetFutureValue <= principal && contributionPerPeriod === 0) return 0;\n\n if (contributionPerPeriod === 0) {\n if (targetFutureValue <= principal) return 0;\n if (principal === 0) {\n throw new RangeError(\n \"rateToReachGoal is undefined when principal is 0 and contributions are 0\",\n );\n }\n return (targetFutureValue / principal) ** (1 / periods) - 1;\n }\n\n const dueFactor = contributionTiming === \"begin\" ? 1 : 0;\n const fn = (r: number) => {\n const onePlusR = 1 + r;\n const onePlusRN = onePlusR ** periods;\n const fvLump = principal * onePlusRN;\n const annuityBase = r === 0 ? periods : (onePlusRN - 1) / r;\n const fvAnnuity = contributionPerPeriod * annuityBase * (1 + dueFactor * r);\n return fvLump + fvAnnuity - targetFutureValue;\n };\n const derivative = (r: number) => {\n const delta = Math.abs(r) > 1e-6 ? Math.abs(r) * 1e-6 : 1e-6;\n return (fn(r + delta) - fn(r - delta)) / (2 * delta);\n };\n\n const initialGuess =\n (targetFutureValue / (principal + contributionPerPeriod * periods)) ** (1 / periods) - 1;\n\n const newton = newtonRaphson({\n initialGuess: Number.isFinite(initialGuess) ? Math.max(initialGuess, lowerBound) : 0.01,\n fn,\n derivative,\n tolerance,\n maxIterations,\n min: lowerBound,\n max: upperBound,\n });\n if (newton !== undefined) return newton;\n\n const bracket = findBracket(fn, lowerBound, upperBound);\n if (bracket === undefined) {\n throw new RangeError(\"rateToReachGoal did not converge within search bounds\");\n }\n if (bracket.lower === bracket.upper) return bracket.lower;\n\n const bisected = bisection({\n fn,\n lower: bracket.lower,\n upper: bracket.upper,\n tolerance,\n maxIterations: maxIterations * 2,\n });\n if (bisected !== undefined) return bisected;\n throw new RangeError(\"rateToReachGoal did not converge\");\n}\n\nfunction findBracket(\n fn: (x: number) => number,\n lowerBound: number,\n upperBound: number,\n): { lower: number; upper: number } | undefined {\n const scan = (\n start: number,\n end: number,\n segments = 200,\n ): { lower: number; upper: number } | undefined => {\n let prevX: number | undefined;\n let prevValue: number | undefined;\n for (let i = 0; i <= segments; i++) {\n const x = start + ((end - start) * i) / segments;\n const value = fn(x);\n if (!Number.isFinite(value)) continue;\n if (value === 0) return { lower: x, upper: x };\n if (prevX !== undefined && prevValue !== undefined && prevValue * value < 0) {\n return { lower: prevX, upper: x };\n }\n prevX = x;\n prevValue = value;\n }\n return undefined;\n };\n\n let lower = lowerBound;\n let upper = upperBound;\n for (let i = 0; i < 20; i++) {\n const bracket = scan(lower, upper);\n if (bracket !== undefined) return bracket;\n lower = Math.max(-0.999999999, (lower - 1) / 2);\n upper = upper * 2 + 1;\n }\n\n return scan(lower, upper, 400);\n}\n","import { assertFiniteNumber } from \"../utils/assertions.js\";\n\nexport type RealReturnParams = { nominalReturn: number; inflationRate: number };\n\nexport function realReturn(params: RealReturnParams): number {\n const { nominalReturn, inflationRate } = params;\n assertFiniteNumber(nominalReturn, \"nominalReturn\");\n assertFiniteNumber(inflationRate, \"inflationRate\");\n if (inflationRate <= -1) return NaN;\n return (1 + nominalReturn) / (1 + inflationRate) - 1;\n}\n","import { assertFiniteNumber, assertPositive } from \"../utils/assertions.js\";\n\nexport type RuleOf72Params = {\n rate: number;\n /** Use 69 for continuous-ish approximation (e.g. daily compounding). Default 72. */\n constant?: 72 | 69;\n};\n\n/**\n * Approximate years to double a lump sum at the given annual rate.\n * rate is decimal (e.g. 0.07 for 7%). Uses rule of 72 by default, or 69 if specified.\n */\nexport function ruleOf72(params: RuleOf72Params): number {\n const { rate, constant = 72 } = params;\n assertFiniteNumber(rate, \"rate\");\n assertPositive(rate, \"rate\");\n return constant / 100 / rate;\n}\n","import { assertFiniteNumber, assertPositive } from \"../utils/assertions.js\";\nimport { bisection, newtonRaphson } from \"../utils/solvers.js\";\n\ntype PaymentTiming = \"end\" | \"begin\";\n\nfunction assertTiming(value: PaymentTiming, name: string): void {\n if (value !== \"end\" && value !== \"begin\") {\n throw new RangeError(`${name} must be \"end\" or \"begin\"`);\n }\n}\n\nfunction annuityDueFactor(ratePerPeriod: number, timing: PaymentTiming): number {\n return timing === \"begin\" ? 1 + ratePerPeriod : 1;\n}\n\nfunction futureValueFromCashFlows(\n ratePerPeriod: number,\n periods: number,\n payment: number,\n presentValue: number,\n timing: PaymentTiming,\n): number {\n if (ratePerPeriodIsInvalidForDomain(ratePerPeriod)) {\n throw new RangeError(\"ratePerPeriod must be > -1\");\n }\n if (ratePerPeriod === 0) return -(presentValue + payment * periods);\n\n const growth = (1 + ratePerPeriod) ** periods;\n if (!Number.isFinite(growth) || growth <= 0) return Number.NaN;\n const paymentFv =\n payment * ((growth - 1) / ratePerPeriod) * annuityDueFactor(ratePerPeriod, timing);\n return -(presentValue * growth + paymentFv);\n}\n\nexport type FvParams = {\n ratePerPeriod: number;\n periods: number;\n payment?: number;\n presentValue: number;\n timing?: PaymentTiming;\n};\n\n/**\n * Excel FV equivalent.\n */\nexport function fv(params: FvParams): number {\n const { ratePerPeriod, periods, payment = 0, presentValue, timing = \"end\" } = params;\n assertFiniteNumber(ratePerPeriod, \"ratePerPeriod\");\n assertPositive(periods, \"periods\");\n assertFiniteNumber(payment, \"payment\");\n assertFiniteNumber(presentValue, \"presentValue\");\n assertTiming(timing, \"timing\");\n\n const value = futureValueFromCashFlows(ratePerPeriod, periods, payment, presentValue, timing);\n if (!Number.isFinite(value)) {\n throw new RangeError(\"Numerical instability for given inputs\");\n }\n return value;\n}\n\nexport type PvParams = {\n ratePerPeriod: number;\n periods: number;\n payment?: number;\n futureValue?: number;\n timing?: PaymentTiming;\n};\n\n/**\n * Excel PV equivalent.\n */\nexport function pv(params: PvParams): number {\n const { ratePerPeriod, periods, payment = 0, futureValue = 0, timing = \"end\" } = params;\n assertFiniteNumber(ratePerPeriod, \"ratePerPeriod\");\n assertPositive(periods, \"periods\");\n assertFiniteNumber(payment, \"payment\");\n assertFiniteNumber(futureValue, \"futureValue\");\n assertTiming(timing, \"timing\");\n if (ratePerPeriodIsInvalidForDomain(ratePerPeriod)) {\n throw new RangeError(\"ratePerPeriod must be > -1\");\n }\n\n if (ratePerPeriod === 0) return -(futureValue + payment * periods);\n\n const growth = (1 + ratePerPeriod) ** periods;\n if (!Number.isFinite(growth) || growth <= 0) {\n throw new RangeError(\"Numerical instability for given ratePerPeriod/periods\");\n }\n const paymentPv =\n ((payment * (1 - 1 / growth)) / ratePerPeriod) * annuityDueFactor(ratePerPeriod, timing);\n const value = -futureValue / growth - paymentPv;\n if (!Number.isFinite(value)) {\n throw new RangeError(\"Numerical instability for given inputs\");\n }\n return value;\n}\n\nexport type PmtParams = {\n ratePerPeriod: number;\n periods: number;\n presentValue: number;\n futureValue?: number;\n timing?: PaymentTiming;\n};\n\n/**\n * Excel PMT equivalent.\n */\nexport function pmt(params: PmtParams): number {\n const { ratePerPeriod, periods, presentValue, futureValue = 0, timing = \"end\" } = params;\n assertFiniteNumber(ratePerPeriod, \"ratePerPeriod\");\n assertPositive(periods, \"periods\");\n assertFiniteNumber(presentValue, \"presentValue\");\n assertFiniteNumber(futureValue, \"futureValue\");\n assertTiming(timing, \"timing\");\n if (ratePerPeriodIsInvalidForDomain(ratePerPeriod)) {\n throw new RangeError(\"ratePerPeriod must be > -1\");\n }\n\n if (ratePerPeriod === 0) return -(presentValue + futureValue) / periods;\n\n const growth = (1 + ratePerPeriod) ** periods;\n if (!Number.isFinite(growth) || growth <= 0) {\n throw new RangeError(\"Numerical instability for given ratePerPeriod/periods\");\n }\n const numerator = -(futureValue + presentValue * growth) * ratePerPeriod;\n const denominator = (growth - 1) * annuityDueFactor(ratePerPeriod, timing);\n const value = numerator / denominator;\n if (!Number.isFinite(value)) {\n throw new RangeError(\"Numerical instability for given inputs\");\n }\n return value;\n}\n\nexport type NperParams = {\n ratePerPeriod: number;\n payment: number;\n presentValue: number;\n futureValue?: number;\n timing?: PaymentTiming;\n};\n\n/**\n * Excel NPER equivalent.\n */\nexport function nper(params: NperParams): number {\n const { ratePerPeriod, payment, presentValue, futureValue = 0, timing = \"end\" } = params;\n assertFiniteNumber(ratePerPeriod, \"ratePerPeriod\");\n assertFiniteNumber(payment, \"payment\");\n assertFiniteNumber(presentValue, \"presentValue\");\n assertFiniteNumber(futureValue, \"futureValue\");\n assertTiming(timing, \"timing\");\n if (ratePerPeriodIsInvalidForDomain(ratePerPeriod)) {\n throw new RangeError(\"ratePerPeriod must be > -1\");\n }\n\n if (ratePerPeriod === 0) {\n const linear = -(presentValue + futureValue) / payment;\n return Number.isFinite(linear) && linear >= 0 ? linear : Number.NaN;\n }\n\n const adjustedPayment = payment * annuityDueFactor(ratePerPeriod, timing);\n const numerator = adjustedPayment - futureValue * ratePerPeriod;\n const denominator = adjustedPayment + presentValue * ratePerPeriod;\n if (numerator === 0 || denominator === 0) return Number.NaN;\n const ratio = numerator / denominator;\n if (ratio <= 0) return Number.NaN;\n\n const periods = Math.log(ratio) / Math.log(1 + ratePerPeriod);\n return Number.isFinite(periods) ? periods : Number.NaN;\n}\n\nexport type RateParams = {\n periods: number;\n payment: number;\n presentValue: number;\n futureValue?: number;\n timing?: PaymentTiming;\n guess?: number;\n tolerance?: number;\n maxIterations?: number;\n lowerBound?: number;\n upperBound?: number;\n};\n\n/**\n * Excel RATE equivalent.\n */\nexport function rate(params: RateParams): number {\n const {\n periods,\n payment,\n presentValue,\n futureValue = 0,\n timing = \"end\",\n guess = 0.1,\n tolerance = 1e-10,\n maxIterations = 100,\n lowerBound = -0.999999999,\n upperBound = 10,\n } = params;\n assertPositive(periods, \"periods\");\n assertFiniteNumber(payment, \"payment\");\n assertFiniteNumber(presentValue, \"presentValue\");\n assertFiniteNumber(futureValue, \"futureValue\");\n assertFiniteNumber(guess, \"guess\");\n assertFiniteNumber(maxIterations, \"maxIterations\");\n assertFiniteNumber(lowerBound, \"lowerBound\");\n assertFiniteNumber(upperBound, \"upperBound\");\n assertTiming(timing, \"timing\");\n if (ratePerPeriodIsInvalidForDomain(lowerBound)) {\n throw new RangeError(\"lowerBound must be > -1\");\n }\n if (upperBound <= lowerBound) {\n throw new RangeError(\"upperBound must be greater than lowerBound\");\n }\n if (!Number.isInteger(maxIterations) || maxIterations <= 0) {\n throw new RangeError(\"maxIterations must be a positive integer\");\n }\n\n const fn = (r: number) =>\n futureValueFromCashFlows(r, periods, payment, presentValue, timing) - futureValue;\n const derivative = (r: number) => {\n const delta = Math.abs(r) > 1e-5 ? Math.abs(r) * 1e-6 : 1e-6;\n return (fn(r + delta) - fn(r - delta)) / (2 * delta);\n };\n\n const newton = newtonRaphson({\n initialGuess: guess,\n fn,\n derivative,\n tolerance,\n maxIterations,\n min: lowerBound,\n max: upperBound,\n });\n if (newton !== undefined) return newton;\n\n const bracket = findRateBracket(fn, lowerBound, upperBound);\n if (bracket === undefined) {\n throw new RangeError(\"RATE did not converge within search bounds\");\n }\n if (bracket.lower === bracket.upper) return bracket.lower;\n\n const bisected = bisection({\n fn,\n lower: bracket.lower,\n upper: bracket.upper,\n tolerance,\n maxIterations: maxIterations * 2,\n });\n if (bisected !== undefined) return bisected;\n\n throw new RangeError(\"RATE did not converge\");\n}\n\nfunction ratePerPeriodIsInvalidForDomain(ratePerPeriod: number): boolean {\n return ratePerPeriod <= -1;\n}\n\nfunction findRateBracket(\n fn: (x: number) => number,\n lowerBound: number,\n upperBound: number,\n): { lower: number; upper: number } | undefined {\n const scan = (\n start: number,\n end: number,\n segments = 200,\n ): { lower: number; upper: number } | undefined => {\n let prevX: number | undefined;\n let prevValue: number | undefined;\n for (let i = 0; i <= segments; i++) {\n const x = start + ((end - start) * i) / segments;\n const value = fn(x);\n if (!Number.isFinite(value)) continue;\n if (value === 0) return { lower: x, upper: x };\n if (prevValue !== undefined && prevX !== undefined && prevValue * value < 0) {\n return { lower: prevX, upper: x };\n }\n prevX = x;\n prevValue = value;\n }\n return undefined;\n };\n\n let lower = lowerBound;\n let upper = upperBound;\n for (let i = 0; i < 20; i++) {\n const bracket = scan(lower, upper);\n if (bracket !== undefined) return bracket;\n lower = Math.max(-0.999999999, (lower - 1) / 2);\n upper = upper * 2 + 1;\n }\n\n return scan(lower, upper, 400);\n}\n","import { assertFiniteNumber, assertNonNegative, assertPositive } from \"../utils/assertions.js\";\n\nexport type LoanPaymentParams = {\n principal: number;\n annualRate: number;\n paymentsPerYear: number;\n years: number;\n};\n\n/**\n * Fixed periodic payment for an amortizing loan.\n *\n * - `annualRate` is nominal annual rate (e.g. 0.06 for 6%)\n * - payment returned is per period (`paymentsPerYear`)\n */\nexport function loanPayment(params: LoanPaymentParams): number {\n const { principal, annualRate, paymentsPerYear, years } = params;\n assertNonNegative(principal, \"principal\");\n assertFiniteNumber(annualRate, \"annualRate\");\n assertPositive(paymentsPerYear, \"paymentsPerYear\");\n assertNonNegative(years, \"years\");\n\n const n = Math.round(paymentsPerYear * years);\n if (n === 0) return 0;\n\n const r = annualRate / paymentsPerYear;\n if (r <= -1) {\n throw new RangeError(\"annualRate / paymentsPerYear must be > -1\");\n }\n if (r === 0) return principal / n;\n\n const value = (r * principal) / (1 - (1 + r) ** -n);\n if (!Number.isFinite(value)) {\n throw new RangeError(\"Numerical instability for given inputs\");\n }\n return value;\n}\n","import { assertNonNegative, assertPositive } from \"../utils/assertions.js\";\nimport { loanPayment } from \"./loanPayment.js\";\n\nexport type AmortizationScheduleParams = {\n principal: number;\n annualRate: number;\n paymentsPerYear: number;\n years: number;\n extraPaymentPerPeriod?: number;\n};\n\nexport type AmortizationRow = {\n period: number;\n payment: number;\n principalPayment: number;\n interestPayment: number;\n balance: number;\n};\n\nexport type AmortizationScheduleResult = {\n paymentPerPeriod: number;\n schedule: AmortizationRow[];\n totalPaid: number;\n totalInterest: number;\n};\n\nexport function amortizationSchedule(\n params: AmortizationScheduleParams,\n): AmortizationScheduleResult {\n const { principal, annualRate, paymentsPerYear, years, extraPaymentPerPeriod = 0 } = params;\n assertNonNegative(principal, \"principal\");\n assertPositive(paymentsPerYear, \"paymentsPerYear\");\n assertNonNegative(years, \"years\");\n assertNonNegative(extraPaymentPerPeriod, \"extraPaymentPerPeriod\");\n\n const scheduledN = Math.round(paymentsPerYear * years);\n if (scheduledN === 0 || principal === 0) {\n return { paymentPerPeriod: 0, schedule: [], totalPaid: 0, totalInterest: 0 };\n }\n\n const basePayment = loanPayment({ principal, annualRate, paymentsPerYear, years });\n const r = annualRate / paymentsPerYear;\n\n const schedule: AmortizationRow[] = [];\n let balance = principal;\n let totalPaid = 0;\n let totalInterest = 0;\n\n for (let period = 1; period <= scheduledN && balance > 0; period++) {\n const interestPayment = r === 0 ? 0 : balance * r;\n let payment = basePayment + extraPaymentPerPeriod;\n let principalPayment = payment - interestPayment;\n\n if (principalPayment > balance) {\n principalPayment = balance;\n payment = principalPayment + interestPayment;\n }\n\n balance = balance - principalPayment;\n if (Math.abs(balance) < 1e-12) balance = 0;\n\n totalPaid += payment;\n totalInterest += interestPayment;\n\n schedule.push({\n period,\n payment,\n principalPayment,\n interestPayment,\n balance,\n });\n }\n\n return {\n paymentPerPeriod: basePayment,\n schedule,\n totalPaid,\n totalInterest,\n };\n}\n","import { assertFiniteNumber, assertNonNegative, assertPositive } from \"../utils/assertions.js\";\n\nexport type PayoffPeriodWithExtraParams = {\n principal: number;\n annualRate: number;\n paymentsPerYear: number;\n basePaymentPerPeriod: number;\n extraPaymentPerPeriod: number;\n};\n\n/**\n * Number of periods until the loan is paid off with the given base + extra payment.\n */\nexport function payoffPeriodWithExtra(params: PayoffPeriodWithExtraParams): number {\n const { principal, annualRate, paymentsPerYear, basePaymentPerPeriod, extraPaymentPerPeriod } =\n params;\n\n assertNonNegative(principal, \"principal\");\n assertFiniteNumber(annualRate, \"annualRate\");\n assertPositive(paymentsPerYear, \"paymentsPerYear\");\n assertNonNegative(basePaymentPerPeriod, \"basePaymentPerPeriod\");\n assertNonNegative(extraPaymentPerPeriod, \"extraPaymentPerPeriod\");\n\n if (principal <= 0) return 0;\n const payment = basePaymentPerPeriod + extraPaymentPerPeriod;\n if (payment <= 0) return Number.POSITIVE_INFINITY;\n\n const r = annualRate / paymentsPerYear;\n let balance = principal;\n let period = 0;\n\n while (balance > 1e-12 && period < 100000) {\n const interest = r > 0 ? balance * r : 0;\n if (payment <= interest) return Number.POSITIVE_INFINITY;\n const principalPaid = Math.min(payment - interest, balance);\n balance -= principalPaid;\n period++;\n }\n return balance <= 1e-12 ? period : Number.POSITIVE_INFINITY;\n}\n","import { assertNonNegative, assertPositive } from \"../utils/assertions.js\";\nimport { loanPayment } from \"./loanPayment.js\";\n\nexport type RemainingBalanceParams = {\n principal: number;\n annualRate: number;\n paymentsPerYear: number;\n years: number;\n afterPeriodNumber: number;\n};\n\n/**\n * Remaining balance after a given number of payments on an amortizing loan.\n */\nexport function remainingBalance(params: RemainingBalanceParams): number {\n const { principal, annualRate, paymentsPerYear, years, afterPeriodNumber } = params;\n assertNonNegative(principal, \"principal\");\n assertPositive(paymentsPerYear, \"paymentsPerYear\");\n assertNonNegative(years, \"years\");\n assertNonNegative(afterPeriodNumber, \"afterPeriodNumber\");\n\n const n = Math.round(paymentsPerYear * years);\n if (n === 0 || afterPeriodNumber >= n) return 0;\n if (afterPeriodNumber <= 0) return principal;\n\n const payment = loanPayment({ principal, annualRate, paymentsPerYear, years });\n const r = annualRate / paymentsPerYear;\n const k = afterPeriodNumber;\n\n if (r === 0) return Math.max(0, principal - payment * k);\n const balance = principal * (1 + r) ** k - payment * (((1 + r) ** k - 1) / r);\n return Math.max(0, balance);\n}\n","import { assertFiniteNumber } from \"./assertions.js\";\n\nexport type RoundToCurrencyParams = {\n value: number;\n /** Decimal places. Default 2. */\n decimals?: number;\n /** 'half-up': 0.5 rounds up. 'half-even': banker's rounding. Default 'half-up'. */\n mode?: \"half-up\" | \"half-even\";\n};\n\n/**\n * Rounds a number to currency (default 2 decimals). half-up: 2.125 -> 2.13. half-even: 2.125 -> 2.12.\n */\nexport function roundToCurrency(params: RoundToCurrencyParams): number {\n const { value, decimals = 2, mode = \"half-up\" } = params;\n assertFiniteNumber(value, \"value\");\n const d = Math.max(0, Math.floor(decimals));\n const factor = 10 ** d;\n if (mode === \"half-even\") {\n const scaled = value * factor;\n const sign = scaled < 0 ? -1 : 1;\n const absScaled = Math.abs(scaled);\n const floorAbs = Math.floor(absScaled);\n const fraction = absScaled - floorAbs;\n const epsilon = 1e-12;\n if (Math.abs(fraction - 0.5) <= epsilon) {\n const nearestEven = floorAbs % 2 === 0 ? floorAbs : floorAbs + 1;\n return (sign * nearestEven) / factor;\n }\n return Math.round(scaled) / factor;\n }\n return Math.round(value * factor) / factor;\n}\n"]}
|
package/dist/index.js
CHANGED
|
@@ -299,6 +299,11 @@ function paymentFromPresentValue(params) {
|
|
|
299
299
|
}
|
|
300
300
|
|
|
301
301
|
// src/interest/periodsToReachGoal.ts
|
|
302
|
+
function assertContributionTiming(value, name) {
|
|
303
|
+
if (value !== "end" && value !== "begin") {
|
|
304
|
+
throw new RangeError(`${name} must be "end" or "begin"`);
|
|
305
|
+
}
|
|
306
|
+
}
|
|
302
307
|
function periodsToReachGoal(params) {
|
|
303
308
|
const {
|
|
304
309
|
principal,
|
|
@@ -315,6 +320,7 @@ function periodsToReachGoal(params) {
|
|
|
315
320
|
assertPositive(timesPerYear, "timesPerYear");
|
|
316
321
|
assertNonNegative(contributionPerPeriod, "contributionPerPeriod");
|
|
317
322
|
assertPositive(maxPeriods, "maxPeriods");
|
|
323
|
+
assertContributionTiming(contributionTiming, "contributionTiming");
|
|
318
324
|
if (targetFutureValue <= principal) return 0;
|
|
319
325
|
const r = rate2 / timesPerYear;
|
|
320
326
|
if (r <= -1) {
|
|
@@ -370,6 +376,11 @@ function presentValueOfAnnuity(params) {
|
|
|
370
376
|
}
|
|
371
377
|
|
|
372
378
|
// src/interest/rateToReachGoal.ts
|
|
379
|
+
function assertContributionTiming2(value, name) {
|
|
380
|
+
if (value !== "end" && value !== "begin") {
|
|
381
|
+
throw new RangeError(`${name} must be "end" or "begin"`);
|
|
382
|
+
}
|
|
383
|
+
}
|
|
373
384
|
function rateToReachGoal(params) {
|
|
374
385
|
const {
|
|
375
386
|
principal,
|
|
@@ -390,13 +401,13 @@ function rateToReachGoal(params) {
|
|
|
390
401
|
assertFiniteNumber(upperBound, "upperBound");
|
|
391
402
|
assertFiniteNumber(maxIterations, "maxIterations");
|
|
392
403
|
assertFiniteNumber(tolerance, "tolerance");
|
|
404
|
+
assertContributionTiming2(contributionTiming, "contributionTiming");
|
|
393
405
|
if (lowerBound <= -1) throw new RangeError("lowerBound must be > -1");
|
|
394
406
|
if (upperBound <= lowerBound) throw new RangeError("upperBound must be greater than lowerBound");
|
|
395
407
|
if (!Number.isInteger(maxIterations) || maxIterations <= 0) {
|
|
396
408
|
throw new RangeError("maxIterations must be a positive integer");
|
|
397
409
|
}
|
|
398
410
|
if (tolerance <= 0) throw new RangeError("tolerance must be > 0");
|
|
399
|
-
if (periods === 0) return 0;
|
|
400
411
|
if (targetFutureValue <= principal && contributionPerPeriod === 0) return 0;
|
|
401
412
|
if (contributionPerPeriod === 0) {
|
|
402
413
|
if (targetFutureValue <= principal) return 0;
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/utils/assertions.ts","../src/interest/cagr.ts","../src/interest/compound.ts","../src/interest/effectiveAnnualRate.ts","../src/interest/futureValue.ts","../src/interest/inflationAdjustedAmount.ts","../src/interest/investmentGrowth.ts","../src/utils/solvers.ts","../src/interest/irr.ts","../src/interest/npv.ts","../src/interest/paymentFromPresentValue.ts","../src/interest/periodsToReachGoal.ts","../src/interest/presentValue.ts","../src/interest/presentValueOfAnnuity.ts","../src/interest/rateToReachGoal.ts","../src/interest/realReturn.ts","../src/interest/ruleOf72.ts","../src/interest/tvom.ts","../src/loans/loanPayment.ts","../src/loans/amortizationSchedule.ts","../src/loans/payoffPeriodWithExtra.ts","../src/loans/remainingBalance.ts","../src/utils/roundToCurrency.ts"],"names":["rate","presentValue","futureValue","pmt","fv","pv","findBracket"],"mappings":";AAAO,SAAS,kBAAA,CAAmB,OAAe,IAAA,EAAoB;AACpE,EAAA,IAAI,CAAC,MAAA,CAAO,QAAA,CAAS,KAAK,CAAA,EAAG;AAC3B,IAAA,MAAM,IAAI,UAAA,CAAW,CAAA,EAAG,IAAI,CAAA,wBAAA,CAA0B,CAAA;AAAA,EACxD;AACF;AAEO,SAAS,iBAAA,CAAkB,OAAe,IAAA,EAAoB;AACnE,EAAA,kBAAA,CAAmB,OAAO,IAAI,CAAA;AAC9B,EAAA,IAAI,QAAQ,CAAA,EAAG;AACb,IAAA,MAAM,IAAI,UAAA,CAAW,CAAA,EAAG,IAAI,CAAA,aAAA,CAAe,CAAA;AAAA,EAC7C;AACF;AAEO,SAAS,cAAA,CAAe,OAAe,IAAA,EAAoB;AAChE,EAAA,kBAAA,CAAmB,OAAO,IAAI,CAAA;AAC9B,EAAA,IAAI,SAAS,CAAA,EAAG;AACd,IAAA,MAAM,IAAI,UAAA,CAAW,CAAA,EAAG,IAAI,CAAA,YAAA,CAAc,CAAA;AAAA,EAC5C;AACF;;;ACNO,SAAS,KAAK,MAAA,EAA4B;AAC/C,EAAA,MAAM,EAAE,UAAA,EAAY,QAAA,EAAU,KAAA,EAAM,GAAI,MAAA;AACxC,EAAA,cAAA,CAAe,YAAY,YAAY,CAAA;AACvC,EAAA,cAAA,CAAe,OAAO,OAAO,CAAA;AAC7B,EAAA,IAAI,QAAA,IAAY,GAAG,OAAO,EAAA;AAC1B,EAAA,OAAA,CAAQ,QAAA,GAAW,UAAA,MAAgB,CAAA,GAAI,KAAA,CAAA,GAAS,CAAA;AAClD;;;ACLO,SAAS,SAAS,MAAA,EAAgC;AACvD,EAAA,MAAM,EAAE,SAAA,EAAW,IAAA,EAAAA,KAAAA,EAAM,YAAA,EAAc,OAAM,GAAI,MAAA;AACjD,EAAA,iBAAA,CAAkB,WAAW,WAAW,CAAA;AACxC,EAAA,cAAA,CAAe,cAAc,cAAc,CAAA;AAC3C,EAAA,iBAAA,CAAkB,OAAO,OAAO,CAAA;AAEhC,EAAA,IAAIA,KAAAA,KAAS,CAAA,IAAK,KAAA,KAAU,CAAA,EAAG,OAAO,SAAA;AAEtC,EAAA,MAAM,CAAA,GAAI,YAAA;AACV,EAAA,MAAM,CAAA,GAAI,KAAA;AACV,EAAA,OAAO,SAAA,GAAA,CAAa,CAAA,GAAIA,KAAAA,GAAO,CAAA,MAAO,CAAA,GAAI,CAAA,CAAA;AAC5C;;;ACbO,SAAS,oBAAoB,MAAA,EAA2C;AAC7E,EAAA,MAAM,EAAE,WAAA,EAAa,YAAA,EAAa,GAAI,MAAA;AACtC,EAAA,kBAAA,CAAmB,aAAa,aAAa,CAAA;AAC7C,EAAA,cAAA,CAAe,cAAc,cAAc,CAAA;AAE3C,EAAA,MAAM,IAAI,WAAA,GAAc,YAAA;AACxB,EAAA,OAAA,CAAQ,CAAA,GAAI,MAAM,YAAA,GAAe,CAAA;AACnC;;;ACNO,SAAS,YAAY,MAAA,EAAmC;AAC7D,EAAA,MAAM,EAAE,YAAA,EAAAC,aAAAA,EAAc,MAAAD,KAAAA,EAAM,YAAA,EAAc,OAAM,GAAI,MAAA;AACpD,EAAA,iBAAA,CAAkBC,eAAc,cAAc,CAAA;AAC9C,EAAA,cAAA,CAAe,cAAc,cAAc,CAAA;AAC3C,EAAA,iBAAA,CAAkB,OAAO,OAAO,CAAA;AAEhC,EAAA,IAAID,KAAAA,KAAS,CAAA,IAAK,KAAA,KAAU,CAAA,EAAG,OAAOC,aAAAA;AAEtC,EAAA,MAAM,CAAA,GAAI,YAAA;AACV,EAAA,MAAM,CAAA,GAAI,KAAA;AACV,EAAA,OAAOA,aAAAA,GAAAA,CAAgB,CAAA,GAAID,KAAAA,GAAO,CAAA,MAAO,CAAA,GAAI,CAAA,CAAA;AAC/C;;;ACXO,SAAS,wBAAwB,MAAA,EAA+C;AACrF,EAAA,MAAM,EAAE,MAAA,EAAQ,mBAAA,EAAqB,KAAA,EAAO,WAAU,GAAI,MAAA;AAC1D,EAAA,kBAAA,CAAmB,QAAQ,QAAQ,CAAA;AACnC,EAAA,kBAAA,CAAmB,qBAAqB,qBAAqB,CAAA;AAC7D,EAAA,iBAAA,CAAkB,OAAO,OAAO,CAAA;AAChC,EAAA,MAAM,MAAA,GAAA,CAAU,IAAI,mBAAA,KAAwB,KAAA;AAC5C,EAAA,OAAO,SAAA,KAAc,QAAA,GAAW,MAAA,GAAS,MAAA,GAAS,MAAA,GAAS,MAAA;AAC7D;;;ACIO,SAAS,iBAAiB,MAAA,EAAwD;AACvF,EAAA,MAAM;AAAA,IACJ,OAAA;AAAA,IACA,qBAAA,GAAwB,CAAA;AAAA,IACxB,IAAA,EAAAA,KAAAA;AAAA,IACA,YAAA;AAAA,IACA,KAAA;AAAA,IACA,kBAAA,GAAqB;AAAA,GACvB,GAAI,MAAA;AAEJ,EAAA,iBAAA,CAAkB,SAAS,SAAS,CAAA;AACpC,EAAA,iBAAA,CAAkB,uBAAuB,uBAAuB,CAAA;AAChE,EAAA,cAAA,CAAe,cAAc,cAAc,CAAA;AAC3C,EAAA,iBAAA,CAAkB,OAAO,OAAO,CAAA;AAEhC,EAAA,MAAM,OAAA,GAAU,IAAA,CAAK,KAAA,CAAM,YAAA,GAAe,KAAK,CAAA;AAC/C,EAAA,IAAI,YAAY,CAAA,EAAG;AACjB,IAAA,OAAO;AAAA,MACL,WAAA,EAAa,OAAA;AAAA,MACb,kBAAA,EAAoB,CAAA;AAAA,MACpB,aAAA,EAAe;AAAA,KACjB;AAAA,EACF;AAEA,EAAA,MAAM,IAAIA,KAAAA,GAAO,YAAA;AAGjB,EAAA,MAAM,YAAYA,KAAAA,KAAS,CAAA,GAAI,OAAA,GAAU,OAAA,GAAA,CAAW,IAAI,CAAA,KAAM,OAAA;AAG9D,EAAA,IAAI,SAAA,GAAY,CAAA;AAChB,EAAA,IAAI,0BAA0B,CAAA,EAAG;AAC/B,IAAA,IAAIA,UAAS,CAAA,EAAG;AACd,MAAA,SAAA,GAAY,qBAAA,GAAwB,OAAA;AAAA,IACtC,CAAA,MAAO;AACL,MAAA,MAAM,QAAA,GAAW,qBAAA,IAAA,CAAA,CAA2B,CAAA,GAAI,CAAA,KAAM,UAAU,CAAA,IAAK,CAAA,CAAA;AACrE,MAAA,SAAA,GAAY,kBAAA,KAAuB,OAAA,GAAU,QAAA,IAAY,CAAA,GAAI,CAAA,CAAA,GAAK,QAAA;AAAA,IACpE;AAAA,EACF;AAEA,EAAA,MAAME,eAAc,SAAA,GAAY,SAAA;AAChC,EAAA,MAAM,qBAAqB,qBAAA,GAAwB,OAAA;AACnD,EAAA,MAAM,aAAA,GAAgBA,eAAc,OAAA,GAAU,kBAAA;AAE9C,EAAA,OAAO,EAAE,WAAA,EAAAA,YAAAA,EAAa,kBAAA,EAAoB,aAAA,EAAc;AAC1D;;;AC1DO,SAAS,cAAc,MAAA,EAAiD;AAC7E,EAAA,MAAM;AAAA,IACJ,YAAA;AAAA,IACA,EAAA;AAAA,IACA,UAAA;AAAA,IACA,SAAA,GAAY,KAAA;AAAA,IACZ,aAAA,GAAgB,GAAA;AAAA,IAChB,MAAM,MAAA,CAAO,iBAAA;AAAA,IACb,MAAM,MAAA,CAAO;AAAA,GACf,GAAI,MAAA;AAEJ,EAAA,IAAI,CAAA,GAAI,YAAA;AACR,EAAA,KAAA,IAAS,CAAA,GAAI,CAAA,EAAG,CAAA,GAAI,aAAA,EAAe,CAAA,EAAA,EAAK;AACtC,IAAA,MAAM,KAAA,GAAQ,GAAG,CAAC,CAAA;AAClB,IAAA,IAAI,CAAC,MAAA,CAAO,QAAA,CAAS,KAAK,GAAG,OAAO,MAAA;AACpC,IAAA,IAAI,IAAA,CAAK,GAAA,CAAI,KAAK,CAAA,IAAK,WAAW,OAAO,CAAA;AAEzC,IAAA,MAAM,KAAA,GAAQ,WAAW,CAAC,CAAA;AAC1B,IAAA,IAAI,CAAC,MAAA,CAAO,QAAA,CAAS,KAAK,CAAA,IAAK,KAAK,GAAA,CAAI,KAAK,CAAA,GAAI,KAAA,EAAO,OAAO,MAAA;AAE/D,IAAA,CAAA,IAAK,KAAA,GAAQ,KAAA;AACb,IAAA,IAAI,CAAA,GAAI,KAAK,CAAA,GAAI,GAAA;AACjB,IAAA,IAAI,CAAA,GAAI,KAAK,CAAA,GAAI,GAAA;AAAA,EACnB;AAEA,EAAA,OAAO,MAAA;AACT;AAUO,SAAS,UAAU,MAAA,EAA6C;AACrE,EAAA,MAAM,EAAE,IAAI,KAAA,EAAO,KAAA,EAAO,YAAY,KAAA,EAAO,aAAA,GAAgB,KAAI,GAAI,MAAA;AACrE,EAAA,IAAI,CAAA,GAAI,KAAA;AACR,EAAA,IAAI,CAAA,GAAI,KAAA;AACR,EAAA,IAAI,EAAA,GAAK,GAAG,CAAC,CAAA;AACb,EAAA,IAAI,EAAA,GAAK,GAAG,CAAC,CAAA;AAEb,EAAA,IAAI,CAAC,MAAA,CAAO,QAAA,CAAS,EAAE,CAAA,IAAK,CAAC,MAAA,CAAO,QAAA,CAAS,EAAE,CAAA,IAAK,EAAA,GAAK,EAAA,GAAK,GAAG,OAAO,MAAA;AACxE,EAAA,IAAI,IAAA,CAAK,GAAA,CAAI,EAAE,CAAA,IAAK,WAAW,OAAO,CAAA;AACtC,EAAA,IAAI,IAAA,CAAK,GAAA,CAAI,EAAE,CAAA,IAAK,WAAW,OAAO,CAAA;AAEtC,EAAA,KAAA,IAAS,CAAA,GAAI,CAAA,EAAG,CAAA,GAAI,aAAA,EAAe,CAAA,EAAA,EAAK;AACtC,IAAA,MAAM,CAAA,GAAA,CAAK,IAAI,CAAA,IAAK,CAAA;AACpB,IAAA,MAAM,EAAA,GAAK,GAAG,CAAC,CAAA;AACf,IAAA,IAAI,CAAC,MAAA,CAAO,QAAA,CAAS,EAAE,GAAG,OAAO,MAAA;AACjC,IAAA,IAAI,IAAA,CAAK,GAAA,CAAI,EAAE,CAAA,IAAK,SAAA,IAAa,IAAA,CAAK,GAAA,CAAI,CAAA,GAAI,CAAC,CAAA,IAAK,SAAA,EAAW,OAAO,CAAA;AAEtE,IAAA,IAAI,EAAA,GAAK,KAAK,CAAA,EAAG;AACf,MAAA,CAAA,GAAI,CAAA;AACJ,MAAA,EAAA,GAAK,EAAA;AAAA,IACP,CAAA,MAAO;AACL,MAAA,CAAA,GAAI,CAAA;AACJ,MAAA,EAAA,GAAK,EAAA;AAAA,IACP;AAAA,EACF;AAEA,EAAA,OAAA,CAAQ,IAAI,CAAA,IAAK,CAAA;AACnB;;;AC9DA,SAAS,KAAA,CAAMF,OAAc,SAAA,EAA6B;AACxD,EAAA,IAAI,GAAA,GAAM,CAAA;AACV,EAAA,KAAA,IAAS,CAAA,GAAI,CAAA,EAAG,CAAA,GAAI,SAAA,CAAU,QAAQ,CAAA,EAAA,EAAK;AACzC,IAAA,MAAM,EAAA,GAAK,UAAU,CAAC,CAAA;AACtB,IAAA,IAAI,EAAA,KAAO,MAAA,EAAW,GAAA,IAAO,EAAA,GAAA,CAAM,IAAIA,KAAAA,KAAS,CAAA;AAAA,EAClD;AACA,EAAA,OAAO,GAAA;AACT;AAEA,SAAS,eAAA,CAAgBA,OAAc,SAAA,EAA6B;AAClE,EAAA,IAAI,GAAA,GAAM,CAAA;AACV,EAAA,KAAA,IAAS,CAAA,GAAI,CAAA,EAAG,CAAA,GAAI,SAAA,CAAU,QAAQ,CAAA,EAAA,EAAK;AACzC,IAAA,MAAM,EAAA,GAAK,UAAU,CAAC,CAAA;AACtB,IAAA,IAAI,OAAO,MAAA,EAAW,GAAA,IAAQ,IAAI,EAAA,GAAA,CAAO,CAAA,GAAIA,WAAU,CAAA,GAAI,CAAA,CAAA;AAAA,EAC7D;AACA,EAAA,OAAO,GAAA;AACT;AAEA,SAAS,uBAAuB,SAAA,EAA8B;AAC5D,EAAA,IAAI,WAAA,GAAc,KAAA;AAClB,EAAA,IAAI,WAAA,GAAc,KAAA;AAClB,EAAA,KAAA,MAAW,MAAM,SAAA,EAAW;AAC1B,IAAA,IAAI,EAAA,GAAK,GAAG,WAAA,GAAc,IAAA;AAC1B,IAAA,IAAI,EAAA,GAAK,GAAG,WAAA,GAAc,IAAA;AAC1B,IAAA,IAAI,WAAA,IAAe,aAAa,OAAO,IAAA;AAAA,EACzC;AACA,EAAA,OAAO,KAAA;AACT;AAEA,SAAS,WAAA,CACP,EAAA,EACA,UAAA,EACA,UAAA,EAC8C;AAC9C,EAAA,MAAM,IAAA,GAAO,CACX,KAAA,EACA,GAAA,EACA,WAAW,GAAA,KACsC;AACjD,IAAA,IAAI,KAAA;AACJ,IAAA,IAAI,SAAA;AACJ,IAAA,KAAA,IAAS,CAAA,GAAI,CAAA,EAAG,CAAA,IAAK,QAAA,EAAU,CAAA,EAAA,EAAK;AAClC,MAAA,MAAM,CAAA,GAAI,KAAA,GAAA,CAAU,GAAA,GAAM,KAAA,IAAS,CAAA,GAAK,QAAA;AACxC,MAAA,MAAM,KAAA,GAAQ,GAAG,CAAC,CAAA;AAClB,MAAA,IAAI,CAAC,MAAA,CAAO,QAAA,CAAS,KAAK,CAAA,EAAG;AAC7B,MAAA,IAAI,UAAU,CAAA,EAAG,OAAO,EAAE,KAAA,EAAO,CAAA,EAAG,OAAO,CAAA,EAAE;AAC7C,MAAA,IAAI,UAAU,MAAA,IAAa,SAAA,KAAc,MAAA,IAAa,SAAA,GAAY,QAAQ,CAAA,EAAG;AAC3E,QAAA,OAAO,EAAE,KAAA,EAAO,KAAA,EAAO,KAAA,EAAO,CAAA,EAAE;AAAA,MAClC;AACA,MAAA,KAAA,GAAQ,CAAA;AACR,MAAA,SAAA,GAAY,KAAA;AAAA,IACd;AACA,IAAA,OAAO,MAAA;AAAA,EACT,CAAA;AAEA,EAAA,IAAI,KAAA,GAAQ,UAAA;AACZ,EAAA,IAAI,KAAA,GAAQ,UAAA;AACZ,EAAA,KAAA,IAAS,CAAA,GAAI,CAAA,EAAG,CAAA,GAAI,EAAA,EAAI,CAAA,EAAA,EAAK;AAC3B,IAAA,MAAM,OAAA,GAAU,IAAA,CAAK,KAAA,EAAO,KAAK,CAAA;AACjC,IAAA,IAAI,OAAA,KAAY,QAAW,OAAO,OAAA;AAClC,IAAA,KAAA,GAAQ,IAAA,CAAK,GAAA,CAAI,YAAA,EAAA,CAAe,KAAA,GAAQ,KAAK,CAAC,CAAA;AAC9C,IAAA,KAAA,GAAQ,QAAQ,CAAA,GAAI,CAAA;AAAA,EACtB;AAEA,EAAA,OAAO,IAAA,CAAK,KAAA,EAAO,KAAA,EAAO,GAAG,CAAA;AAC/B;AAEO,SAAS,IAAI,MAAA,EAA2B;AAC7C,EAAA,MAAM;AAAA,IACJ,SAAA;AAAA,IACA,KAAA,GAAQ,GAAA;AAAA,IACR,aAAA,GAAgB,GAAA;AAAA,IAChB,UAAA,GAAa,KAAA;AAAA,IACb,UAAA,GAAa;AAAA,GACf,GAAI,MAAA;AACJ,EAAA,IAAI,SAAA,CAAU,WAAW,CAAA,EAAG;AAC1B,IAAA,MAAM,IAAI,WAAW,2CAA2C,CAAA;AAAA,EAClE;AACA,EAAA,kBAAA,CAAmB,OAAO,OAAO,CAAA;AACjC,EAAA,kBAAA,CAAmB,eAAe,eAAe,CAAA;AACjD,EAAA,kBAAA,CAAmB,YAAY,YAAY,CAAA;AAC3C,EAAA,kBAAA,CAAmB,YAAY,YAAY,CAAA;AAC3C,EAAA,IAAI,iBAAiB,CAAA,IAAK,CAAC,MAAA,CAAO,SAAA,CAAU,aAAa,CAAA,EAAG;AAC1D,IAAA,MAAM,IAAI,WAAW,0CAA0C,CAAA;AAAA,EACjE;AACA,EAAA,IAAI,cAAc,EAAA,EAAI;AACpB,IAAA,MAAM,IAAI,WAAW,yBAAyB,CAAA;AAAA,EAChD;AACA,EAAA,IAAI,cAAc,UAAA,EAAY;AAC5B,IAAA,MAAM,IAAI,WAAW,4CAA4C,CAAA;AAAA,EACnE;AAEA,EAAA,KAAA,MAAW,EAAA,IAAM,SAAA,EAAW,kBAAA,CAAmB,EAAA,EAAI,aAAa,CAAA;AAChE,EAAA,IAAI,CAAC,sBAAA,CAAuB,SAAS,CAAA,EAAG;AACtC,IAAA,MAAM,IAAI,WAAW,qEAAqE,CAAA;AAAA,EAC5F;AAEA,EAAA,MAAM,EAAA,GAAK,CAACA,KAAAA,KAAiB,KAAA,CAAMA,OAAM,SAAS,CAAA;AAClD,EAAA,MAAM,UAAA,GAAa,CAACA,KAAAA,KAAiB,eAAA,CAAgBA,OAAM,SAAS,CAAA;AAEpE,EAAA,MAAM,SAAS,aAAA,CAAc;AAAA,IAC3B,YAAA,EAAc,KAAA;AAAA,IACd,EAAA;AAAA,IACA,UAAA;AAAA,IACA,SAAA,EAAW,KAAA;AAAA,IACX,aAAA;AAAA,IACA,GAAA,EAAK,UAAA;AAAA,IACL,GAAA,EAAK;AAAA,GACN,CAAA;AACD,EAAA,IAAI,MAAA,KAAW,QAAW,OAAO,MAAA;AAEjC,EAAA,MAAM,OAAA,GAAU,WAAA,CAAY,EAAA,EAAI,UAAA,EAAY,UAAU,CAAA;AACtD,EAAA,IAAI,YAAY,MAAA,EAAW;AACzB,IAAA,MAAM,IAAI,WAAW,2CAA2C,CAAA;AAAA,EAClE;AACA,EAAA,IAAI,OAAA,CAAQ,KAAA,KAAU,OAAA,CAAQ,KAAA,SAAc,OAAA,CAAQ,KAAA;AAEpD,EAAA,MAAM,WAAW,SAAA,CAAU;AAAA,IACzB,EAAA;AAAA,IACA,OAAO,OAAA,CAAQ,KAAA;AAAA,IACf,OAAO,OAAA,CAAQ,KAAA;AAAA,IACf,SAAA,EAAW,KAAA;AAAA,IACX,eAAe,aAAA,GAAgB;AAAA,GAChC,CAAA;AACD,EAAA,IAAI,QAAA,KAAa,QAAW,OAAO,QAAA;AAEnC,EAAA,MAAM,IAAI,WAAW,sBAAsB,CAAA;AAC7C;;;AC/HO,SAAS,IAAI,MAAA,EAA2B;AAC7C,EAAA,MAAM,EAAE,IAAA,EAAAA,KAAAA,EAAM,SAAA,EAAU,GAAI,MAAA;AAC5B,EAAA,kBAAA,CAAmBA,OAAM,MAAM,CAAA;AAC/B,EAAA,IAAIA,KAAAA,IAAQ,EAAA,EAAI,MAAM,IAAI,WAAW,mBAAmB,CAAA;AACxD,EAAA,IAAI,SAAA,CAAU,MAAA,KAAW,CAAA,EAAG,OAAO,CAAA;AAEnC,EAAA,IAAI,GAAA,GAAM,CAAA;AACV,EAAA,KAAA,IAAS,CAAA,GAAI,CAAA,EAAG,CAAA,GAAI,SAAA,CAAU,QAAQ,CAAA,EAAA,EAAK;AACzC,IAAA,MAAM,EAAA,GAAK,UAAU,CAAC,CAAA;AACtB,IAAA,IAAI,OAAO,MAAA,EAAW;AACtB,IAAA,kBAAA,CAAmB,EAAA,EAAI,CAAA,UAAA,EAAa,CAAC,CAAA,CAAA,CAAG,CAAA;AACxC,IAAA,GAAA,IAAO,EAAA,GAAA,CAAM,IAAIA,KAAAA,KAAS,CAAA;AAAA,EAC5B;AACA,EAAA,OAAO,GAAA;AACT;;;ACXO,SAAS,wBAAwB,MAAA,EAA+C;AACrF,EAAA,MAAM,EAAE,YAAA,EAAAC,aAAAA,EAAc,eAAe,OAAA,EAAS,MAAA,GAAS,OAAM,GAAI,MAAA;AACjE,EAAA,iBAAA,CAAkBA,eAAc,cAAc,CAAA;AAC9C,EAAA,iBAAA,CAAkB,SAAS,SAAS,CAAA;AAEpC,EAAA,IAAIA,aAAAA,KAAiB,CAAA,IAAK,OAAA,KAAY,CAAA,EAAG,OAAO,CAAA;AAChD,EAAA,IAAI,kBAAkB,CAAA,EAAG;AACvB,IAAA,MAAME,OAAMF,aAAAA,GAAe,OAAA;AAC3B,IAAA,OAAO,MAAA,KAAW,OAAA,GAAUE,IAAAA,IAAO,CAAA,GAAI,aAAA,CAAA,GAAiBA,IAAAA;AAAA,EAC1D;AACA,EAAA,IAAIA,OAAO,aAAA,GAAgBF,aAAAA,IAAiB,CAAA,GAAA,CAAK,CAAA,GAAI,kBAAkB,CAAC,OAAA,CAAA;AACxE,EAAA,IAAI,MAAA,KAAW,OAAA,EAASE,IAAAA,IAAO,CAAA,GAAI,aAAA;AACnC,EAAA,OAAOA,IAAAA;AACT;;;ACXO,SAAS,mBAAmB,MAAA,EAA0C;AAC3E,EAAA,MAAM;AAAA,IACJ,SAAA;AAAA,IACA,iBAAA;AAAA,IACA,IAAA,EAAAH,KAAAA;AAAA,IACA,YAAA;AAAA,IACA,qBAAA,GAAwB,CAAA;AAAA,IACxB,kBAAA,GAAqB,KAAA;AAAA,IACrB,UAAA,GAAa;AAAA,GACf,GAAI,MAAA;AAEJ,EAAA,iBAAA,CAAkB,WAAW,WAAW,CAAA;AACxC,EAAA,iBAAA,CAAkB,mBAAmB,mBAAmB,CAAA;AACxD,EAAA,kBAAA,CAAmBA,OAAM,MAAM,CAAA;AAC/B,EAAA,cAAA,CAAe,cAAc,cAAc,CAAA;AAC3C,EAAA,iBAAA,CAAkB,uBAAuB,uBAAuB,CAAA;AAChE,EAAA,cAAA,CAAe,YAAY,YAAY,CAAA;AAEvC,EAAA,IAAI,iBAAA,IAAqB,WAAW,OAAO,CAAA;AAE3C,EAAA,MAAM,IAAIA,KAAAA,GAAO,YAAA;AACjB,EAAA,IAAI,KAAK,EAAA,EAAI;AACX,IAAA,MAAM,IAAI,WAAW,kCAAkC,CAAA;AAAA,EACzD;AAEA,EAAA,IAAI,0BAA0B,CAAA,EAAG;AAC/B,IAAA,IAAI,SAAA,KAAc,CAAA,EAAG,OAAO,MAAA,CAAO,iBAAA;AACnC,IAAA,IAAIA,UAAS,CAAA,EAAG,OAAO,iBAAA,IAAqB,SAAA,GAAY,IAAI,MAAA,CAAO,iBAAA;AACnE,IAAA,IAAI,CAAA,GAAI,CAAA,EAAG,OAAO,MAAA,CAAO,iBAAA;AACzB,IAAA,MAAM,CAAA,GAAI,KAAK,GAAA,CAAI,iBAAA,GAAoB,SAAS,CAAA,GAAI,IAAA,CAAK,GAAA,CAAI,CAAA,GAAI,CAAC,CAAA;AAClE,IAAA,OAAO,MAAA,CAAO,QAAA,CAAS,CAAC,CAAA,IAAK,CAAA,IAAK,IAAI,IAAA,CAAK,IAAA,CAAK,CAAC,CAAA,GAAI,MAAA,CAAO,iBAAA;AAAA,EAC9D;AAEA,EAAA,IAAIA,UAAS,CAAA,EAAG;AACd,IAAA,MAAM,SAAS,iBAAA,GAAoB,SAAA;AACnC,IAAA,IAAI,MAAA,IAAU,GAAG,OAAO,CAAA;AACxB,IAAA,OAAO,IAAA,CAAK,IAAA,CAAK,MAAA,GAAS,qBAAqB,CAAA;AAAA,EACjD;AAGA,EAAA,IAAII,GAAAA,GAAK,SAAA;AACT,EAAA,IAAI,OAAA,GAAU,CAAA;AACd,EAAA,OAAOA,GAAAA,GAAK,iBAAA,IAAqB,OAAA,GAAU,UAAA,EAAY;AACrD,IAAA,IAAI,kBAAA,KAAuB,OAAA,EAASA,GAAAA,IAAM,qBAAA;AAC1C,IAAAA,MAAKA,GAAAA,IAAM,CAAA,GAAI,CAAA,CAAA,IAAM,kBAAA,KAAuB,QAAQ,qBAAA,GAAwB,CAAA,CAAA;AAC5E,IAAA,OAAA,EAAA;AAAA,EACF;AACA,EAAA,IAAIA,GAAAA,IAAM,mBAAmB,OAAO,OAAA;AACpC,EAAA,MAAM,IAAI,WAAW,4CAA4C,CAAA;AACnE;;;ACrDO,SAAS,aAAa,MAAA,EAAoC;AAC/D,EAAA,MAAM,EAAE,WAAA,EAAaA,GAAAA,EAAI,MAAAJ,KAAAA,EAAM,YAAA,EAAc,OAAM,GAAI,MAAA;AACvD,EAAA,iBAAA,CAAkBI,KAAI,aAAa,CAAA;AACnC,EAAA,cAAA,CAAe,cAAc,cAAc,CAAA;AAC3C,EAAA,iBAAA,CAAkB,OAAO,OAAO,CAAA;AAEhC,EAAA,IAAIJ,KAAAA,KAAS,CAAA,IAAK,KAAA,KAAU,CAAA,EAAG,OAAOI,GAAAA;AAEtC,EAAA,MAAM,CAAA,GAAI,YAAA;AACV,EAAA,MAAM,CAAA,GAAI,KAAA;AACV,EAAA,OAAOA,GAAAA,GAAAA,CAAM,CAAA,GAAIJ,KAAAA,GAAO,CAAA,MAAO,CAAA,GAAI,CAAA,CAAA;AACrC;;;ACXO,SAAS,sBAAsB,MAAA,EAA6C;AACjF,EAAA,MAAM,EAAE,gBAAA,EAAkB,aAAA,EAAe,OAAA,EAAS,MAAA,GAAS,OAAM,GAAI,MAAA;AACrE,EAAA,iBAAA,CAAkB,kBAAkB,kBAAkB,CAAA;AACtD,EAAA,iBAAA,CAAkB,SAAS,SAAS,CAAA;AAEpC,EAAA,IAAI,OAAA,KAAY,GAAG,OAAO,CAAA;AAC1B,EAAA,IAAI,kBAAkB,CAAA,EAAG;AACvB,IAAA,MAAMK,MAAK,gBAAA,GAAmB,OAAA;AAC9B,IAAA,OAAO,MAAA,KAAW,OAAA,GAAUA,GAAAA,IAAM,CAAA,GAAI,aAAA,CAAA,GAAiBA,GAAAA;AAAA,EACzD;AACA,EAAA,MAAMA,MAAM,gBAAA,IAAoB,CAAA,GAAA,CAAK,CAAA,GAAI,aAAA,KAAkB,CAAC,OAAA,CAAA,GAAY,aAAA;AACxE,EAAA,OAAO,MAAA,KAAW,OAAA,GAAUA,GAAAA,IAAM,CAAA,GAAI,aAAA,CAAA,GAAiBA,GAAAA;AACzD;;;ACLO,SAAS,gBAAgB,MAAA,EAAuC;AACrE,EAAA,MAAM;AAAA,IACJ,SAAA;AAAA,IACA,iBAAA;AAAA,IACA,OAAA;AAAA,IACA,qBAAA,GAAwB,CAAA;AAAA,IACxB,kBAAA,GAAqB,KAAA;AAAA,IACrB,UAAA,GAAa,KAAA;AAAA,IACb,UAAA,GAAa,EAAA;AAAA,IACb,aAAA,GAAgB,GAAA;AAAA,IAChB,SAAA,GAAY;AAAA,GACd,GAAI,MAAA;AAEJ,EAAA,iBAAA,CAAkB,WAAW,WAAW,CAAA;AACxC,EAAA,iBAAA,CAAkB,mBAAmB,mBAAmB,CAAA;AACxD,EAAA,cAAA,CAAe,SAAS,SAAS,CAAA;AACjC,EAAA,iBAAA,CAAkB,uBAAuB,uBAAuB,CAAA;AAChE,EAAA,kBAAA,CAAmB,YAAY,YAAY,CAAA;AAC3C,EAAA,kBAAA,CAAmB,YAAY,YAAY,CAAA;AAC3C,EAAA,kBAAA,CAAmB,eAAe,eAAe,CAAA;AACjD,EAAA,kBAAA,CAAmB,WAAW,WAAW,CAAA;AACzC,EAAA,IAAI,UAAA,IAAc,EAAA,EAAI,MAAM,IAAI,WAAW,yBAAyB,CAAA;AACpE,EAAA,IAAI,UAAA,IAAc,UAAA,EAAY,MAAM,IAAI,WAAW,4CAA4C,CAAA;AAC/F,EAAA,IAAI,CAAC,MAAA,CAAO,SAAA,CAAU,aAAa,CAAA,IAAK,iBAAiB,CAAA,EAAG;AAC1D,IAAA,MAAM,IAAI,WAAW,0CAA0C,CAAA;AAAA,EACjE;AACA,EAAA,IAAI,SAAA,IAAa,CAAA,EAAG,MAAM,IAAI,WAAW,uBAAuB,CAAA;AAEhE,EAAA,IAAI,OAAA,KAAY,GAAG,OAAO,CAAA;AAC1B,EAAA,IAAI,iBAAA,IAAqB,SAAA,IAAa,qBAAA,KAA0B,CAAA,EAAG,OAAO,CAAA;AAE1E,EAAA,IAAI,0BAA0B,CAAA,EAAG;AAC/B,IAAA,IAAI,iBAAA,IAAqB,WAAW,OAAO,CAAA;AAC3C,IAAA,IAAI,cAAc,CAAA,EAAG;AACnB,MAAA,MAAM,IAAI,UAAA;AAAA,QACR;AAAA,OACF;AAAA,IACF;AACA,IAAA,OAAA,CAAQ,iBAAA,GAAoB,SAAA,MAAe,CAAA,GAAI,OAAA,CAAA,GAAW,CAAA;AAAA,EAC5D;AAEA,EAAA,MAAM,SAAA,GAAY,kBAAA,KAAuB,OAAA,GAAU,CAAA,GAAI,CAAA;AACvD,EAAA,MAAM,EAAA,GAAK,CAAC,CAAA,KAAc;AACxB,IAAA,MAAM,WAAW,CAAA,GAAI,CAAA;AACrB,IAAA,MAAM,YAAY,QAAA,IAAY,OAAA;AAC9B,IAAA,MAAM,SAAS,SAAA,GAAY,SAAA;AAC3B,IAAA,MAAM,WAAA,GAAc,CAAA,KAAM,CAAA,GAAI,OAAA,GAAA,CAAW,YAAY,CAAA,IAAK,CAAA;AAC1D,IAAA,MAAM,SAAA,GAAY,qBAAA,GAAwB,WAAA,IAAe,CAAA,GAAI,SAAA,GAAY,CAAA,CAAA;AACzE,IAAA,OAAO,SAAS,SAAA,GAAY,iBAAA;AAAA,EAC9B,CAAA;AACA,EAAA,MAAM,UAAA,GAAa,CAAC,CAAA,KAAc;AAChC,IAAA,MAAM,KAAA,GAAQ,IAAA,CAAK,GAAA,CAAI,CAAC,CAAA,GAAI,OAAO,IAAA,CAAK,GAAA,CAAI,CAAC,CAAA,GAAI,IAAA,GAAO,IAAA;AACxD,IAAA,OAAA,CAAQ,EAAA,CAAG,IAAI,KAAK,CAAA,GAAI,GAAG,CAAA,GAAI,KAAK,MAAM,CAAA,GAAI,KAAA,CAAA;AAAA,EAChD,CAAA;AAEA,EAAA,MAAM,gBACH,iBAAA,IAAqB,SAAA,GAAY,qBAAA,GAAwB,OAAA,CAAA,MAAc,IAAI,OAAA,CAAA,GAAW,CAAA;AAEzF,EAAA,MAAM,SAAS,aAAA,CAAc;AAAA,IAC3B,YAAA,EAAc,OAAO,QAAA,CAAS,YAAY,IAAI,IAAA,CAAK,GAAA,CAAI,YAAA,EAAc,UAAU,CAAA,GAAI,IAAA;AAAA,IACnF,EAAA;AAAA,IACA,UAAA;AAAA,IACA,SAAA;AAAA,IACA,aAAA;AAAA,IACA,GAAA,EAAK,UAAA;AAAA,IACL,GAAA,EAAK;AAAA,GACN,CAAA;AACD,EAAA,IAAI,MAAA,KAAW,QAAW,OAAO,MAAA;AAEjC,EAAA,MAAM,OAAA,GAAUC,YAAAA,CAAY,EAAA,EAAI,UAAA,EAAY,UAAU,CAAA;AACtD,EAAA,IAAI,YAAY,MAAA,EAAW;AACzB,IAAA,MAAM,IAAI,WAAW,uDAAuD,CAAA;AAAA,EAC9E;AACA,EAAA,IAAI,OAAA,CAAQ,KAAA,KAAU,OAAA,CAAQ,KAAA,SAAc,OAAA,CAAQ,KAAA;AAEpD,EAAA,MAAM,WAAW,SAAA,CAAU;AAAA,IACzB,EAAA;AAAA,IACA,OAAO,OAAA,CAAQ,KAAA;AAAA,IACf,OAAO,OAAA,CAAQ,KAAA;AAAA,IACf,SAAA;AAAA,IACA,eAAe,aAAA,GAAgB;AAAA,GAChC,CAAA;AACD,EAAA,IAAI,QAAA,KAAa,QAAW,OAAO,QAAA;AACnC,EAAA,MAAM,IAAI,WAAW,kCAAkC,CAAA;AACzD;AAEA,SAASA,YAAAA,CACP,EAAA,EACA,UAAA,EACA,UAAA,EAC8C;AAC9C,EAAA,MAAM,IAAA,GAAO,CACX,KAAA,EACA,GAAA,EACA,WAAW,GAAA,KACsC;AACjD,IAAA,IAAI,KAAA;AACJ,IAAA,IAAI,SAAA;AACJ,IAAA,KAAA,IAAS,CAAA,GAAI,CAAA,EAAG,CAAA,IAAK,QAAA,EAAU,CAAA,EAAA,EAAK;AAClC,MAAA,MAAM,CAAA,GAAI,KAAA,GAAA,CAAU,GAAA,GAAM,KAAA,IAAS,CAAA,GAAK,QAAA;AACxC,MAAA,MAAM,KAAA,GAAQ,GAAG,CAAC,CAAA;AAClB,MAAA,IAAI,CAAC,MAAA,CAAO,QAAA,CAAS,KAAK,CAAA,EAAG;AAC7B,MAAA,IAAI,UAAU,CAAA,EAAG,OAAO,EAAE,KAAA,EAAO,CAAA,EAAG,OAAO,CAAA,EAAE;AAC7C,MAAA,IAAI,UAAU,MAAA,IAAa,SAAA,KAAc,MAAA,IAAa,SAAA,GAAY,QAAQ,CAAA,EAAG;AAC3E,QAAA,OAAO,EAAE,KAAA,EAAO,KAAA,EAAO,KAAA,EAAO,CAAA,EAAE;AAAA,MAClC;AACA,MAAA,KAAA,GAAQ,CAAA;AACR,MAAA,SAAA,GAAY,KAAA;AAAA,IACd;AACA,IAAA,OAAO,MAAA;AAAA,EACT,CAAA;AAEA,EAAA,IAAI,KAAA,GAAQ,UAAA;AACZ,EAAA,IAAI,KAAA,GAAQ,UAAA;AACZ,EAAA,KAAA,IAAS,CAAA,GAAI,CAAA,EAAG,CAAA,GAAI,EAAA,EAAI,CAAA,EAAA,EAAK;AAC3B,IAAA,MAAM,OAAA,GAAU,IAAA,CAAK,KAAA,EAAO,KAAK,CAAA;AACjC,IAAA,IAAI,OAAA,KAAY,QAAW,OAAO,OAAA;AAClC,IAAA,KAAA,GAAQ,IAAA,CAAK,GAAA,CAAI,YAAA,EAAA,CAAe,KAAA,GAAQ,KAAK,CAAC,CAAA;AAC9C,IAAA,KAAA,GAAQ,QAAQ,CAAA,GAAI,CAAA;AAAA,EACtB;AAEA,EAAA,OAAO,IAAA,CAAK,KAAA,EAAO,KAAA,EAAO,GAAG,CAAA;AAC/B;;;ACzIO,SAAS,WAAW,MAAA,EAAkC;AAC3D,EAAA,MAAM,EAAE,aAAA,EAAe,aAAA,EAAc,GAAI,MAAA;AACzC,EAAA,kBAAA,CAAmB,eAAe,eAAe,CAAA;AACjD,EAAA,kBAAA,CAAmB,eAAe,eAAe,CAAA;AACjD,EAAA,IAAI,aAAA,IAAiB,IAAI,OAAO,GAAA;AAChC,EAAA,OAAA,CAAQ,CAAA,GAAI,aAAA,KAAkB,CAAA,GAAI,aAAA,CAAA,GAAiB,CAAA;AACrD;;;ACEO,SAAS,SAAS,MAAA,EAAgC;AACvD,EAAA,MAAM,EAAE,IAAA,EAAAN,KAAAA,EAAM,QAAA,GAAW,IAAG,GAAI,MAAA;AAChC,EAAA,kBAAA,CAAmBA,OAAM,MAAM,CAAA;AAC/B,EAAA,cAAA,CAAeA,OAAM,MAAM,CAAA;AAC3B,EAAA,OAAO,WAAW,GAAA,GAAMA,KAAAA;AAC1B;;;ACZA,SAAS,YAAA,CAAa,OAAsB,IAAA,EAAoB;AAC9D,EAAA,IAAI,KAAA,KAAU,KAAA,IAAS,KAAA,KAAU,OAAA,EAAS;AACxC,IAAA,MAAM,IAAI,UAAA,CAAW,CAAA,EAAG,IAAI,CAAA,yBAAA,CAA2B,CAAA;AAAA,EACzD;AACF;AAEA,SAAS,gBAAA,CAAiB,eAAuB,MAAA,EAA+B;AAC9E,EAAA,OAAO,MAAA,KAAW,OAAA,GAAU,CAAA,GAAI,aAAA,GAAgB,CAAA;AAClD;AAEA,SAAS,wBAAA,CACP,aAAA,EACA,OAAA,EACA,OAAA,EACAC,eACA,MAAA,EACQ;AACR,EAAA,IAAI,+BAAA,CAAgC,aAAa,CAAA,EAAG;AAClD,IAAA,MAAM,IAAI,WAAW,4BAA4B,CAAA;AAAA,EACnD;AACA,EAAA,IAAI,aAAA,KAAkB,CAAA,EAAG,OAAO,EAAEA,gBAAe,OAAA,GAAU,OAAA,CAAA;AAE3D,EAAA,MAAM,MAAA,GAAA,CAAU,IAAI,aAAA,KAAkB,OAAA;AACtC,EAAA,IAAI,CAAC,OAAO,QAAA,CAAS,MAAM,KAAK,MAAA,IAAU,CAAA,SAAU,MAAA,CAAO,GAAA;AAC3D,EAAA,MAAM,YACJ,OAAA,IAAA,CAAY,MAAA,GAAS,KAAK,aAAA,CAAA,GAAiB,gBAAA,CAAiB,eAAe,MAAM,CAAA;AACnF,EAAA,OAAO,EAAEA,gBAAe,MAAA,GAAS,SAAA,CAAA;AACnC;AAaO,SAAS,GAAG,MAAA,EAA0B;AAC3C,EAAA,MAAM,EAAE,eAAe,OAAA,EAAS,OAAA,GAAU,GAAG,YAAA,EAAAA,aAAAA,EAAc,MAAA,GAAS,KAAA,EAAM,GAAI,MAAA;AAC9E,EAAA,kBAAA,CAAmB,eAAe,eAAe,CAAA;AACjD,EAAA,cAAA,CAAe,SAAS,SAAS,CAAA;AACjC,EAAA,kBAAA,CAAmB,SAAS,SAAS,CAAA;AACrC,EAAA,kBAAA,CAAmBA,eAAc,cAAc,CAAA;AAC/C,EAAA,YAAA,CAAa,QAAQ,QAAQ,CAAA;AAE7B,EAAA,MAAM,QAAQ,wBAAA,CAAyB,aAAA,EAAe,OAAA,EAAS,OAAA,EAASA,eAAc,MAAM,CAAA;AAC5F,EAAA,IAAI,CAAC,MAAA,CAAO,QAAA,CAAS,KAAK,CAAA,EAAG;AAC3B,IAAA,MAAM,IAAI,WAAW,wCAAwC,CAAA;AAAA,EAC/D;AACA,EAAA,OAAO,KAAA;AACT;AAaO,SAAS,GAAG,MAAA,EAA0B;AAC3C,EAAA,MAAM,EAAE,aAAA,EAAe,OAAA,EAAS,OAAA,GAAU,CAAA,EAAG,aAAAC,YAAAA,GAAc,CAAA,EAAG,MAAA,GAAS,KAAA,EAAM,GAAI,MAAA;AACjF,EAAA,kBAAA,CAAmB,eAAe,eAAe,CAAA;AACjD,EAAA,cAAA,CAAe,SAAS,SAAS,CAAA;AACjC,EAAA,kBAAA,CAAmB,SAAS,SAAS,CAAA;AACrC,EAAA,kBAAA,CAAmBA,cAAa,aAAa,CAAA;AAC7C,EAAA,YAAA,CAAa,QAAQ,QAAQ,CAAA;AAC7B,EAAA,IAAI,+BAAA,CAAgC,aAAa,CAAA,EAAG;AAClD,IAAA,MAAM,IAAI,WAAW,4BAA4B,CAAA;AAAA,EACnD;AAEA,EAAA,IAAI,aAAA,KAAkB,CAAA,EAAG,OAAO,EAAEA,eAAc,OAAA,GAAU,OAAA,CAAA;AAE1D,EAAA,MAAM,MAAA,GAAA,CAAU,IAAI,aAAA,KAAkB,OAAA;AACtC,EAAA,IAAI,CAAC,MAAA,CAAO,QAAA,CAAS,MAAM,CAAA,IAAK,UAAU,CAAA,EAAG;AAC3C,IAAA,MAAM,IAAI,WAAW,uDAAuD,CAAA;AAAA,EAC9E;AACA,EAAA,MAAM,SAAA,GACF,WAAW,CAAA,GAAI,CAAA,GAAI,UAAW,aAAA,GAAiB,gBAAA,CAAiB,eAAe,MAAM,CAAA;AACzF,EAAA,MAAM,KAAA,GAAQ,CAACA,YAAAA,GAAc,MAAA,GAAS,SAAA;AACtC,EAAA,IAAI,CAAC,MAAA,CAAO,QAAA,CAAS,KAAK,CAAA,EAAG;AAC3B,IAAA,MAAM,IAAI,WAAW,wCAAwC,CAAA;AAAA,EAC/D;AACA,EAAA,OAAO,KAAA;AACT;AAaO,SAAS,IAAI,MAAA,EAA2B;AAC7C,EAAA,MAAM,EAAE,aAAA,EAAe,OAAA,EAAS,YAAA,EAAAD,aAAAA,EAAc,aAAAC,YAAAA,GAAc,CAAA,EAAG,MAAA,GAAS,KAAA,EAAM,GAAI,MAAA;AAClF,EAAA,kBAAA,CAAmB,eAAe,eAAe,CAAA;AACjD,EAAA,cAAA,CAAe,SAAS,SAAS,CAAA;AACjC,EAAA,kBAAA,CAAmBD,eAAc,cAAc,CAAA;AAC/C,EAAA,kBAAA,CAAmBC,cAAa,aAAa,CAAA;AAC7C,EAAA,YAAA,CAAa,QAAQ,QAAQ,CAAA;AAC7B,EAAA,IAAI,+BAAA,CAAgC,aAAa,CAAA,EAAG;AAClD,IAAA,MAAM,IAAI,WAAW,4BAA4B,CAAA;AAAA,EACnD;AAEA,EAAA,IAAI,aAAA,KAAkB,CAAA,EAAG,OAAO,EAAED,gBAAeC,YAAAA,CAAAA,GAAe,OAAA;AAEhE,EAAA,MAAM,MAAA,GAAA,CAAU,IAAI,aAAA,KAAkB,OAAA;AACtC,EAAA,IAAI,CAAC,MAAA,CAAO,QAAA,CAAS,MAAM,CAAA,IAAK,UAAU,CAAA,EAAG;AAC3C,IAAA,MAAM,IAAI,WAAW,uDAAuD,CAAA;AAAA,EAC9E;AACA,EAAA,MAAM,SAAA,GAAY,EAAEA,YAAAA,GAAcD,aAAAA,GAAe,MAAA,CAAA,GAAU,aAAA;AAC3D,EAAA,MAAM,WAAA,GAAA,CAAe,MAAA,GAAS,CAAA,IAAK,gBAAA,CAAiB,eAAe,MAAM,CAAA;AACzE,EAAA,MAAM,QAAQ,SAAA,GAAY,WAAA;AAC1B,EAAA,IAAI,CAAC,MAAA,CAAO,QAAA,CAAS,KAAK,CAAA,EAAG;AAC3B,IAAA,MAAM,IAAI,WAAW,wCAAwC,CAAA;AAAA,EAC/D;AACA,EAAA,OAAO,KAAA;AACT;AAaO,SAAS,KAAK,MAAA,EAA4B;AAC/C,EAAA,MAAM,EAAE,aAAA,EAAe,OAAA,EAAS,YAAA,EAAAA,aAAAA,EAAc,aAAAC,YAAAA,GAAc,CAAA,EAAG,MAAA,GAAS,KAAA,EAAM,GAAI,MAAA;AAClF,EAAA,kBAAA,CAAmB,eAAe,eAAe,CAAA;AACjD,EAAA,kBAAA,CAAmB,SAAS,SAAS,CAAA;AACrC,EAAA,kBAAA,CAAmBD,eAAc,cAAc,CAAA;AAC/C,EAAA,kBAAA,CAAmBC,cAAa,aAAa,CAAA;AAC7C,EAAA,YAAA,CAAa,QAAQ,QAAQ,CAAA;AAC7B,EAAA,IAAI,+BAAA,CAAgC,aAAa,CAAA,EAAG;AAClD,IAAA,MAAM,IAAI,WAAW,4BAA4B,CAAA;AAAA,EACnD;AAEA,EAAA,IAAI,kBAAkB,CAAA,EAAG;AACvB,IAAA,MAAM,MAAA,GAAS,EAAED,aAAAA,GAAeC,YAAAA,CAAAA,GAAe,OAAA;AAC/C,IAAA,OAAO,OAAO,QAAA,CAAS,MAAM,KAAK,MAAA,IAAU,CAAA,GAAI,SAAS,MAAA,CAAO,GAAA;AAAA,EAClE;AAEA,EAAA,MAAM,eAAA,GAAkB,OAAA,GAAU,gBAAA,CAAiB,aAAA,EAAe,MAAM,CAAA;AACxE,EAAA,MAAM,SAAA,GAAY,kBAAkBA,YAAAA,GAAc,aAAA;AAClD,EAAA,MAAM,WAAA,GAAc,kBAAkBD,aAAAA,GAAe,aAAA;AACrD,EAAA,IAAI,SAAA,KAAc,CAAA,IAAK,WAAA,KAAgB,CAAA,SAAU,MAAA,CAAO,GAAA;AACxD,EAAA,MAAM,QAAQ,SAAA,GAAY,WAAA;AAC1B,EAAA,IAAI,KAAA,IAAS,CAAA,EAAG,OAAO,MAAA,CAAO,GAAA;AAE9B,EAAA,MAAM,OAAA,GAAU,KAAK,GAAA,CAAI,KAAK,IAAI,IAAA,CAAK,GAAA,CAAI,IAAI,aAAa,CAAA;AAC5D,EAAA,OAAO,MAAA,CAAO,QAAA,CAAS,OAAO,CAAA,GAAI,UAAU,MAAA,CAAO,GAAA;AACrD;AAkBO,SAAS,KAAK,MAAA,EAA4B;AAC/C,EAAA,MAAM;AAAA,IACJ,OAAA;AAAA,IACA,OAAA;AAAA,IACA,YAAA,EAAAA,aAAAA;AAAA,IACA,aAAAC,YAAAA,GAAc,CAAA;AAAA,IACd,MAAA,GAAS,KAAA;AAAA,IACT,KAAA,GAAQ,GAAA;AAAA,IACR,SAAA,GAAY,KAAA;AAAA,IACZ,aAAA,GAAgB,GAAA;AAAA,IAChB,UAAA,GAAa,YAAA;AAAA,IACb,UAAA,GAAa;AAAA,GACf,GAAI,MAAA;AACJ,EAAA,cAAA,CAAe,SAAS,SAAS,CAAA;AACjC,EAAA,kBAAA,CAAmB,SAAS,SAAS,CAAA;AACrC,EAAA,kBAAA,CAAmBD,eAAc,cAAc,CAAA;AAC/C,EAAA,kBAAA,CAAmBC,cAAa,aAAa,CAAA;AAC7C,EAAA,kBAAA,CAAmB,OAAO,OAAO,CAAA;AACjC,EAAA,kBAAA,CAAmB,eAAe,eAAe,CAAA;AACjD,EAAA,kBAAA,CAAmB,YAAY,YAAY,CAAA;AAC3C,EAAA,kBAAA,CAAmB,YAAY,YAAY,CAAA;AAC3C,EAAA,YAAA,CAAa,QAAQ,QAAQ,CAAA;AAC7B,EAAA,IAAI,+BAAA,CAAgC,UAAU,CAAA,EAAG;AAC/C,IAAA,MAAM,IAAI,WAAW,yBAAyB,CAAA;AAAA,EAChD;AACA,EAAA,IAAI,cAAc,UAAA,EAAY;AAC5B,IAAA,MAAM,IAAI,WAAW,4CAA4C,CAAA;AAAA,EACnE;AACA,EAAA,IAAI,CAAC,MAAA,CAAO,SAAA,CAAU,aAAa,CAAA,IAAK,iBAAiB,CAAA,EAAG;AAC1D,IAAA,MAAM,IAAI,WAAW,0CAA0C,CAAA;AAAA,EACjE;AAEA,EAAA,MAAM,EAAA,GAAK,CAAC,CAAA,KACV,wBAAA,CAAyB,GAAG,OAAA,EAAS,OAAA,EAASD,aAAAA,EAAc,MAAM,CAAA,GAAIC,YAAAA;AACxE,EAAA,MAAM,UAAA,GAAa,CAAC,CAAA,KAAc;AAChC,IAAA,MAAM,KAAA,GAAQ,IAAA,CAAK,GAAA,CAAI,CAAC,CAAA,GAAI,OAAO,IAAA,CAAK,GAAA,CAAI,CAAC,CAAA,GAAI,IAAA,GAAO,IAAA;AACxD,IAAA,OAAA,CAAQ,EAAA,CAAG,IAAI,KAAK,CAAA,GAAI,GAAG,CAAA,GAAI,KAAK,MAAM,CAAA,GAAI,KAAA,CAAA;AAAA,EAChD,CAAA;AAEA,EAAA,MAAM,SAAS,aAAA,CAAc;AAAA,IAC3B,YAAA,EAAc,KAAA;AAAA,IACd,EAAA;AAAA,IACA,UAAA;AAAA,IACA,SAAA;AAAA,IACA,aAAA;AAAA,IACA,GAAA,EAAK,UAAA;AAAA,IACL,GAAA,EAAK;AAAA,GACN,CAAA;AACD,EAAA,IAAI,MAAA,KAAW,QAAW,OAAO,MAAA;AAEjC,EAAA,MAAM,OAAA,GAAU,eAAA,CAAgB,EAAA,EAAI,UAAA,EAAY,UAAU,CAAA;AAC1D,EAAA,IAAI,YAAY,MAAA,EAAW;AACzB,IAAA,MAAM,IAAI,WAAW,4CAA4C,CAAA;AAAA,EACnE;AACA,EAAA,IAAI,OAAA,CAAQ,KAAA,KAAU,OAAA,CAAQ,KAAA,SAAc,OAAA,CAAQ,KAAA;AAEpD,EAAA,MAAM,WAAW,SAAA,CAAU;AAAA,IACzB,EAAA;AAAA,IACA,OAAO,OAAA,CAAQ,KAAA;AAAA,IACf,OAAO,OAAA,CAAQ,KAAA;AAAA,IACf,SAAA;AAAA,IACA,eAAe,aAAA,GAAgB;AAAA,GAChC,CAAA;AACD,EAAA,IAAI,QAAA,KAAa,QAAW,OAAO,QAAA;AAEnC,EAAA,MAAM,IAAI,WAAW,uBAAuB,CAAA;AAC9C;AAEA,SAAS,gCAAgC,aAAA,EAAgC;AACvE,EAAA,OAAO,aAAA,IAAiB,EAAA;AAC1B;AAEA,SAAS,eAAA,CACP,EAAA,EACA,UAAA,EACA,UAAA,EAC8C;AAC9C,EAAA,MAAM,IAAA,GAAO,CACX,KAAA,EACA,GAAA,EACA,WAAW,GAAA,KACsC;AACjD,IAAA,IAAI,KAAA;AACJ,IAAA,IAAI,SAAA;AACJ,IAAA,KAAA,IAAS,CAAA,GAAI,CAAA,EAAG,CAAA,IAAK,QAAA,EAAU,CAAA,EAAA,EAAK;AAClC,MAAA,MAAM,CAAA,GAAI,KAAA,GAAA,CAAU,GAAA,GAAM,KAAA,IAAS,CAAA,GAAK,QAAA;AACxC,MAAA,MAAM,KAAA,GAAQ,GAAG,CAAC,CAAA;AAClB,MAAA,IAAI,CAAC,MAAA,CAAO,QAAA,CAAS,KAAK,CAAA,EAAG;AAC7B,MAAA,IAAI,UAAU,CAAA,EAAG,OAAO,EAAE,KAAA,EAAO,CAAA,EAAG,OAAO,CAAA,EAAE;AAC7C,MAAA,IAAI,cAAc,MAAA,IAAa,KAAA,KAAU,MAAA,IAAa,SAAA,GAAY,QAAQ,CAAA,EAAG;AAC3E,QAAA,OAAO,EAAE,KAAA,EAAO,KAAA,EAAO,KAAA,EAAO,CAAA,EAAE;AAAA,MAClC;AACA,MAAA,KAAA,GAAQ,CAAA;AACR,MAAA,SAAA,GAAY,KAAA;AAAA,IACd;AACA,IAAA,OAAO,MAAA;AAAA,EACT,CAAA;AAEA,EAAA,IAAI,KAAA,GAAQ,UAAA;AACZ,EAAA,IAAI,KAAA,GAAQ,UAAA;AACZ,EAAA,KAAA,IAAS,CAAA,GAAI,CAAA,EAAG,CAAA,GAAI,EAAA,EAAI,CAAA,EAAA,EAAK;AAC3B,IAAA,MAAM,OAAA,GAAU,IAAA,CAAK,KAAA,EAAO,KAAK,CAAA;AACjC,IAAA,IAAI,OAAA,KAAY,QAAW,OAAO,OAAA;AAClC,IAAA,KAAA,GAAQ,IAAA,CAAK,GAAA,CAAI,YAAA,EAAA,CAAe,KAAA,GAAQ,KAAK,CAAC,CAAA;AAC9C,IAAA,KAAA,GAAQ,QAAQ,CAAA,GAAI,CAAA;AAAA,EACtB;AAEA,EAAA,OAAO,IAAA,CAAK,KAAA,EAAO,KAAA,EAAO,GAAG,CAAA;AAC/B;;;ACzRO,SAAS,YAAY,MAAA,EAAmC;AAC7D,EAAA,MAAM,EAAE,SAAA,EAAW,UAAA,EAAY,eAAA,EAAiB,OAAM,GAAI,MAAA;AAC1D,EAAA,iBAAA,CAAkB,WAAW,WAAW,CAAA;AACxC,EAAA,kBAAA,CAAmB,YAAY,YAAY,CAAA;AAC3C,EAAA,cAAA,CAAe,iBAAiB,iBAAiB,CAAA;AACjD,EAAA,iBAAA,CAAkB,OAAO,OAAO,CAAA;AAEhC,EAAA,MAAM,CAAA,GAAI,IAAA,CAAK,KAAA,CAAM,eAAA,GAAkB,KAAK,CAAA;AAC5C,EAAA,IAAI,CAAA,KAAM,GAAG,OAAO,CAAA;AAEpB,EAAA,MAAM,IAAI,UAAA,GAAa,eAAA;AACvB,EAAA,IAAI,KAAK,EAAA,EAAI;AACX,IAAA,MAAM,IAAI,WAAW,2CAA2C,CAAA;AAAA,EAClE;AACA,EAAA,IAAI,CAAA,KAAM,CAAA,EAAG,OAAO,SAAA,GAAY,CAAA;AAEhC,EAAA,MAAM,QAAS,CAAA,GAAI,SAAA,IAAc,CAAA,GAAA,CAAK,CAAA,GAAI,MAAM,CAAC,CAAA,CAAA;AACjD,EAAA,IAAI,CAAC,MAAA,CAAO,QAAA,CAAS,KAAK,CAAA,EAAG;AAC3B,IAAA,MAAM,IAAI,WAAW,wCAAwC,CAAA;AAAA,EAC/D;AACA,EAAA,OAAO,KAAA;AACT;;;ACVO,SAAS,qBACd,MAAA,EAC4B;AAC5B,EAAA,MAAM,EAAE,SAAA,EAAW,UAAA,EAAY,iBAAiB,KAAA,EAAO,qBAAA,GAAwB,GAAE,GAAI,MAAA;AACrF,EAAA,iBAAA,CAAkB,WAAW,WAAW,CAAA;AACxC,EAAA,cAAA,CAAe,iBAAiB,iBAAiB,CAAA;AACjD,EAAA,iBAAA,CAAkB,OAAO,OAAO,CAAA;AAChC,EAAA,iBAAA,CAAkB,uBAAuB,uBAAuB,CAAA;AAEhE,EAAA,MAAM,UAAA,GAAa,IAAA,CAAK,KAAA,CAAM,eAAA,GAAkB,KAAK,CAAA;AACrD,EAAA,IAAI,UAAA,KAAe,CAAA,IAAK,SAAA,KAAc,CAAA,EAAG;AACvC,IAAA,OAAO,EAAE,kBAAkB,CAAA,EAAG,QAAA,EAAU,EAAC,EAAG,SAAA,EAAW,CAAA,EAAG,aAAA,EAAe,CAAA,EAAE;AAAA,EAC7E;AAEA,EAAA,MAAM,cAAc,WAAA,CAAY,EAAE,WAAW,UAAA,EAAY,eAAA,EAAiB,OAAO,CAAA;AACjF,EAAA,MAAM,IAAI,UAAA,GAAa,eAAA;AAEvB,EAAA,MAAM,WAA8B,EAAC;AACrC,EAAA,IAAI,OAAA,GAAU,SAAA;AACd,EAAA,IAAI,SAAA,GAAY,CAAA;AAChB,EAAA,IAAI,aAAA,GAAgB,CAAA;AAEpB,EAAA,KAAA,IAAS,SAAS,CAAA,EAAG,MAAA,IAAU,UAAA,IAAc,OAAA,GAAU,GAAG,MAAA,EAAA,EAAU;AAClE,IAAA,MAAM,eAAA,GAAkB,CAAA,KAAM,CAAA,GAAI,CAAA,GAAI,OAAA,GAAU,CAAA;AAChD,IAAA,IAAI,UAAU,WAAA,GAAc,qBAAA;AAC5B,IAAA,IAAI,mBAAmB,OAAA,GAAU,eAAA;AAEjC,IAAA,IAAI,mBAAmB,OAAA,EAAS;AAC9B,MAAA,gBAAA,GAAmB,OAAA;AACnB,MAAA,OAAA,GAAU,gBAAA,GAAmB,eAAA;AAAA,IAC/B;AAEA,IAAA,OAAA,GAAU,OAAA,GAAU,gBAAA;AACpB,IAAA,IAAI,IAAA,CAAK,GAAA,CAAI,OAAO,CAAA,GAAI,OAAO,OAAA,GAAU,CAAA;AAEzC,IAAA,SAAA,IAAa,OAAA;AACb,IAAA,aAAA,IAAiB,eAAA;AAEjB,IAAA,QAAA,CAAS,IAAA,CAAK;AAAA,MACZ,MAAA;AAAA,MACA,OAAA;AAAA,MACA,gBAAA;AAAA,MACA,eAAA;AAAA,MACA;AAAA,KACD,CAAA;AAAA,EACH;AAEA,EAAA,OAAO;AAAA,IACL,gBAAA,EAAkB,WAAA;AAAA,IAClB,QAAA;AAAA,IACA,SAAA;AAAA,IACA;AAAA,GACF;AACF;;;AClEO,SAAS,sBAAsB,MAAA,EAA6C;AACjF,EAAA,MAAM,EAAE,SAAA,EAAW,UAAA,EAAY,eAAA,EAAiB,oBAAA,EAAsB,uBAAsB,GAC1F,MAAA;AAEF,EAAA,iBAAA,CAAkB,WAAW,WAAW,CAAA;AACxC,EAAA,kBAAA,CAAmB,YAAY,YAAY,CAAA;AAC3C,EAAA,cAAA,CAAe,iBAAiB,iBAAiB,CAAA;AACjD,EAAA,iBAAA,CAAkB,sBAAsB,sBAAsB,CAAA;AAC9D,EAAA,iBAAA,CAAkB,uBAAuB,uBAAuB,CAAA;AAEhE,EAAA,IAAI,SAAA,IAAa,GAAG,OAAO,CAAA;AAC3B,EAAA,MAAM,UAAU,oBAAA,GAAuB,qBAAA;AACvC,EAAA,IAAI,OAAA,IAAW,CAAA,EAAG,OAAO,MAAA,CAAO,iBAAA;AAEhC,EAAA,MAAM,IAAI,UAAA,GAAa,eAAA;AACvB,EAAA,IAAI,OAAA,GAAU,SAAA;AACd,EAAA,IAAI,MAAA,GAAS,CAAA;AAEb,EAAA,OAAO,OAAA,GAAU,KAAA,IAAS,MAAA,GAAS,GAAA,EAAQ;AACzC,IAAA,MAAM,QAAA,GAAW,CAAA,GAAI,CAAA,GAAI,OAAA,GAAU,CAAA,GAAI,CAAA;AACvC,IAAA,IAAI,OAAA,IAAW,QAAA,EAAU,OAAO,MAAA,CAAO,iBAAA;AACvC,IAAA,MAAM,aAAA,GAAgB,IAAA,CAAK,GAAA,CAAI,OAAA,GAAU,UAAU,OAAO,CAAA;AAC1D,IAAA,OAAA,IAAW,aAAA;AACX,IAAA,MAAA,EAAA;AAAA,EACF;AACA,EAAA,OAAO,OAAA,IAAW,KAAA,GAAQ,MAAA,GAAS,MAAA,CAAO,iBAAA;AAC5C;;;ACzBO,SAAS,iBAAiB,MAAA,EAAwC;AACvE,EAAA,MAAM,EAAE,SAAA,EAAW,UAAA,EAAY,eAAA,EAAiB,KAAA,EAAO,mBAAkB,GAAI,MAAA;AAC7E,EAAA,iBAAA,CAAkB,WAAW,WAAW,CAAA;AACxC,EAAA,cAAA,CAAe,iBAAiB,iBAAiB,CAAA;AACjD,EAAA,iBAAA,CAAkB,OAAO,OAAO,CAAA;AAChC,EAAA,iBAAA,CAAkB,mBAAmB,mBAAmB,CAAA;AAExD,EAAA,MAAM,CAAA,GAAI,IAAA,CAAK,KAAA,CAAM,eAAA,GAAkB,KAAK,CAAA;AAC5C,EAAA,IAAI,CAAA,KAAM,CAAA,IAAK,iBAAA,IAAqB,CAAA,EAAG,OAAO,CAAA;AAC9C,EAAA,IAAI,iBAAA,IAAqB,GAAG,OAAO,SAAA;AAEnC,EAAA,MAAM,UAAU,WAAA,CAAY,EAAE,WAAW,UAAA,EAAY,eAAA,EAAiB,OAAO,CAAA;AAC7E,EAAA,MAAM,IAAI,UAAA,GAAa,eAAA;AACvB,EAAA,MAAM,CAAA,GAAI,iBAAA;AAEV,EAAA,IAAI,CAAA,KAAM,GAAG,OAAO,IAAA,CAAK,IAAI,CAAA,EAAG,SAAA,GAAY,UAAU,CAAC,CAAA;AACvD,EAAA,MAAM,OAAA,GAAU,aAAa,CAAA,GAAI,CAAA,KAAM,IAAI,OAAA,IAAA,CAAA,CAAa,CAAA,GAAI,CAAA,KAAM,CAAA,GAAI,CAAA,IAAK,CAAA,CAAA;AAC3E,EAAA,OAAO,IAAA,CAAK,GAAA,CAAI,CAAA,EAAG,OAAO,CAAA;AAC5B;;;ACnBO,SAAS,gBAAgB,MAAA,EAAuC;AACrE,EAAA,MAAM,EAAE,KAAA,EAAO,QAAA,GAAW,CAAA,EAAG,IAAA,GAAO,WAAU,GAAI,MAAA;AAClD,EAAA,kBAAA,CAAmB,OAAO,OAAO,CAAA;AACjC,EAAA,MAAM,IAAI,IAAA,CAAK,GAAA,CAAI,GAAG,IAAA,CAAK,KAAA,CAAM,QAAQ,CAAC,CAAA;AAC1C,EAAA,MAAM,SAAS,EAAA,IAAM,CAAA;AACrB,EAAA,IAAI,SAAS,WAAA,EAAa;AACxB,IAAA,MAAM,SAAS,KAAA,GAAQ,MAAA;AACvB,IAAA,MAAM,IAAA,GAAO,MAAA,GAAS,CAAA,GAAI,EAAA,GAAK,CAAA;AAC/B,IAAA,MAAM,SAAA,GAAY,IAAA,CAAK,GAAA,CAAI,MAAM,CAAA;AACjC,IAAA,MAAM,QAAA,GAAW,IAAA,CAAK,KAAA,CAAM,SAAS,CAAA;AACrC,IAAA,MAAM,WAAW,SAAA,GAAY,QAAA;AAC7B,IAAA,MAAM,OAAA,GAAU,KAAA;AAChB,IAAA,IAAI,IAAA,CAAK,GAAA,CAAI,QAAA,GAAW,GAAG,KAAK,OAAA,EAAS;AACvC,MAAA,MAAM,WAAA,GAAc,QAAA,GAAW,CAAA,KAAM,CAAA,GAAI,WAAW,QAAA,GAAW,CAAA;AAC/D,MAAA,OAAQ,OAAO,WAAA,GAAe,MAAA;AAAA,IAChC;AACA,IAAA,OAAO,IAAA,CAAK,KAAA,CAAM,MAAM,CAAA,GAAI,MAAA;AAAA,EAC9B;AACA,EAAA,OAAO,IAAA,CAAK,KAAA,CAAM,KAAA,GAAQ,MAAM,CAAA,GAAI,MAAA;AACtC","file":"index.js","sourcesContent":["export function assertFiniteNumber(value: number, name: string): void {\n if (!Number.isFinite(value)) {\n throw new RangeError(`${name} must be a finite number`);\n }\n}\n\nexport function assertNonNegative(value: number, name: string): void {\n assertFiniteNumber(value, name);\n if (value < 0) {\n throw new RangeError(`${name} must be >= 0`);\n }\n}\n\nexport function assertPositive(value: number, name: string): void {\n assertFiniteNumber(value, name);\n if (value <= 0) {\n throw new RangeError(`${name} must be > 0`);\n }\n}\n","import { assertPositive } from \"../utils/assertions.js\";\n\nexport type CagrParams = {\n startValue: number;\n endValue: number;\n years: number;\n};\n\n/**\n * Compound annual growth rate (CAGR) between start and end value over the given years.\n * CAGR = (endValue/startValue)^(1/years) - 1\n */\nexport function cagr(params: CagrParams): number {\n const { startValue, endValue, years } = params;\n assertPositive(startValue, \"startValue\");\n assertPositive(years, \"years\");\n if (endValue <= 0) return -1;\n return (endValue / startValue) ** (1 / years) - 1;\n}\n","import { assertNonNegative, assertPositive } from \"../utils/assertions.js\";\n\nexport type CompoundParams = {\n principal: number;\n rate: number;\n timesPerYear: number;\n years: number;\n};\n\n/**\n * Computes compound growth using nominal annual `rate` compounded `timesPerYear`.\n * Returns the final amount (principal + interest).\n */\nexport function compound(params: CompoundParams): number {\n const { principal, rate, timesPerYear, years } = params;\n assertNonNegative(principal, \"principal\");\n assertPositive(timesPerYear, \"timesPerYear\");\n assertNonNegative(years, \"years\");\n\n if (rate === 0 || years === 0) return principal;\n\n const n = timesPerYear;\n const t = years;\n return principal * (1 + rate / n) ** (n * t);\n}\n","import { assertFiniteNumber, assertPositive } from \"../utils/assertions.js\";\n\nexport type EffectiveAnnualRateParams = {\n nominalRate: number;\n timesPerYear: number;\n};\n\n/**\n * Converts a nominal annual rate to effective annual rate (EAR).\n * EAR = (1 + nominalRate/timesPerYear)^timesPerYear - 1\n */\nexport function effectiveAnnualRate(params: EffectiveAnnualRateParams): number {\n const { nominalRate, timesPerYear } = params;\n assertFiniteNumber(nominalRate, \"nominalRate\");\n assertPositive(timesPerYear, \"timesPerYear\");\n\n const r = nominalRate / timesPerYear;\n return (1 + r) ** timesPerYear - 1;\n}\n","import { assertNonNegative, assertPositive } from \"../utils/assertions.js\";\n\nexport type FutureValueParams = {\n presentValue: number;\n rate: number;\n timesPerYear: number;\n years: number;\n};\n\n/**\n * Future value of a lump sum using nominal annual `rate` compounded `timesPerYear`.\n */\nexport function futureValue(params: FutureValueParams): number {\n const { presentValue, rate, timesPerYear, years } = params;\n assertNonNegative(presentValue, \"presentValue\");\n assertPositive(timesPerYear, \"timesPerYear\");\n assertNonNegative(years, \"years\");\n\n if (rate === 0 || years === 0) return presentValue;\n\n const n = timesPerYear;\n const t = years;\n return presentValue * (1 + rate / n) ** (n * t);\n}\n","import { assertFiniteNumber, assertNonNegative } from \"../utils/assertions.js\";\n\nexport type InflationAdjustedAmountParams = {\n amount: number;\n annualInflationRate: number;\n years: number;\n direction: \"toPast\" | \"toFuture\";\n};\n\n/**\n * Purchasing power across time. toPast: amount/(1+rate)^years. toFuture: amount*(1+rate)^years.\n */\nexport function inflationAdjustedAmount(params: InflationAdjustedAmountParams): number {\n const { amount, annualInflationRate, years, direction } = params;\n assertFiniteNumber(amount, \"amount\");\n assertFiniteNumber(annualInflationRate, \"annualInflationRate\");\n assertNonNegative(years, \"years\");\n const factor = (1 + annualInflationRate) ** years;\n return direction === \"toPast\" ? amount / factor : amount * factor;\n}\n","import { assertNonNegative, assertPositive } from \"../utils/assertions.js\";\n\nexport type InvestmentGrowthParams = {\n initial: number;\n contributionPerPeriod?: number;\n rate: number;\n timesPerYear: number;\n years: number;\n contributionTiming?: \"end\" | \"begin\";\n};\n\nexport type InvestmentGrowthResult = {\n futureValue: number;\n totalContributions: number;\n totalInterest: number;\n};\n\n/**\n * Future value of an investment with optional periodic contributions.\n *\n * - `rate` is nominal annual rate (e.g. 0.05 for 5%)\n * - contributions occur each compounding period (`timesPerYear`)\n */\nexport function investmentGrowth(params: InvestmentGrowthParams): InvestmentGrowthResult {\n const {\n initial,\n contributionPerPeriod = 0,\n rate,\n timesPerYear,\n years,\n contributionTiming = \"end\",\n } = params;\n\n assertNonNegative(initial, \"initial\");\n assertNonNegative(contributionPerPeriod, \"contributionPerPeriod\");\n assertPositive(timesPerYear, \"timesPerYear\");\n assertNonNegative(years, \"years\");\n\n const periods = Math.round(timesPerYear * years);\n if (periods === 0) {\n return {\n futureValue: initial,\n totalContributions: 0,\n totalInterest: 0,\n };\n }\n\n const r = rate / timesPerYear;\n\n // Lump sum growth\n const fvInitial = rate === 0 ? initial : initial * (1 + r) ** periods;\n\n // Annuity future value (ordinary vs due)\n let fvContrib = 0;\n if (contributionPerPeriod !== 0) {\n if (rate === 0) {\n fvContrib = contributionPerPeriod * periods;\n } else {\n const ordinary = contributionPerPeriod * (((1 + r) ** periods - 1) / r);\n fvContrib = contributionTiming === \"begin\" ? ordinary * (1 + r) : ordinary;\n }\n }\n\n const futureValue = fvInitial + fvContrib;\n const totalContributions = contributionPerPeriod * periods;\n const totalInterest = futureValue - initial - totalContributions;\n\n return { futureValue, totalContributions, totalInterest };\n}\n","export type NewtonRaphsonParams = {\n initialGuess: number;\n fn: (x: number) => number;\n derivative: (x: number) => number;\n tolerance?: number;\n maxIterations?: number;\n min?: number;\n max?: number;\n};\n\nexport function newtonRaphson(params: NewtonRaphsonParams): number | undefined {\n const {\n initialGuess,\n fn,\n derivative,\n tolerance = 1e-10,\n maxIterations = 100,\n min = Number.NEGATIVE_INFINITY,\n max = Number.POSITIVE_INFINITY,\n } = params;\n\n let x = initialGuess;\n for (let i = 0; i < maxIterations; i++) {\n const value = fn(x);\n if (!Number.isFinite(value)) return undefined;\n if (Math.abs(value) <= tolerance) return x;\n\n const slope = derivative(x);\n if (!Number.isFinite(slope) || Math.abs(slope) < 1e-14) return undefined;\n\n x -= value / slope;\n if (x < min) x = min;\n if (x > max) x = max;\n }\n\n return undefined;\n}\n\nexport type BisectionParams = {\n fn: (x: number) => number;\n lower: number;\n upper: number;\n tolerance?: number;\n maxIterations?: number;\n};\n\nexport function bisection(params: BisectionParams): number | undefined {\n const { fn, lower, upper, tolerance = 1e-10, maxIterations = 200 } = params;\n let a = lower;\n let b = upper;\n let fa = fn(a);\n let fb = fn(b);\n\n if (!Number.isFinite(fa) || !Number.isFinite(fb) || fa * fb > 0) return undefined;\n if (Math.abs(fa) <= tolerance) return a;\n if (Math.abs(fb) <= tolerance) return b;\n\n for (let i = 0; i < maxIterations; i++) {\n const c = (a + b) / 2;\n const fc = fn(c);\n if (!Number.isFinite(fc)) return undefined;\n if (Math.abs(fc) <= tolerance || Math.abs(b - a) <= tolerance) return c;\n\n if (fa * fc < 0) {\n b = c;\n fb = fc;\n } else {\n a = c;\n fa = fc;\n }\n }\n\n return (a + b) / 2;\n}\n","import { assertFiniteNumber } from \"../utils/assertions.js\";\nimport { bisection, newtonRaphson } from \"../utils/solvers.js\";\n\nexport type IrrParams = {\n cashFlows: number[];\n guess?: number;\n maxIterations?: number;\n lowerBound?: number;\n upperBound?: number;\n};\n\nfunction npvAt(rate: number, cashFlows: number[]): number {\n let sum = 0;\n for (let t = 0; t < cashFlows.length; t++) {\n const cf = cashFlows[t];\n if (cf !== undefined) sum += cf / (1 + rate) ** t;\n }\n return sum;\n}\n\nfunction npvDerivativeAt(rate: number, cashFlows: number[]): number {\n let sum = 0;\n for (let t = 1; t < cashFlows.length; t++) {\n const cf = cashFlows[t];\n if (cf !== undefined) sum -= (t * cf) / (1 + rate) ** (t + 1);\n }\n return sum;\n}\n\nfunction hasPositiveAndNegative(cashFlows: number[]): boolean {\n let hasPositive = false;\n let hasNegative = false;\n for (const cf of cashFlows) {\n if (cf > 0) hasPositive = true;\n if (cf < 0) hasNegative = true;\n if (hasPositive && hasNegative) return true;\n }\n return false;\n}\n\nfunction findBracket(\n fn: (x: number) => number,\n lowerBound: number,\n upperBound: number,\n): { lower: number; upper: number } | undefined {\n const scan = (\n start: number,\n end: number,\n segments = 200,\n ): { lower: number; upper: number } | undefined => {\n let prevX: number | undefined;\n let prevValue: number | undefined;\n for (let i = 0; i <= segments; i++) {\n const x = start + ((end - start) * i) / segments;\n const value = fn(x);\n if (!Number.isFinite(value)) continue;\n if (value === 0) return { lower: x, upper: x };\n if (prevX !== undefined && prevValue !== undefined && prevValue * value < 0) {\n return { lower: prevX, upper: x };\n }\n prevX = x;\n prevValue = value;\n }\n return undefined;\n };\n\n let lower = lowerBound;\n let upper = upperBound;\n for (let i = 0; i < 20; i++) {\n const bracket = scan(lower, upper);\n if (bracket !== undefined) return bracket;\n lower = Math.max(-0.999999999, (lower - 1) / 2);\n upper = upper * 2 + 1;\n }\n\n return scan(lower, upper, 400);\n}\n\nexport function irr(params: IrrParams): number {\n const {\n cashFlows,\n guess = 0.1,\n maxIterations = 100,\n lowerBound = -0.99,\n upperBound = 10,\n } = params;\n if (cashFlows.length === 0) {\n throw new RangeError(\"cashFlows must contain at least one value\");\n }\n assertFiniteNumber(guess, \"guess\");\n assertFiniteNumber(maxIterations, \"maxIterations\");\n assertFiniteNumber(lowerBound, \"lowerBound\");\n assertFiniteNumber(upperBound, \"upperBound\");\n if (maxIterations <= 0 || !Number.isInteger(maxIterations)) {\n throw new RangeError(\"maxIterations must be a positive integer\");\n }\n if (lowerBound <= -1) {\n throw new RangeError(\"lowerBound must be > -1\");\n }\n if (upperBound <= lowerBound) {\n throw new RangeError(\"upperBound must be greater than lowerBound\");\n }\n\n for (const cf of cashFlows) assertFiniteNumber(cf, \"cashFlows[]\");\n if (!hasPositiveAndNegative(cashFlows)) {\n throw new RangeError(\"cashFlows must include at least one positive and one negative value\");\n }\n\n const fn = (rate: number) => npvAt(rate, cashFlows);\n const derivative = (rate: number) => npvDerivativeAt(rate, cashFlows);\n\n const newton = newtonRaphson({\n initialGuess: guess,\n fn,\n derivative,\n tolerance: 1e-10,\n maxIterations,\n min: lowerBound,\n max: upperBound,\n });\n if (newton !== undefined) return newton;\n\n const bracket = findBracket(fn, lowerBound, upperBound);\n if (bracket === undefined) {\n throw new RangeError(\"IRR did not converge within search bounds\");\n }\n if (bracket.lower === bracket.upper) return bracket.lower;\n\n const bisected = bisection({\n fn,\n lower: bracket.lower,\n upper: bracket.upper,\n tolerance: 1e-10,\n maxIterations: maxIterations * 2,\n });\n if (bisected !== undefined) return bisected;\n\n throw new RangeError(\"IRR did not converge\");\n}\n","import { assertFiniteNumber } from \"../utils/assertions.js\";\n\nexport type NpvParams = {\n rate: number;\n cashFlows: number[];\n};\n\n/**\n * Net present value at a discount `rate`.\n * cashFlows[0] is the period-0 cash flow.\n */\nexport function npv(params: NpvParams): number {\n const { rate, cashFlows } = params;\n assertFiniteNumber(rate, \"rate\");\n if (rate <= -1) throw new RangeError(\"rate must be > -1\");\n if (cashFlows.length === 0) return 0;\n\n let sum = 0;\n for (let t = 0; t < cashFlows.length; t++) {\n const cf = cashFlows[t];\n if (cf === undefined) continue;\n assertFiniteNumber(cf, `cashFlows[${t}]`);\n sum += cf / (1 + rate) ** t;\n }\n return sum;\n}\n","import { assertNonNegative } from \"../utils/assertions.js\";\n\nexport type PaymentFromPresentValueParams = {\n presentValue: number;\n ratePerPeriod: number;\n periods: number;\n /** Payment at start of each period (annuity due). Default end (ordinary). */\n timing?: \"end\" | \"begin\";\n};\n\n/**\n * Periodic payment required to pay off a present value (e.g. loan) over periods.\n * PMT = PV * r / (1 - (1+r)^-n). For due: divide by (1+r).\n */\nexport function paymentFromPresentValue(params: PaymentFromPresentValueParams): number {\n const { presentValue, ratePerPeriod, periods, timing = \"end\" } = params;\n assertNonNegative(presentValue, \"presentValue\");\n assertNonNegative(periods, \"periods\");\n\n if (presentValue === 0 || periods === 0) return 0;\n if (ratePerPeriod === 0) {\n const pmt = presentValue / periods;\n return timing === \"begin\" ? pmt / (1 + ratePerPeriod) : pmt;\n }\n let pmt = (ratePerPeriod * presentValue) / (1 - (1 + ratePerPeriod) ** -periods);\n if (timing === \"begin\") pmt /= 1 + ratePerPeriod;\n return pmt;\n}\n","import { assertFiniteNumber, assertNonNegative, assertPositive } from \"../utils/assertions.js\";\n\nexport type PeriodsToReachGoalParams = {\n principal: number;\n targetFutureValue: number;\n rate: number;\n timesPerYear: number;\n contributionPerPeriod?: number;\n contributionTiming?: \"end\" | \"begin\";\n maxPeriods?: number;\n};\n\n/**\n * Number of compounding periods until future value reaches the goal.\n * With no contributions: closed form. With contributions: iterative.\n */\nexport function periodsToReachGoal(params: PeriodsToReachGoalParams): number {\n const {\n principal,\n targetFutureValue,\n rate,\n timesPerYear,\n contributionPerPeriod = 0,\n contributionTiming = \"end\",\n maxPeriods = 100000,\n } = params;\n\n assertNonNegative(principal, \"principal\");\n assertNonNegative(targetFutureValue, \"targetFutureValue\");\n assertFiniteNumber(rate, \"rate\");\n assertPositive(timesPerYear, \"timesPerYear\");\n assertNonNegative(contributionPerPeriod, \"contributionPerPeriod\");\n assertPositive(maxPeriods, \"maxPeriods\");\n\n if (targetFutureValue <= principal) return 0;\n\n const r = rate / timesPerYear;\n if (r <= -1) {\n throw new RangeError(\"rate / timesPerYear must be > -1\");\n }\n\n if (contributionPerPeriod === 0) {\n if (principal === 0) return Number.POSITIVE_INFINITY;\n if (rate === 0) return targetFutureValue <= principal ? 0 : Number.POSITIVE_INFINITY;\n if (r < 0) return Number.POSITIVE_INFINITY;\n const n = Math.log(targetFutureValue / principal) / Math.log(1 + r);\n return Number.isFinite(n) && n >= 0 ? Math.ceil(n) : Number.POSITIVE_INFINITY;\n }\n\n if (rate === 0) {\n const needed = targetFutureValue - principal;\n if (needed <= 0) return 0;\n return Math.ceil(needed / contributionPerPeriod);\n }\n\n // With contributions: iterate until FV >= target\n let fv = principal;\n let periods = 0;\n while (fv < targetFutureValue && periods < maxPeriods) {\n if (contributionTiming === \"begin\") fv += contributionPerPeriod;\n fv = fv * (1 + r) + (contributionTiming === \"end\" ? contributionPerPeriod : 0);\n periods++;\n }\n if (fv >= targetFutureValue) return periods;\n throw new RangeError(\"maxPeriods exceeded before reaching target\");\n}\n","import { assertNonNegative, assertPositive } from \"../utils/assertions.js\";\n\nexport type PresentValueParams = {\n futureValue: number;\n rate: number;\n timesPerYear: number;\n years: number;\n};\n\n/**\n * Present value of a lump sum using nominal annual `rate` compounded `timesPerYear`.\n */\nexport function presentValue(params: PresentValueParams): number {\n const { futureValue: fv, rate, timesPerYear, years } = params;\n assertNonNegative(fv, \"futureValue\");\n assertPositive(timesPerYear, \"timesPerYear\");\n assertNonNegative(years, \"years\");\n\n if (rate === 0 || years === 0) return fv;\n\n const n = timesPerYear;\n const t = years;\n return fv / (1 + rate / n) ** (n * t);\n}\n","import { assertNonNegative } from \"../utils/assertions.js\";\n\nexport type PresentValueOfAnnuityParams = {\n paymentPerPeriod: number;\n ratePerPeriod: number;\n periods: number;\n timing?: \"end\" | \"begin\";\n};\n\n/**\n * Present value of an annuity. PV = PMT * (1 - (1+r)^-n) / r. Due: multiply by (1+r).\n */\nexport function presentValueOfAnnuity(params: PresentValueOfAnnuityParams): number {\n const { paymentPerPeriod, ratePerPeriod, periods, timing = \"end\" } = params;\n assertNonNegative(paymentPerPeriod, \"paymentPerPeriod\");\n assertNonNegative(periods, \"periods\");\n\n if (periods === 0) return 0;\n if (ratePerPeriod === 0) {\n const pv = paymentPerPeriod * periods;\n return timing === \"begin\" ? pv * (1 + ratePerPeriod) : pv;\n }\n const pv = (paymentPerPeriod * (1 - (1 + ratePerPeriod) ** -periods)) / ratePerPeriod;\n return timing === \"begin\" ? pv * (1 + ratePerPeriod) : pv;\n}\n","import { assertFiniteNumber, assertNonNegative, assertPositive } from \"../utils/assertions.js\";\nimport { bisection, newtonRaphson } from \"../utils/solvers.js\";\n\nexport type RateToReachGoalParams = {\n principal: number;\n targetFutureValue: number;\n periods: number;\n contributionPerPeriod?: number;\n contributionTiming?: \"end\" | \"begin\";\n lowerBound?: number;\n upperBound?: number;\n maxIterations?: number;\n tolerance?: number;\n};\n\n/**\n * Rate per period required to reach target future value in given periods.\n * Uses Newton-Raphson when contributions are present; closed form for lump sum.\n */\nexport function rateToReachGoal(params: RateToReachGoalParams): number {\n const {\n principal,\n targetFutureValue,\n periods,\n contributionPerPeriod = 0,\n contributionTiming = \"end\",\n lowerBound = -0.99,\n upperBound = 10,\n maxIterations = 100,\n tolerance = 1e-10,\n } = params;\n\n assertNonNegative(principal, \"principal\");\n assertNonNegative(targetFutureValue, \"targetFutureValue\");\n assertPositive(periods, \"periods\");\n assertNonNegative(contributionPerPeriod, \"contributionPerPeriod\");\n assertFiniteNumber(lowerBound, \"lowerBound\");\n assertFiniteNumber(upperBound, \"upperBound\");\n assertFiniteNumber(maxIterations, \"maxIterations\");\n assertFiniteNumber(tolerance, \"tolerance\");\n if (lowerBound <= -1) throw new RangeError(\"lowerBound must be > -1\");\n if (upperBound <= lowerBound) throw new RangeError(\"upperBound must be greater than lowerBound\");\n if (!Number.isInteger(maxIterations) || maxIterations <= 0) {\n throw new RangeError(\"maxIterations must be a positive integer\");\n }\n if (tolerance <= 0) throw new RangeError(\"tolerance must be > 0\");\n\n if (periods === 0) return 0;\n if (targetFutureValue <= principal && contributionPerPeriod === 0) return 0;\n\n if (contributionPerPeriod === 0) {\n if (targetFutureValue <= principal) return 0;\n if (principal === 0) {\n throw new RangeError(\n \"rateToReachGoal is undefined when principal is 0 and contributions are 0\",\n );\n }\n return (targetFutureValue / principal) ** (1 / periods) - 1;\n }\n\n const dueFactor = contributionTiming === \"begin\" ? 1 : 0;\n const fn = (r: number) => {\n const onePlusR = 1 + r;\n const onePlusRN = onePlusR ** periods;\n const fvLump = principal * onePlusRN;\n const annuityBase = r === 0 ? periods : (onePlusRN - 1) / r;\n const fvAnnuity = contributionPerPeriod * annuityBase * (1 + dueFactor * r);\n return fvLump + fvAnnuity - targetFutureValue;\n };\n const derivative = (r: number) => {\n const delta = Math.abs(r) > 1e-6 ? Math.abs(r) * 1e-6 : 1e-6;\n return (fn(r + delta) - fn(r - delta)) / (2 * delta);\n };\n\n const initialGuess =\n (targetFutureValue / (principal + contributionPerPeriod * periods)) ** (1 / periods) - 1;\n\n const newton = newtonRaphson({\n initialGuess: Number.isFinite(initialGuess) ? Math.max(initialGuess, lowerBound) : 0.01,\n fn,\n derivative,\n tolerance,\n maxIterations,\n min: lowerBound,\n max: upperBound,\n });\n if (newton !== undefined) return newton;\n\n const bracket = findBracket(fn, lowerBound, upperBound);\n if (bracket === undefined) {\n throw new RangeError(\"rateToReachGoal did not converge within search bounds\");\n }\n if (bracket.lower === bracket.upper) return bracket.lower;\n\n const bisected = bisection({\n fn,\n lower: bracket.lower,\n upper: bracket.upper,\n tolerance,\n maxIterations: maxIterations * 2,\n });\n if (bisected !== undefined) return bisected;\n throw new RangeError(\"rateToReachGoal did not converge\");\n}\n\nfunction findBracket(\n fn: (x: number) => number,\n lowerBound: number,\n upperBound: number,\n): { lower: number; upper: number } | undefined {\n const scan = (\n start: number,\n end: number,\n segments = 200,\n ): { lower: number; upper: number } | undefined => {\n let prevX: number | undefined;\n let prevValue: number | undefined;\n for (let i = 0; i <= segments; i++) {\n const x = start + ((end - start) * i) / segments;\n const value = fn(x);\n if (!Number.isFinite(value)) continue;\n if (value === 0) return { lower: x, upper: x };\n if (prevX !== undefined && prevValue !== undefined && prevValue * value < 0) {\n return { lower: prevX, upper: x };\n }\n prevX = x;\n prevValue = value;\n }\n return undefined;\n };\n\n let lower = lowerBound;\n let upper = upperBound;\n for (let i = 0; i < 20; i++) {\n const bracket = scan(lower, upper);\n if (bracket !== undefined) return bracket;\n lower = Math.max(-0.999999999, (lower - 1) / 2);\n upper = upper * 2 + 1;\n }\n\n return scan(lower, upper, 400);\n}\n","import { assertFiniteNumber } from \"../utils/assertions.js\";\n\nexport type RealReturnParams = { nominalReturn: number; inflationRate: number };\n\nexport function realReturn(params: RealReturnParams): number {\n const { nominalReturn, inflationRate } = params;\n assertFiniteNumber(nominalReturn, \"nominalReturn\");\n assertFiniteNumber(inflationRate, \"inflationRate\");\n if (inflationRate <= -1) return NaN;\n return (1 + nominalReturn) / (1 + inflationRate) - 1;\n}\n","import { assertFiniteNumber, assertPositive } from \"../utils/assertions.js\";\n\nexport type RuleOf72Params = {\n rate: number;\n /** Use 69 for continuous-ish approximation (e.g. daily compounding). Default 72. */\n constant?: 72 | 69;\n};\n\n/**\n * Approximate years to double a lump sum at the given annual rate.\n * rate is decimal (e.g. 0.07 for 7%). Uses rule of 72 by default, or 69 if specified.\n */\nexport function ruleOf72(params: RuleOf72Params): number {\n const { rate, constant = 72 } = params;\n assertFiniteNumber(rate, \"rate\");\n assertPositive(rate, \"rate\");\n return constant / 100 / rate;\n}\n","import { assertFiniteNumber, assertPositive } from \"../utils/assertions.js\";\nimport { bisection, newtonRaphson } from \"../utils/solvers.js\";\n\ntype PaymentTiming = \"end\" | \"begin\";\n\nfunction assertTiming(value: PaymentTiming, name: string): void {\n if (value !== \"end\" && value !== \"begin\") {\n throw new RangeError(`${name} must be \"end\" or \"begin\"`);\n }\n}\n\nfunction annuityDueFactor(ratePerPeriod: number, timing: PaymentTiming): number {\n return timing === \"begin\" ? 1 + ratePerPeriod : 1;\n}\n\nfunction futureValueFromCashFlows(\n ratePerPeriod: number,\n periods: number,\n payment: number,\n presentValue: number,\n timing: PaymentTiming,\n): number {\n if (ratePerPeriodIsInvalidForDomain(ratePerPeriod)) {\n throw new RangeError(\"ratePerPeriod must be > -1\");\n }\n if (ratePerPeriod === 0) return -(presentValue + payment * periods);\n\n const growth = (1 + ratePerPeriod) ** periods;\n if (!Number.isFinite(growth) || growth <= 0) return Number.NaN;\n const paymentFv =\n payment * ((growth - 1) / ratePerPeriod) * annuityDueFactor(ratePerPeriod, timing);\n return -(presentValue * growth + paymentFv);\n}\n\nexport type FvParams = {\n ratePerPeriod: number;\n periods: number;\n payment?: number;\n presentValue: number;\n timing?: PaymentTiming;\n};\n\n/**\n * Excel FV equivalent.\n */\nexport function fv(params: FvParams): number {\n const { ratePerPeriod, periods, payment = 0, presentValue, timing = \"end\" } = params;\n assertFiniteNumber(ratePerPeriod, \"ratePerPeriod\");\n assertPositive(periods, \"periods\");\n assertFiniteNumber(payment, \"payment\");\n assertFiniteNumber(presentValue, \"presentValue\");\n assertTiming(timing, \"timing\");\n\n const value = futureValueFromCashFlows(ratePerPeriod, periods, payment, presentValue, timing);\n if (!Number.isFinite(value)) {\n throw new RangeError(\"Numerical instability for given inputs\");\n }\n return value;\n}\n\nexport type PvParams = {\n ratePerPeriod: number;\n periods: number;\n payment?: number;\n futureValue?: number;\n timing?: PaymentTiming;\n};\n\n/**\n * Excel PV equivalent.\n */\nexport function pv(params: PvParams): number {\n const { ratePerPeriod, periods, payment = 0, futureValue = 0, timing = \"end\" } = params;\n assertFiniteNumber(ratePerPeriod, \"ratePerPeriod\");\n assertPositive(periods, \"periods\");\n assertFiniteNumber(payment, \"payment\");\n assertFiniteNumber(futureValue, \"futureValue\");\n assertTiming(timing, \"timing\");\n if (ratePerPeriodIsInvalidForDomain(ratePerPeriod)) {\n throw new RangeError(\"ratePerPeriod must be > -1\");\n }\n\n if (ratePerPeriod === 0) return -(futureValue + payment * periods);\n\n const growth = (1 + ratePerPeriod) ** periods;\n if (!Number.isFinite(growth) || growth <= 0) {\n throw new RangeError(\"Numerical instability for given ratePerPeriod/periods\");\n }\n const paymentPv =\n ((payment * (1 - 1 / growth)) / ratePerPeriod) * annuityDueFactor(ratePerPeriod, timing);\n const value = -futureValue / growth - paymentPv;\n if (!Number.isFinite(value)) {\n throw new RangeError(\"Numerical instability for given inputs\");\n }\n return value;\n}\n\nexport type PmtParams = {\n ratePerPeriod: number;\n periods: number;\n presentValue: number;\n futureValue?: number;\n timing?: PaymentTiming;\n};\n\n/**\n * Excel PMT equivalent.\n */\nexport function pmt(params: PmtParams): number {\n const { ratePerPeriod, periods, presentValue, futureValue = 0, timing = \"end\" } = params;\n assertFiniteNumber(ratePerPeriod, \"ratePerPeriod\");\n assertPositive(periods, \"periods\");\n assertFiniteNumber(presentValue, \"presentValue\");\n assertFiniteNumber(futureValue, \"futureValue\");\n assertTiming(timing, \"timing\");\n if (ratePerPeriodIsInvalidForDomain(ratePerPeriod)) {\n throw new RangeError(\"ratePerPeriod must be > -1\");\n }\n\n if (ratePerPeriod === 0) return -(presentValue + futureValue) / periods;\n\n const growth = (1 + ratePerPeriod) ** periods;\n if (!Number.isFinite(growth) || growth <= 0) {\n throw new RangeError(\"Numerical instability for given ratePerPeriod/periods\");\n }\n const numerator = -(futureValue + presentValue * growth) * ratePerPeriod;\n const denominator = (growth - 1) * annuityDueFactor(ratePerPeriod, timing);\n const value = numerator / denominator;\n if (!Number.isFinite(value)) {\n throw new RangeError(\"Numerical instability for given inputs\");\n }\n return value;\n}\n\nexport type NperParams = {\n ratePerPeriod: number;\n payment: number;\n presentValue: number;\n futureValue?: number;\n timing?: PaymentTiming;\n};\n\n/**\n * Excel NPER equivalent.\n */\nexport function nper(params: NperParams): number {\n const { ratePerPeriod, payment, presentValue, futureValue = 0, timing = \"end\" } = params;\n assertFiniteNumber(ratePerPeriod, \"ratePerPeriod\");\n assertFiniteNumber(payment, \"payment\");\n assertFiniteNumber(presentValue, \"presentValue\");\n assertFiniteNumber(futureValue, \"futureValue\");\n assertTiming(timing, \"timing\");\n if (ratePerPeriodIsInvalidForDomain(ratePerPeriod)) {\n throw new RangeError(\"ratePerPeriod must be > -1\");\n }\n\n if (ratePerPeriod === 0) {\n const linear = -(presentValue + futureValue) / payment;\n return Number.isFinite(linear) && linear >= 0 ? linear : Number.NaN;\n }\n\n const adjustedPayment = payment * annuityDueFactor(ratePerPeriod, timing);\n const numerator = adjustedPayment - futureValue * ratePerPeriod;\n const denominator = adjustedPayment + presentValue * ratePerPeriod;\n if (numerator === 0 || denominator === 0) return Number.NaN;\n const ratio = numerator / denominator;\n if (ratio <= 0) return Number.NaN;\n\n const periods = Math.log(ratio) / Math.log(1 + ratePerPeriod);\n return Number.isFinite(periods) ? periods : Number.NaN;\n}\n\nexport type RateParams = {\n periods: number;\n payment: number;\n presentValue: number;\n futureValue?: number;\n timing?: PaymentTiming;\n guess?: number;\n tolerance?: number;\n maxIterations?: number;\n lowerBound?: number;\n upperBound?: number;\n};\n\n/**\n * Excel RATE equivalent.\n */\nexport function rate(params: RateParams): number {\n const {\n periods,\n payment,\n presentValue,\n futureValue = 0,\n timing = \"end\",\n guess = 0.1,\n tolerance = 1e-10,\n maxIterations = 100,\n lowerBound = -0.999999999,\n upperBound = 10,\n } = params;\n assertPositive(periods, \"periods\");\n assertFiniteNumber(payment, \"payment\");\n assertFiniteNumber(presentValue, \"presentValue\");\n assertFiniteNumber(futureValue, \"futureValue\");\n assertFiniteNumber(guess, \"guess\");\n assertFiniteNumber(maxIterations, \"maxIterations\");\n assertFiniteNumber(lowerBound, \"lowerBound\");\n assertFiniteNumber(upperBound, \"upperBound\");\n assertTiming(timing, \"timing\");\n if (ratePerPeriodIsInvalidForDomain(lowerBound)) {\n throw new RangeError(\"lowerBound must be > -1\");\n }\n if (upperBound <= lowerBound) {\n throw new RangeError(\"upperBound must be greater than lowerBound\");\n }\n if (!Number.isInteger(maxIterations) || maxIterations <= 0) {\n throw new RangeError(\"maxIterations must be a positive integer\");\n }\n\n const fn = (r: number) =>\n futureValueFromCashFlows(r, periods, payment, presentValue, timing) - futureValue;\n const derivative = (r: number) => {\n const delta = Math.abs(r) > 1e-5 ? Math.abs(r) * 1e-6 : 1e-6;\n return (fn(r + delta) - fn(r - delta)) / (2 * delta);\n };\n\n const newton = newtonRaphson({\n initialGuess: guess,\n fn,\n derivative,\n tolerance,\n maxIterations,\n min: lowerBound,\n max: upperBound,\n });\n if (newton !== undefined) return newton;\n\n const bracket = findRateBracket(fn, lowerBound, upperBound);\n if (bracket === undefined) {\n throw new RangeError(\"RATE did not converge within search bounds\");\n }\n if (bracket.lower === bracket.upper) return bracket.lower;\n\n const bisected = bisection({\n fn,\n lower: bracket.lower,\n upper: bracket.upper,\n tolerance,\n maxIterations: maxIterations * 2,\n });\n if (bisected !== undefined) return bisected;\n\n throw new RangeError(\"RATE did not converge\");\n}\n\nfunction ratePerPeriodIsInvalidForDomain(ratePerPeriod: number): boolean {\n return ratePerPeriod <= -1;\n}\n\nfunction findRateBracket(\n fn: (x: number) => number,\n lowerBound: number,\n upperBound: number,\n): { lower: number; upper: number } | undefined {\n const scan = (\n start: number,\n end: number,\n segments = 200,\n ): { lower: number; upper: number } | undefined => {\n let prevX: number | undefined;\n let prevValue: number | undefined;\n for (let i = 0; i <= segments; i++) {\n const x = start + ((end - start) * i) / segments;\n const value = fn(x);\n if (!Number.isFinite(value)) continue;\n if (value === 0) return { lower: x, upper: x };\n if (prevValue !== undefined && prevX !== undefined && prevValue * value < 0) {\n return { lower: prevX, upper: x };\n }\n prevX = x;\n prevValue = value;\n }\n return undefined;\n };\n\n let lower = lowerBound;\n let upper = upperBound;\n for (let i = 0; i < 20; i++) {\n const bracket = scan(lower, upper);\n if (bracket !== undefined) return bracket;\n lower = Math.max(-0.999999999, (lower - 1) / 2);\n upper = upper * 2 + 1;\n }\n\n return scan(lower, upper, 400);\n}\n","import { assertFiniteNumber, assertNonNegative, assertPositive } from \"../utils/assertions.js\";\n\nexport type LoanPaymentParams = {\n principal: number;\n annualRate: number;\n paymentsPerYear: number;\n years: number;\n};\n\n/**\n * Fixed periodic payment for an amortizing loan.\n *\n * - `annualRate` is nominal annual rate (e.g. 0.06 for 6%)\n * - payment returned is per period (`paymentsPerYear`)\n */\nexport function loanPayment(params: LoanPaymentParams): number {\n const { principal, annualRate, paymentsPerYear, years } = params;\n assertNonNegative(principal, \"principal\");\n assertFiniteNumber(annualRate, \"annualRate\");\n assertPositive(paymentsPerYear, \"paymentsPerYear\");\n assertNonNegative(years, \"years\");\n\n const n = Math.round(paymentsPerYear * years);\n if (n === 0) return 0;\n\n const r = annualRate / paymentsPerYear;\n if (r <= -1) {\n throw new RangeError(\"annualRate / paymentsPerYear must be > -1\");\n }\n if (r === 0) return principal / n;\n\n const value = (r * principal) / (1 - (1 + r) ** -n);\n if (!Number.isFinite(value)) {\n throw new RangeError(\"Numerical instability for given inputs\");\n }\n return value;\n}\n","import { assertNonNegative, assertPositive } from \"../utils/assertions.js\";\nimport { loanPayment } from \"./loanPayment.js\";\n\nexport type AmortizationScheduleParams = {\n principal: number;\n annualRate: number;\n paymentsPerYear: number;\n years: number;\n extraPaymentPerPeriod?: number;\n};\n\nexport type AmortizationRow = {\n period: number;\n payment: number;\n principalPayment: number;\n interestPayment: number;\n balance: number;\n};\n\nexport type AmortizationScheduleResult = {\n paymentPerPeriod: number;\n schedule: AmortizationRow[];\n totalPaid: number;\n totalInterest: number;\n};\n\nexport function amortizationSchedule(\n params: AmortizationScheduleParams,\n): AmortizationScheduleResult {\n const { principal, annualRate, paymentsPerYear, years, extraPaymentPerPeriod = 0 } = params;\n assertNonNegative(principal, \"principal\");\n assertPositive(paymentsPerYear, \"paymentsPerYear\");\n assertNonNegative(years, \"years\");\n assertNonNegative(extraPaymentPerPeriod, \"extraPaymentPerPeriod\");\n\n const scheduledN = Math.round(paymentsPerYear * years);\n if (scheduledN === 0 || principal === 0) {\n return { paymentPerPeriod: 0, schedule: [], totalPaid: 0, totalInterest: 0 };\n }\n\n const basePayment = loanPayment({ principal, annualRate, paymentsPerYear, years });\n const r = annualRate / paymentsPerYear;\n\n const schedule: AmortizationRow[] = [];\n let balance = principal;\n let totalPaid = 0;\n let totalInterest = 0;\n\n for (let period = 1; period <= scheduledN && balance > 0; period++) {\n const interestPayment = r === 0 ? 0 : balance * r;\n let payment = basePayment + extraPaymentPerPeriod;\n let principalPayment = payment - interestPayment;\n\n if (principalPayment > balance) {\n principalPayment = balance;\n payment = principalPayment + interestPayment;\n }\n\n balance = balance - principalPayment;\n if (Math.abs(balance) < 1e-12) balance = 0;\n\n totalPaid += payment;\n totalInterest += interestPayment;\n\n schedule.push({\n period,\n payment,\n principalPayment,\n interestPayment,\n balance,\n });\n }\n\n return {\n paymentPerPeriod: basePayment,\n schedule,\n totalPaid,\n totalInterest,\n };\n}\n","import { assertFiniteNumber, assertNonNegative, assertPositive } from \"../utils/assertions.js\";\n\nexport type PayoffPeriodWithExtraParams = {\n principal: number;\n annualRate: number;\n paymentsPerYear: number;\n basePaymentPerPeriod: number;\n extraPaymentPerPeriod: number;\n};\n\n/**\n * Number of periods until the loan is paid off with the given base + extra payment.\n */\nexport function payoffPeriodWithExtra(params: PayoffPeriodWithExtraParams): number {\n const { principal, annualRate, paymentsPerYear, basePaymentPerPeriod, extraPaymentPerPeriod } =\n params;\n\n assertNonNegative(principal, \"principal\");\n assertFiniteNumber(annualRate, \"annualRate\");\n assertPositive(paymentsPerYear, \"paymentsPerYear\");\n assertNonNegative(basePaymentPerPeriod, \"basePaymentPerPeriod\");\n assertNonNegative(extraPaymentPerPeriod, \"extraPaymentPerPeriod\");\n\n if (principal <= 0) return 0;\n const payment = basePaymentPerPeriod + extraPaymentPerPeriod;\n if (payment <= 0) return Number.POSITIVE_INFINITY;\n\n const r = annualRate / paymentsPerYear;\n let balance = principal;\n let period = 0;\n\n while (balance > 1e-12 && period < 100000) {\n const interest = r > 0 ? balance * r : 0;\n if (payment <= interest) return Number.POSITIVE_INFINITY;\n const principalPaid = Math.min(payment - interest, balance);\n balance -= principalPaid;\n period++;\n }\n return balance <= 1e-12 ? period : Number.POSITIVE_INFINITY;\n}\n","import { assertNonNegative, assertPositive } from \"../utils/assertions.js\";\nimport { loanPayment } from \"./loanPayment.js\";\n\nexport type RemainingBalanceParams = {\n principal: number;\n annualRate: number;\n paymentsPerYear: number;\n years: number;\n afterPeriodNumber: number;\n};\n\n/**\n * Remaining balance after a given number of payments on an amortizing loan.\n */\nexport function remainingBalance(params: RemainingBalanceParams): number {\n const { principal, annualRate, paymentsPerYear, years, afterPeriodNumber } = params;\n assertNonNegative(principal, \"principal\");\n assertPositive(paymentsPerYear, \"paymentsPerYear\");\n assertNonNegative(years, \"years\");\n assertNonNegative(afterPeriodNumber, \"afterPeriodNumber\");\n\n const n = Math.round(paymentsPerYear * years);\n if (n === 0 || afterPeriodNumber >= n) return 0;\n if (afterPeriodNumber <= 0) return principal;\n\n const payment = loanPayment({ principal, annualRate, paymentsPerYear, years });\n const r = annualRate / paymentsPerYear;\n const k = afterPeriodNumber;\n\n if (r === 0) return Math.max(0, principal - payment * k);\n const balance = principal * (1 + r) ** k - payment * (((1 + r) ** k - 1) / r);\n return Math.max(0, balance);\n}\n","import { assertFiniteNumber } from \"./assertions.js\";\n\nexport type RoundToCurrencyParams = {\n value: number;\n /** Decimal places. Default 2. */\n decimals?: number;\n /** 'half-up': 0.5 rounds up. 'half-even': banker's rounding. Default 'half-up'. */\n mode?: \"half-up\" | \"half-even\";\n};\n\n/**\n * Rounds a number to currency (default 2 decimals). half-up: 2.125 -> 2.13. half-even: 2.125 -> 2.12.\n */\nexport function roundToCurrency(params: RoundToCurrencyParams): number {\n const { value, decimals = 2, mode = \"half-up\" } = params;\n assertFiniteNumber(value, \"value\");\n const d = Math.max(0, Math.floor(decimals));\n const factor = 10 ** d;\n if (mode === \"half-even\") {\n const scaled = value * factor;\n const sign = scaled < 0 ? -1 : 1;\n const absScaled = Math.abs(scaled);\n const floorAbs = Math.floor(absScaled);\n const fraction = absScaled - floorAbs;\n const epsilon = 1e-12;\n if (Math.abs(fraction - 0.5) <= epsilon) {\n const nearestEven = floorAbs % 2 === 0 ? floorAbs : floorAbs + 1;\n return (sign * nearestEven) / factor;\n }\n return Math.round(scaled) / factor;\n }\n return Math.round(value * factor) / factor;\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/utils/assertions.ts","../src/interest/cagr.ts","../src/interest/compound.ts","../src/interest/effectiveAnnualRate.ts","../src/interest/futureValue.ts","../src/interest/inflationAdjustedAmount.ts","../src/interest/investmentGrowth.ts","../src/utils/solvers.ts","../src/interest/irr.ts","../src/interest/npv.ts","../src/interest/paymentFromPresentValue.ts","../src/interest/periodsToReachGoal.ts","../src/interest/presentValue.ts","../src/interest/presentValueOfAnnuity.ts","../src/interest/rateToReachGoal.ts","../src/interest/realReturn.ts","../src/interest/ruleOf72.ts","../src/interest/tvom.ts","../src/loans/loanPayment.ts","../src/loans/amortizationSchedule.ts","../src/loans/payoffPeriodWithExtra.ts","../src/loans/remainingBalance.ts","../src/utils/roundToCurrency.ts"],"names":["rate","presentValue","futureValue","pmt","fv","pv","assertContributionTiming","findBracket"],"mappings":"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","file":"index.js","sourcesContent":["export function assertFiniteNumber(value: number, name: string): void {\n if (!Number.isFinite(value)) {\n throw new RangeError(`${name} must be a finite number`);\n }\n}\n\nexport function assertNonNegative(value: number, name: string): void {\n assertFiniteNumber(value, name);\n if (value < 0) {\n throw new RangeError(`${name} must be >= 0`);\n }\n}\n\nexport function assertPositive(value: number, name: string): void {\n assertFiniteNumber(value, name);\n if (value <= 0) {\n throw new RangeError(`${name} must be > 0`);\n }\n}\n","import { assertPositive } from \"../utils/assertions.js\";\n\nexport type CagrParams = {\n startValue: number;\n endValue: number;\n years: number;\n};\n\n/**\n * Compound annual growth rate (CAGR) between start and end value over the given years.\n * CAGR = (endValue/startValue)^(1/years) - 1\n */\nexport function cagr(params: CagrParams): number {\n const { startValue, endValue, years } = params;\n assertPositive(startValue, \"startValue\");\n assertPositive(years, \"years\");\n if (endValue <= 0) return -1;\n return (endValue / startValue) ** (1 / years) - 1;\n}\n","import { assertNonNegative, assertPositive } from \"../utils/assertions.js\";\n\nexport type CompoundParams = {\n principal: number;\n rate: number;\n timesPerYear: number;\n years: number;\n};\n\n/**\n * Computes compound growth using nominal annual `rate` compounded `timesPerYear`.\n * Returns the final amount (principal + interest).\n */\nexport function compound(params: CompoundParams): number {\n const { principal, rate, timesPerYear, years } = params;\n assertNonNegative(principal, \"principal\");\n assertPositive(timesPerYear, \"timesPerYear\");\n assertNonNegative(years, \"years\");\n\n if (rate === 0 || years === 0) return principal;\n\n const n = timesPerYear;\n const t = years;\n return principal * (1 + rate / n) ** (n * t);\n}\n","import { assertFiniteNumber, assertPositive } from \"../utils/assertions.js\";\n\nexport type EffectiveAnnualRateParams = {\n nominalRate: number;\n timesPerYear: number;\n};\n\n/**\n * Converts a nominal annual rate to effective annual rate (EAR).\n * EAR = (1 + nominalRate/timesPerYear)^timesPerYear - 1\n */\nexport function effectiveAnnualRate(params: EffectiveAnnualRateParams): number {\n const { nominalRate, timesPerYear } = params;\n assertFiniteNumber(nominalRate, \"nominalRate\");\n assertPositive(timesPerYear, \"timesPerYear\");\n\n const r = nominalRate / timesPerYear;\n return (1 + r) ** timesPerYear - 1;\n}\n","import { assertNonNegative, assertPositive } from \"../utils/assertions.js\";\n\nexport type FutureValueParams = {\n presentValue: number;\n rate: number;\n timesPerYear: number;\n years: number;\n};\n\n/**\n * Future value of a lump sum using nominal annual `rate` compounded `timesPerYear`.\n */\nexport function futureValue(params: FutureValueParams): number {\n const { presentValue, rate, timesPerYear, years } = params;\n assertNonNegative(presentValue, \"presentValue\");\n assertPositive(timesPerYear, \"timesPerYear\");\n assertNonNegative(years, \"years\");\n\n if (rate === 0 || years === 0) return presentValue;\n\n const n = timesPerYear;\n const t = years;\n return presentValue * (1 + rate / n) ** (n * t);\n}\n","import { assertFiniteNumber, assertNonNegative } from \"../utils/assertions.js\";\n\nexport type InflationAdjustedAmountParams = {\n amount: number;\n annualInflationRate: number;\n years: number;\n direction: \"toPast\" | \"toFuture\";\n};\n\n/**\n * Purchasing power across time. toPast: amount/(1+rate)^years. toFuture: amount*(1+rate)^years.\n */\nexport function inflationAdjustedAmount(params: InflationAdjustedAmountParams): number {\n const { amount, annualInflationRate, years, direction } = params;\n assertFiniteNumber(amount, \"amount\");\n assertFiniteNumber(annualInflationRate, \"annualInflationRate\");\n assertNonNegative(years, \"years\");\n const factor = (1 + annualInflationRate) ** years;\n return direction === \"toPast\" ? amount / factor : amount * factor;\n}\n","import { assertNonNegative, assertPositive } from \"../utils/assertions.js\";\n\nexport type InvestmentGrowthParams = {\n initial: number;\n contributionPerPeriod?: number;\n rate: number;\n timesPerYear: number;\n years: number;\n contributionTiming?: \"end\" | \"begin\";\n};\n\nexport type InvestmentGrowthResult = {\n futureValue: number;\n totalContributions: number;\n totalInterest: number;\n};\n\n/**\n * Future value of an investment with optional periodic contributions.\n *\n * - `rate` is nominal annual rate (e.g. 0.05 for 5%)\n * - contributions occur each compounding period (`timesPerYear`)\n */\nexport function investmentGrowth(params: InvestmentGrowthParams): InvestmentGrowthResult {\n const {\n initial,\n contributionPerPeriod = 0,\n rate,\n timesPerYear,\n years,\n contributionTiming = \"end\",\n } = params;\n\n assertNonNegative(initial, \"initial\");\n assertNonNegative(contributionPerPeriod, \"contributionPerPeriod\");\n assertPositive(timesPerYear, \"timesPerYear\");\n assertNonNegative(years, \"years\");\n\n const periods = Math.round(timesPerYear * years);\n if (periods === 0) {\n return {\n futureValue: initial,\n totalContributions: 0,\n totalInterest: 0,\n };\n }\n\n const r = rate / timesPerYear;\n\n // Lump sum growth\n const fvInitial = rate === 0 ? initial : initial * (1 + r) ** periods;\n\n // Annuity future value (ordinary vs due)\n let fvContrib = 0;\n if (contributionPerPeriod !== 0) {\n if (rate === 0) {\n fvContrib = contributionPerPeriod * periods;\n } else {\n const ordinary = contributionPerPeriod * (((1 + r) ** periods - 1) / r);\n fvContrib = contributionTiming === \"begin\" ? ordinary * (1 + r) : ordinary;\n }\n }\n\n const futureValue = fvInitial + fvContrib;\n const totalContributions = contributionPerPeriod * periods;\n const totalInterest = futureValue - initial - totalContributions;\n\n return { futureValue, totalContributions, totalInterest };\n}\n","export type NewtonRaphsonParams = {\n initialGuess: number;\n fn: (x: number) => number;\n derivative: (x: number) => number;\n tolerance?: number;\n maxIterations?: number;\n min?: number;\n max?: number;\n};\n\nexport function newtonRaphson(params: NewtonRaphsonParams): number | undefined {\n const {\n initialGuess,\n fn,\n derivative,\n tolerance = 1e-10,\n maxIterations = 100,\n min = Number.NEGATIVE_INFINITY,\n max = Number.POSITIVE_INFINITY,\n } = params;\n\n let x = initialGuess;\n for (let i = 0; i < maxIterations; i++) {\n const value = fn(x);\n if (!Number.isFinite(value)) return undefined;\n if (Math.abs(value) <= tolerance) return x;\n\n const slope = derivative(x);\n if (!Number.isFinite(slope) || Math.abs(slope) < 1e-14) return undefined;\n\n x -= value / slope;\n if (x < min) x = min;\n if (x > max) x = max;\n }\n\n return undefined;\n}\n\nexport type BisectionParams = {\n fn: (x: number) => number;\n lower: number;\n upper: number;\n tolerance?: number;\n maxIterations?: number;\n};\n\nexport function bisection(params: BisectionParams): number | undefined {\n const { fn, lower, upper, tolerance = 1e-10, maxIterations = 200 } = params;\n let a = lower;\n let b = upper;\n let fa = fn(a);\n let fb = fn(b);\n\n if (!Number.isFinite(fa) || !Number.isFinite(fb) || fa * fb > 0) return undefined;\n if (Math.abs(fa) <= tolerance) return a;\n if (Math.abs(fb) <= tolerance) return b;\n\n for (let i = 0; i < maxIterations; i++) {\n const c = (a + b) / 2;\n const fc = fn(c);\n if (!Number.isFinite(fc)) return undefined;\n if (Math.abs(fc) <= tolerance || Math.abs(b - a) <= tolerance) return c;\n\n if (fa * fc < 0) {\n b = c;\n fb = fc;\n } else {\n a = c;\n fa = fc;\n }\n }\n\n return (a + b) / 2;\n}\n","import { assertFiniteNumber } from \"../utils/assertions.js\";\nimport { bisection, newtonRaphson } from \"../utils/solvers.js\";\n\nexport type IrrParams = {\n cashFlows: number[];\n guess?: number;\n maxIterations?: number;\n lowerBound?: number;\n upperBound?: number;\n};\n\nfunction npvAt(rate: number, cashFlows: number[]): number {\n let sum = 0;\n for (let t = 0; t < cashFlows.length; t++) {\n const cf = cashFlows[t];\n if (cf !== undefined) sum += cf / (1 + rate) ** t;\n }\n return sum;\n}\n\nfunction npvDerivativeAt(rate: number, cashFlows: number[]): number {\n let sum = 0;\n for (let t = 1; t < cashFlows.length; t++) {\n const cf = cashFlows[t];\n if (cf !== undefined) sum -= (t * cf) / (1 + rate) ** (t + 1);\n }\n return sum;\n}\n\nfunction hasPositiveAndNegative(cashFlows: number[]): boolean {\n let hasPositive = false;\n let hasNegative = false;\n for (const cf of cashFlows) {\n if (cf > 0) hasPositive = true;\n if (cf < 0) hasNegative = true;\n if (hasPositive && hasNegative) return true;\n }\n return false;\n}\n\nfunction findBracket(\n fn: (x: number) => number,\n lowerBound: number,\n upperBound: number,\n): { lower: number; upper: number } | undefined {\n const scan = (\n start: number,\n end: number,\n segments = 200,\n ): { lower: number; upper: number } | undefined => {\n let prevX: number | undefined;\n let prevValue: number | undefined;\n for (let i = 0; i <= segments; i++) {\n const x = start + ((end - start) * i) / segments;\n const value = fn(x);\n if (!Number.isFinite(value)) continue;\n if (value === 0) return { lower: x, upper: x };\n if (prevX !== undefined && prevValue !== undefined && prevValue * value < 0) {\n return { lower: prevX, upper: x };\n }\n prevX = x;\n prevValue = value;\n }\n return undefined;\n };\n\n let lower = lowerBound;\n let upper = upperBound;\n for (let i = 0; i < 20; i++) {\n const bracket = scan(lower, upper);\n if (bracket !== undefined) return bracket;\n lower = Math.max(-0.999999999, (lower - 1) / 2);\n upper = upper * 2 + 1;\n }\n\n return scan(lower, upper, 400);\n}\n\nexport function irr(params: IrrParams): number {\n const {\n cashFlows,\n guess = 0.1,\n maxIterations = 100,\n lowerBound = -0.99,\n upperBound = 10,\n } = params;\n if (cashFlows.length === 0) {\n throw new RangeError(\"cashFlows must contain at least one value\");\n }\n assertFiniteNumber(guess, \"guess\");\n assertFiniteNumber(maxIterations, \"maxIterations\");\n assertFiniteNumber(lowerBound, \"lowerBound\");\n assertFiniteNumber(upperBound, \"upperBound\");\n if (maxIterations <= 0 || !Number.isInteger(maxIterations)) {\n throw new RangeError(\"maxIterations must be a positive integer\");\n }\n if (lowerBound <= -1) {\n throw new RangeError(\"lowerBound must be > -1\");\n }\n if (upperBound <= lowerBound) {\n throw new RangeError(\"upperBound must be greater than lowerBound\");\n }\n\n for (const cf of cashFlows) assertFiniteNumber(cf, \"cashFlows[]\");\n if (!hasPositiveAndNegative(cashFlows)) {\n throw new RangeError(\"cashFlows must include at least one positive and one negative value\");\n }\n\n const fn = (rate: number) => npvAt(rate, cashFlows);\n const derivative = (rate: number) => npvDerivativeAt(rate, cashFlows);\n\n const newton = newtonRaphson({\n initialGuess: guess,\n fn,\n derivative,\n tolerance: 1e-10,\n maxIterations,\n min: lowerBound,\n max: upperBound,\n });\n if (newton !== undefined) return newton;\n\n const bracket = findBracket(fn, lowerBound, upperBound);\n if (bracket === undefined) {\n throw new RangeError(\"IRR did not converge within search bounds\");\n }\n if (bracket.lower === bracket.upper) return bracket.lower;\n\n const bisected = bisection({\n fn,\n lower: bracket.lower,\n upper: bracket.upper,\n tolerance: 1e-10,\n maxIterations: maxIterations * 2,\n });\n if (bisected !== undefined) return bisected;\n\n throw new RangeError(\"IRR did not converge\");\n}\n","import { assertFiniteNumber } from \"../utils/assertions.js\";\n\nexport type NpvParams = {\n rate: number;\n cashFlows: number[];\n};\n\n/**\n * Net present value at a discount `rate`.\n * cashFlows[0] is the period-0 cash flow.\n */\nexport function npv(params: NpvParams): number {\n const { rate, cashFlows } = params;\n assertFiniteNumber(rate, \"rate\");\n if (rate <= -1) throw new RangeError(\"rate must be > -1\");\n if (cashFlows.length === 0) return 0;\n\n let sum = 0;\n for (let t = 0; t < cashFlows.length; t++) {\n const cf = cashFlows[t];\n if (cf === undefined) continue;\n assertFiniteNumber(cf, `cashFlows[${t}]`);\n sum += cf / (1 + rate) ** t;\n }\n return sum;\n}\n","import { assertNonNegative } from \"../utils/assertions.js\";\n\nexport type PaymentFromPresentValueParams = {\n presentValue: number;\n ratePerPeriod: number;\n periods: number;\n /** Payment at start of each period (annuity due). Default end (ordinary). */\n timing?: \"end\" | \"begin\";\n};\n\n/**\n * Periodic payment required to pay off a present value (e.g. loan) over periods.\n * PMT = PV * r / (1 - (1+r)^-n). For due: divide by (1+r).\n */\nexport function paymentFromPresentValue(params: PaymentFromPresentValueParams): number {\n const { presentValue, ratePerPeriod, periods, timing = \"end\" } = params;\n assertNonNegative(presentValue, \"presentValue\");\n assertNonNegative(periods, \"periods\");\n\n if (presentValue === 0 || periods === 0) return 0;\n if (ratePerPeriod === 0) {\n const pmt = presentValue / periods;\n return timing === \"begin\" ? pmt / (1 + ratePerPeriod) : pmt;\n }\n let pmt = (ratePerPeriod * presentValue) / (1 - (1 + ratePerPeriod) ** -periods);\n if (timing === \"begin\") pmt /= 1 + ratePerPeriod;\n return pmt;\n}\n","import { assertFiniteNumber, assertNonNegative, assertPositive } from \"../utils/assertions.js\";\n\nexport type PeriodsToReachGoalParams = {\n principal: number;\n targetFutureValue: number;\n rate: number;\n timesPerYear: number;\n contributionPerPeriod?: number;\n contributionTiming?: \"end\" | \"begin\";\n maxPeriods?: number;\n};\n\nfunction assertContributionTiming(value: \"end\" | \"begin\", name: string): void {\n if (value !== \"end\" && value !== \"begin\") {\n throw new RangeError(`${name} must be \"end\" or \"begin\"`);\n }\n}\n\n/**\n * Number of compounding periods until future value reaches the goal.\n * With no contributions: closed form. With contributions: iterative.\n */\nexport function periodsToReachGoal(params: PeriodsToReachGoalParams): number {\n const {\n principal,\n targetFutureValue,\n rate,\n timesPerYear,\n contributionPerPeriod = 0,\n contributionTiming = \"end\",\n maxPeriods = 100000,\n } = params;\n\n assertNonNegative(principal, \"principal\");\n assertNonNegative(targetFutureValue, \"targetFutureValue\");\n assertFiniteNumber(rate, \"rate\");\n assertPositive(timesPerYear, \"timesPerYear\");\n assertNonNegative(contributionPerPeriod, \"contributionPerPeriod\");\n assertPositive(maxPeriods, \"maxPeriods\");\n assertContributionTiming(contributionTiming, \"contributionTiming\");\n\n if (targetFutureValue <= principal) return 0;\n\n const r = rate / timesPerYear;\n if (r <= -1) {\n throw new RangeError(\"rate / timesPerYear must be > -1\");\n }\n\n if (contributionPerPeriod === 0) {\n if (principal === 0) return Number.POSITIVE_INFINITY;\n if (rate === 0) return targetFutureValue <= principal ? 0 : Number.POSITIVE_INFINITY;\n if (r < 0) return Number.POSITIVE_INFINITY;\n const n = Math.log(targetFutureValue / principal) / Math.log(1 + r);\n return Number.isFinite(n) && n >= 0 ? Math.ceil(n) : Number.POSITIVE_INFINITY;\n }\n\n if (rate === 0) {\n const needed = targetFutureValue - principal;\n if (needed <= 0) return 0;\n return Math.ceil(needed / contributionPerPeriod);\n }\n\n // With contributions: iterate until FV >= target\n let fv = principal;\n let periods = 0;\n while (fv < targetFutureValue && periods < maxPeriods) {\n if (contributionTiming === \"begin\") fv += contributionPerPeriod;\n fv = fv * (1 + r) + (contributionTiming === \"end\" ? contributionPerPeriod : 0);\n periods++;\n }\n if (fv >= targetFutureValue) return periods;\n throw new RangeError(\"maxPeriods exceeded before reaching target\");\n}\n","import { assertNonNegative, assertPositive } from \"../utils/assertions.js\";\n\nexport type PresentValueParams = {\n futureValue: number;\n rate: number;\n timesPerYear: number;\n years: number;\n};\n\n/**\n * Present value of a lump sum using nominal annual `rate` compounded `timesPerYear`.\n */\nexport function presentValue(params: PresentValueParams): number {\n const { futureValue: fv, rate, timesPerYear, years } = params;\n assertNonNegative(fv, \"futureValue\");\n assertPositive(timesPerYear, \"timesPerYear\");\n assertNonNegative(years, \"years\");\n\n if (rate === 0 || years === 0) return fv;\n\n const n = timesPerYear;\n const t = years;\n return fv / (1 + rate / n) ** (n * t);\n}\n","import { assertNonNegative } from \"../utils/assertions.js\";\n\nexport type PresentValueOfAnnuityParams = {\n paymentPerPeriod: number;\n ratePerPeriod: number;\n periods: number;\n timing?: \"end\" | \"begin\";\n};\n\n/**\n * Present value of an annuity. PV = PMT * (1 - (1+r)^-n) / r. Due: multiply by (1+r).\n */\nexport function presentValueOfAnnuity(params: PresentValueOfAnnuityParams): number {\n const { paymentPerPeriod, ratePerPeriod, periods, timing = \"end\" } = params;\n assertNonNegative(paymentPerPeriod, \"paymentPerPeriod\");\n assertNonNegative(periods, \"periods\");\n\n if (periods === 0) return 0;\n if (ratePerPeriod === 0) {\n const pv = paymentPerPeriod * periods;\n return timing === \"begin\" ? pv * (1 + ratePerPeriod) : pv;\n }\n const pv = (paymentPerPeriod * (1 - (1 + ratePerPeriod) ** -periods)) / ratePerPeriod;\n return timing === \"begin\" ? pv * (1 + ratePerPeriod) : pv;\n}\n","import { assertFiniteNumber, assertNonNegative, assertPositive } from \"../utils/assertions.js\";\nimport { bisection, newtonRaphson } from \"../utils/solvers.js\";\n\nexport type RateToReachGoalParams = {\n principal: number;\n targetFutureValue: number;\n periods: number;\n contributionPerPeriod?: number;\n contributionTiming?: \"end\" | \"begin\";\n lowerBound?: number;\n upperBound?: number;\n maxIterations?: number;\n tolerance?: number;\n};\n\nfunction assertContributionTiming(value: \"end\" | \"begin\", name: string): void {\n if (value !== \"end\" && value !== \"begin\") {\n throw new RangeError(`${name} must be \"end\" or \"begin\"`);\n }\n}\n\n/**\n * Rate per period required to reach target future value in given periods.\n * Uses Newton-Raphson when contributions are present; closed form for lump sum.\n */\nexport function rateToReachGoal(params: RateToReachGoalParams): number {\n const {\n principal,\n targetFutureValue,\n periods,\n contributionPerPeriod = 0,\n contributionTiming = \"end\",\n lowerBound = -0.99,\n upperBound = 10,\n maxIterations = 100,\n tolerance = 1e-10,\n } = params;\n\n assertNonNegative(principal, \"principal\");\n assertNonNegative(targetFutureValue, \"targetFutureValue\");\n assertPositive(periods, \"periods\");\n assertNonNegative(contributionPerPeriod, \"contributionPerPeriod\");\n assertFiniteNumber(lowerBound, \"lowerBound\");\n assertFiniteNumber(upperBound, \"upperBound\");\n assertFiniteNumber(maxIterations, \"maxIterations\");\n assertFiniteNumber(tolerance, \"tolerance\");\n assertContributionTiming(contributionTiming, \"contributionTiming\");\n if (lowerBound <= -1) throw new RangeError(\"lowerBound must be > -1\");\n if (upperBound <= lowerBound) throw new RangeError(\"upperBound must be greater than lowerBound\");\n if (!Number.isInteger(maxIterations) || maxIterations <= 0) {\n throw new RangeError(\"maxIterations must be a positive integer\");\n }\n if (tolerance <= 0) throw new RangeError(\"tolerance must be > 0\");\n\n if (targetFutureValue <= principal && contributionPerPeriod === 0) return 0;\n\n if (contributionPerPeriod === 0) {\n if (targetFutureValue <= principal) return 0;\n if (principal === 0) {\n throw new RangeError(\n \"rateToReachGoal is undefined when principal is 0 and contributions are 0\",\n );\n }\n return (targetFutureValue / principal) ** (1 / periods) - 1;\n }\n\n const dueFactor = contributionTiming === \"begin\" ? 1 : 0;\n const fn = (r: number) => {\n const onePlusR = 1 + r;\n const onePlusRN = onePlusR ** periods;\n const fvLump = principal * onePlusRN;\n const annuityBase = r === 0 ? periods : (onePlusRN - 1) / r;\n const fvAnnuity = contributionPerPeriod * annuityBase * (1 + dueFactor * r);\n return fvLump + fvAnnuity - targetFutureValue;\n };\n const derivative = (r: number) => {\n const delta = Math.abs(r) > 1e-6 ? Math.abs(r) * 1e-6 : 1e-6;\n return (fn(r + delta) - fn(r - delta)) / (2 * delta);\n };\n\n const initialGuess =\n (targetFutureValue / (principal + contributionPerPeriod * periods)) ** (1 / periods) - 1;\n\n const newton = newtonRaphson({\n initialGuess: Number.isFinite(initialGuess) ? Math.max(initialGuess, lowerBound) : 0.01,\n fn,\n derivative,\n tolerance,\n maxIterations,\n min: lowerBound,\n max: upperBound,\n });\n if (newton !== undefined) return newton;\n\n const bracket = findBracket(fn, lowerBound, upperBound);\n if (bracket === undefined) {\n throw new RangeError(\"rateToReachGoal did not converge within search bounds\");\n }\n if (bracket.lower === bracket.upper) return bracket.lower;\n\n const bisected = bisection({\n fn,\n lower: bracket.lower,\n upper: bracket.upper,\n tolerance,\n maxIterations: maxIterations * 2,\n });\n if (bisected !== undefined) return bisected;\n throw new RangeError(\"rateToReachGoal did not converge\");\n}\n\nfunction findBracket(\n fn: (x: number) => number,\n lowerBound: number,\n upperBound: number,\n): { lower: number; upper: number } | undefined {\n const scan = (\n start: number,\n end: number,\n segments = 200,\n ): { lower: number; upper: number } | undefined => {\n let prevX: number | undefined;\n let prevValue: number | undefined;\n for (let i = 0; i <= segments; i++) {\n const x = start + ((end - start) * i) / segments;\n const value = fn(x);\n if (!Number.isFinite(value)) continue;\n if (value === 0) return { lower: x, upper: x };\n if (prevX !== undefined && prevValue !== undefined && prevValue * value < 0) {\n return { lower: prevX, upper: x };\n }\n prevX = x;\n prevValue = value;\n }\n return undefined;\n };\n\n let lower = lowerBound;\n let upper = upperBound;\n for (let i = 0; i < 20; i++) {\n const bracket = scan(lower, upper);\n if (bracket !== undefined) return bracket;\n lower = Math.max(-0.999999999, (lower - 1) / 2);\n upper = upper * 2 + 1;\n }\n\n return scan(lower, upper, 400);\n}\n","import { assertFiniteNumber } from \"../utils/assertions.js\";\n\nexport type RealReturnParams = { nominalReturn: number; inflationRate: number };\n\nexport function realReturn(params: RealReturnParams): number {\n const { nominalReturn, inflationRate } = params;\n assertFiniteNumber(nominalReturn, \"nominalReturn\");\n assertFiniteNumber(inflationRate, \"inflationRate\");\n if (inflationRate <= -1) return NaN;\n return (1 + nominalReturn) / (1 + inflationRate) - 1;\n}\n","import { assertFiniteNumber, assertPositive } from \"../utils/assertions.js\";\n\nexport type RuleOf72Params = {\n rate: number;\n /** Use 69 for continuous-ish approximation (e.g. daily compounding). Default 72. */\n constant?: 72 | 69;\n};\n\n/**\n * Approximate years to double a lump sum at the given annual rate.\n * rate is decimal (e.g. 0.07 for 7%). Uses rule of 72 by default, or 69 if specified.\n */\nexport function ruleOf72(params: RuleOf72Params): number {\n const { rate, constant = 72 } = params;\n assertFiniteNumber(rate, \"rate\");\n assertPositive(rate, \"rate\");\n return constant / 100 / rate;\n}\n","import { assertFiniteNumber, assertPositive } from \"../utils/assertions.js\";\nimport { bisection, newtonRaphson } from \"../utils/solvers.js\";\n\ntype PaymentTiming = \"end\" | \"begin\";\n\nfunction assertTiming(value: PaymentTiming, name: string): void {\n if (value !== \"end\" && value !== \"begin\") {\n throw new RangeError(`${name} must be \"end\" or \"begin\"`);\n }\n}\n\nfunction annuityDueFactor(ratePerPeriod: number, timing: PaymentTiming): number {\n return timing === \"begin\" ? 1 + ratePerPeriod : 1;\n}\n\nfunction futureValueFromCashFlows(\n ratePerPeriod: number,\n periods: number,\n payment: number,\n presentValue: number,\n timing: PaymentTiming,\n): number {\n if (ratePerPeriodIsInvalidForDomain(ratePerPeriod)) {\n throw new RangeError(\"ratePerPeriod must be > -1\");\n }\n if (ratePerPeriod === 0) return -(presentValue + payment * periods);\n\n const growth = (1 + ratePerPeriod) ** periods;\n if (!Number.isFinite(growth) || growth <= 0) return Number.NaN;\n const paymentFv =\n payment * ((growth - 1) / ratePerPeriod) * annuityDueFactor(ratePerPeriod, timing);\n return -(presentValue * growth + paymentFv);\n}\n\nexport type FvParams = {\n ratePerPeriod: number;\n periods: number;\n payment?: number;\n presentValue: number;\n timing?: PaymentTiming;\n};\n\n/**\n * Excel FV equivalent.\n */\nexport function fv(params: FvParams): number {\n const { ratePerPeriod, periods, payment = 0, presentValue, timing = \"end\" } = params;\n assertFiniteNumber(ratePerPeriod, \"ratePerPeriod\");\n assertPositive(periods, \"periods\");\n assertFiniteNumber(payment, \"payment\");\n assertFiniteNumber(presentValue, \"presentValue\");\n assertTiming(timing, \"timing\");\n\n const value = futureValueFromCashFlows(ratePerPeriod, periods, payment, presentValue, timing);\n if (!Number.isFinite(value)) {\n throw new RangeError(\"Numerical instability for given inputs\");\n }\n return value;\n}\n\nexport type PvParams = {\n ratePerPeriod: number;\n periods: number;\n payment?: number;\n futureValue?: number;\n timing?: PaymentTiming;\n};\n\n/**\n * Excel PV equivalent.\n */\nexport function pv(params: PvParams): number {\n const { ratePerPeriod, periods, payment = 0, futureValue = 0, timing = \"end\" } = params;\n assertFiniteNumber(ratePerPeriod, \"ratePerPeriod\");\n assertPositive(periods, \"periods\");\n assertFiniteNumber(payment, \"payment\");\n assertFiniteNumber(futureValue, \"futureValue\");\n assertTiming(timing, \"timing\");\n if (ratePerPeriodIsInvalidForDomain(ratePerPeriod)) {\n throw new RangeError(\"ratePerPeriod must be > -1\");\n }\n\n if (ratePerPeriod === 0) return -(futureValue + payment * periods);\n\n const growth = (1 + ratePerPeriod) ** periods;\n if (!Number.isFinite(growth) || growth <= 0) {\n throw new RangeError(\"Numerical instability for given ratePerPeriod/periods\");\n }\n const paymentPv =\n ((payment * (1 - 1 / growth)) / ratePerPeriod) * annuityDueFactor(ratePerPeriod, timing);\n const value = -futureValue / growth - paymentPv;\n if (!Number.isFinite(value)) {\n throw new RangeError(\"Numerical instability for given inputs\");\n }\n return value;\n}\n\nexport type PmtParams = {\n ratePerPeriod: number;\n periods: number;\n presentValue: number;\n futureValue?: number;\n timing?: PaymentTiming;\n};\n\n/**\n * Excel PMT equivalent.\n */\nexport function pmt(params: PmtParams): number {\n const { ratePerPeriod, periods, presentValue, futureValue = 0, timing = \"end\" } = params;\n assertFiniteNumber(ratePerPeriod, \"ratePerPeriod\");\n assertPositive(periods, \"periods\");\n assertFiniteNumber(presentValue, \"presentValue\");\n assertFiniteNumber(futureValue, \"futureValue\");\n assertTiming(timing, \"timing\");\n if (ratePerPeriodIsInvalidForDomain(ratePerPeriod)) {\n throw new RangeError(\"ratePerPeriod must be > -1\");\n }\n\n if (ratePerPeriod === 0) return -(presentValue + futureValue) / periods;\n\n const growth = (1 + ratePerPeriod) ** periods;\n if (!Number.isFinite(growth) || growth <= 0) {\n throw new RangeError(\"Numerical instability for given ratePerPeriod/periods\");\n }\n const numerator = -(futureValue + presentValue * growth) * ratePerPeriod;\n const denominator = (growth - 1) * annuityDueFactor(ratePerPeriod, timing);\n const value = numerator / denominator;\n if (!Number.isFinite(value)) {\n throw new RangeError(\"Numerical instability for given inputs\");\n }\n return value;\n}\n\nexport type NperParams = {\n ratePerPeriod: number;\n payment: number;\n presentValue: number;\n futureValue?: number;\n timing?: PaymentTiming;\n};\n\n/**\n * Excel NPER equivalent.\n */\nexport function nper(params: NperParams): number {\n const { ratePerPeriod, payment, presentValue, futureValue = 0, timing = \"end\" } = params;\n assertFiniteNumber(ratePerPeriod, \"ratePerPeriod\");\n assertFiniteNumber(payment, \"payment\");\n assertFiniteNumber(presentValue, \"presentValue\");\n assertFiniteNumber(futureValue, \"futureValue\");\n assertTiming(timing, \"timing\");\n if (ratePerPeriodIsInvalidForDomain(ratePerPeriod)) {\n throw new RangeError(\"ratePerPeriod must be > -1\");\n }\n\n if (ratePerPeriod === 0) {\n const linear = -(presentValue + futureValue) / payment;\n return Number.isFinite(linear) && linear >= 0 ? linear : Number.NaN;\n }\n\n const adjustedPayment = payment * annuityDueFactor(ratePerPeriod, timing);\n const numerator = adjustedPayment - futureValue * ratePerPeriod;\n const denominator = adjustedPayment + presentValue * ratePerPeriod;\n if (numerator === 0 || denominator === 0) return Number.NaN;\n const ratio = numerator / denominator;\n if (ratio <= 0) return Number.NaN;\n\n const periods = Math.log(ratio) / Math.log(1 + ratePerPeriod);\n return Number.isFinite(periods) ? periods : Number.NaN;\n}\n\nexport type RateParams = {\n periods: number;\n payment: number;\n presentValue: number;\n futureValue?: number;\n timing?: PaymentTiming;\n guess?: number;\n tolerance?: number;\n maxIterations?: number;\n lowerBound?: number;\n upperBound?: number;\n};\n\n/**\n * Excel RATE equivalent.\n */\nexport function rate(params: RateParams): number {\n const {\n periods,\n payment,\n presentValue,\n futureValue = 0,\n timing = \"end\",\n guess = 0.1,\n tolerance = 1e-10,\n maxIterations = 100,\n lowerBound = -0.999999999,\n upperBound = 10,\n } = params;\n assertPositive(periods, \"periods\");\n assertFiniteNumber(payment, \"payment\");\n assertFiniteNumber(presentValue, \"presentValue\");\n assertFiniteNumber(futureValue, \"futureValue\");\n assertFiniteNumber(guess, \"guess\");\n assertFiniteNumber(maxIterations, \"maxIterations\");\n assertFiniteNumber(lowerBound, \"lowerBound\");\n assertFiniteNumber(upperBound, \"upperBound\");\n assertTiming(timing, \"timing\");\n if (ratePerPeriodIsInvalidForDomain(lowerBound)) {\n throw new RangeError(\"lowerBound must be > -1\");\n }\n if (upperBound <= lowerBound) {\n throw new RangeError(\"upperBound must be greater than lowerBound\");\n }\n if (!Number.isInteger(maxIterations) || maxIterations <= 0) {\n throw new RangeError(\"maxIterations must be a positive integer\");\n }\n\n const fn = (r: number) =>\n futureValueFromCashFlows(r, periods, payment, presentValue, timing) - futureValue;\n const derivative = (r: number) => {\n const delta = Math.abs(r) > 1e-5 ? Math.abs(r) * 1e-6 : 1e-6;\n return (fn(r + delta) - fn(r - delta)) / (2 * delta);\n };\n\n const newton = newtonRaphson({\n initialGuess: guess,\n fn,\n derivative,\n tolerance,\n maxIterations,\n min: lowerBound,\n max: upperBound,\n });\n if (newton !== undefined) return newton;\n\n const bracket = findRateBracket(fn, lowerBound, upperBound);\n if (bracket === undefined) {\n throw new RangeError(\"RATE did not converge within search bounds\");\n }\n if (bracket.lower === bracket.upper) return bracket.lower;\n\n const bisected = bisection({\n fn,\n lower: bracket.lower,\n upper: bracket.upper,\n tolerance,\n maxIterations: maxIterations * 2,\n });\n if (bisected !== undefined) return bisected;\n\n throw new RangeError(\"RATE did not converge\");\n}\n\nfunction ratePerPeriodIsInvalidForDomain(ratePerPeriod: number): boolean {\n return ratePerPeriod <= -1;\n}\n\nfunction findRateBracket(\n fn: (x: number) => number,\n lowerBound: number,\n upperBound: number,\n): { lower: number; upper: number } | undefined {\n const scan = (\n start: number,\n end: number,\n segments = 200,\n ): { lower: number; upper: number } | undefined => {\n let prevX: number | undefined;\n let prevValue: number | undefined;\n for (let i = 0; i <= segments; i++) {\n const x = start + ((end - start) * i) / segments;\n const value = fn(x);\n if (!Number.isFinite(value)) continue;\n if (value === 0) return { lower: x, upper: x };\n if (prevValue !== undefined && prevX !== undefined && prevValue * value < 0) {\n return { lower: prevX, upper: x };\n }\n prevX = x;\n prevValue = value;\n }\n return undefined;\n };\n\n let lower = lowerBound;\n let upper = upperBound;\n for (let i = 0; i < 20; i++) {\n const bracket = scan(lower, upper);\n if (bracket !== undefined) return bracket;\n lower = Math.max(-0.999999999, (lower - 1) / 2);\n upper = upper * 2 + 1;\n }\n\n return scan(lower, upper, 400);\n}\n","import { assertFiniteNumber, assertNonNegative, assertPositive } from \"../utils/assertions.js\";\n\nexport type LoanPaymentParams = {\n principal: number;\n annualRate: number;\n paymentsPerYear: number;\n years: number;\n};\n\n/**\n * Fixed periodic payment for an amortizing loan.\n *\n * - `annualRate` is nominal annual rate (e.g. 0.06 for 6%)\n * - payment returned is per period (`paymentsPerYear`)\n */\nexport function loanPayment(params: LoanPaymentParams): number {\n const { principal, annualRate, paymentsPerYear, years } = params;\n assertNonNegative(principal, \"principal\");\n assertFiniteNumber(annualRate, \"annualRate\");\n assertPositive(paymentsPerYear, \"paymentsPerYear\");\n assertNonNegative(years, \"years\");\n\n const n = Math.round(paymentsPerYear * years);\n if (n === 0) return 0;\n\n const r = annualRate / paymentsPerYear;\n if (r <= -1) {\n throw new RangeError(\"annualRate / paymentsPerYear must be > -1\");\n }\n if (r === 0) return principal / n;\n\n const value = (r * principal) / (1 - (1 + r) ** -n);\n if (!Number.isFinite(value)) {\n throw new RangeError(\"Numerical instability for given inputs\");\n }\n return value;\n}\n","import { assertNonNegative, assertPositive } from \"../utils/assertions.js\";\nimport { loanPayment } from \"./loanPayment.js\";\n\nexport type AmortizationScheduleParams = {\n principal: number;\n annualRate: number;\n paymentsPerYear: number;\n years: number;\n extraPaymentPerPeriod?: number;\n};\n\nexport type AmortizationRow = {\n period: number;\n payment: number;\n principalPayment: number;\n interestPayment: number;\n balance: number;\n};\n\nexport type AmortizationScheduleResult = {\n paymentPerPeriod: number;\n schedule: AmortizationRow[];\n totalPaid: number;\n totalInterest: number;\n};\n\nexport function amortizationSchedule(\n params: AmortizationScheduleParams,\n): AmortizationScheduleResult {\n const { principal, annualRate, paymentsPerYear, years, extraPaymentPerPeriod = 0 } = params;\n assertNonNegative(principal, \"principal\");\n assertPositive(paymentsPerYear, \"paymentsPerYear\");\n assertNonNegative(years, \"years\");\n assertNonNegative(extraPaymentPerPeriod, \"extraPaymentPerPeriod\");\n\n const scheduledN = Math.round(paymentsPerYear * years);\n if (scheduledN === 0 || principal === 0) {\n return { paymentPerPeriod: 0, schedule: [], totalPaid: 0, totalInterest: 0 };\n }\n\n const basePayment = loanPayment({ principal, annualRate, paymentsPerYear, years });\n const r = annualRate / paymentsPerYear;\n\n const schedule: AmortizationRow[] = [];\n let balance = principal;\n let totalPaid = 0;\n let totalInterest = 0;\n\n for (let period = 1; period <= scheduledN && balance > 0; period++) {\n const interestPayment = r === 0 ? 0 : balance * r;\n let payment = basePayment + extraPaymentPerPeriod;\n let principalPayment = payment - interestPayment;\n\n if (principalPayment > balance) {\n principalPayment = balance;\n payment = principalPayment + interestPayment;\n }\n\n balance = balance - principalPayment;\n if (Math.abs(balance) < 1e-12) balance = 0;\n\n totalPaid += payment;\n totalInterest += interestPayment;\n\n schedule.push({\n period,\n payment,\n principalPayment,\n interestPayment,\n balance,\n });\n }\n\n return {\n paymentPerPeriod: basePayment,\n schedule,\n totalPaid,\n totalInterest,\n };\n}\n","import { assertFiniteNumber, assertNonNegative, assertPositive } from \"../utils/assertions.js\";\n\nexport type PayoffPeriodWithExtraParams = {\n principal: number;\n annualRate: number;\n paymentsPerYear: number;\n basePaymentPerPeriod: number;\n extraPaymentPerPeriod: number;\n};\n\n/**\n * Number of periods until the loan is paid off with the given base + extra payment.\n */\nexport function payoffPeriodWithExtra(params: PayoffPeriodWithExtraParams): number {\n const { principal, annualRate, paymentsPerYear, basePaymentPerPeriod, extraPaymentPerPeriod } =\n params;\n\n assertNonNegative(principal, \"principal\");\n assertFiniteNumber(annualRate, \"annualRate\");\n assertPositive(paymentsPerYear, \"paymentsPerYear\");\n assertNonNegative(basePaymentPerPeriod, \"basePaymentPerPeriod\");\n assertNonNegative(extraPaymentPerPeriod, \"extraPaymentPerPeriod\");\n\n if (principal <= 0) return 0;\n const payment = basePaymentPerPeriod + extraPaymentPerPeriod;\n if (payment <= 0) return Number.POSITIVE_INFINITY;\n\n const r = annualRate / paymentsPerYear;\n let balance = principal;\n let period = 0;\n\n while (balance > 1e-12 && period < 100000) {\n const interest = r > 0 ? balance * r : 0;\n if (payment <= interest) return Number.POSITIVE_INFINITY;\n const principalPaid = Math.min(payment - interest, balance);\n balance -= principalPaid;\n period++;\n }\n return balance <= 1e-12 ? period : Number.POSITIVE_INFINITY;\n}\n","import { assertNonNegative, assertPositive } from \"../utils/assertions.js\";\nimport { loanPayment } from \"./loanPayment.js\";\n\nexport type RemainingBalanceParams = {\n principal: number;\n annualRate: number;\n paymentsPerYear: number;\n years: number;\n afterPeriodNumber: number;\n};\n\n/**\n * Remaining balance after a given number of payments on an amortizing loan.\n */\nexport function remainingBalance(params: RemainingBalanceParams): number {\n const { principal, annualRate, paymentsPerYear, years, afterPeriodNumber } = params;\n assertNonNegative(principal, \"principal\");\n assertPositive(paymentsPerYear, \"paymentsPerYear\");\n assertNonNegative(years, \"years\");\n assertNonNegative(afterPeriodNumber, \"afterPeriodNumber\");\n\n const n = Math.round(paymentsPerYear * years);\n if (n === 0 || afterPeriodNumber >= n) return 0;\n if (afterPeriodNumber <= 0) return principal;\n\n const payment = loanPayment({ principal, annualRate, paymentsPerYear, years });\n const r = annualRate / paymentsPerYear;\n const k = afterPeriodNumber;\n\n if (r === 0) return Math.max(0, principal - payment * k);\n const balance = principal * (1 + r) ** k - payment * (((1 + r) ** k - 1) / r);\n return Math.max(0, balance);\n}\n","import { assertFiniteNumber } from \"./assertions.js\";\n\nexport type RoundToCurrencyParams = {\n value: number;\n /** Decimal places. Default 2. */\n decimals?: number;\n /** 'half-up': 0.5 rounds up. 'half-even': banker's rounding. Default 'half-up'. */\n mode?: \"half-up\" | \"half-even\";\n};\n\n/**\n * Rounds a number to currency (default 2 decimals). half-up: 2.125 -> 2.13. half-even: 2.125 -> 2.12.\n */\nexport function roundToCurrency(params: RoundToCurrencyParams): number {\n const { value, decimals = 2, mode = \"half-up\" } = params;\n assertFiniteNumber(value, \"value\");\n const d = Math.max(0, Math.floor(decimals));\n const factor = 10 ** d;\n if (mode === \"half-even\") {\n const scaled = value * factor;\n const sign = scaled < 0 ? -1 : 1;\n const absScaled = Math.abs(scaled);\n const floorAbs = Math.floor(absScaled);\n const fraction = absScaled - floorAbs;\n const epsilon = 1e-12;\n if (Math.abs(fraction - 0.5) <= epsilon) {\n const nearestEven = floorAbs % 2 === 0 ? floorAbs : floorAbs + 1;\n return (sign * nearestEven) / factor;\n }\n return Math.round(scaled) / factor;\n }\n return Math.round(value * factor) / factor;\n}\n"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pyverret/ratejs",
|
|
3
|
-
"version": "1.1.
|
|
3
|
+
"version": "1.1.3",
|
|
4
4
|
"description": "Lightweight, dependency-free TypeScript financial math library providing pure calculation utilities.",
|
|
5
5
|
"author": "Pierre-Yves Verret",
|
|
6
6
|
"license": "ISC",
|
|
@@ -50,7 +50,9 @@
|
|
|
50
50
|
"typecheck": "tsc -p tsconfig.json --noEmit",
|
|
51
51
|
"test": "vitest run",
|
|
52
52
|
"test:watch": "vitest",
|
|
53
|
-
"
|
|
53
|
+
"validate": "npm run lint && npm run typecheck && npm test && npm run build",
|
|
54
|
+
"release": "semantic-release",
|
|
55
|
+
"prepublishOnly": "npm run validate"
|
|
54
56
|
},
|
|
55
57
|
"publishConfig": {
|
|
56
58
|
"access": "public",
|
|
@@ -62,6 +64,8 @@
|
|
|
62
64
|
"devDependencies": {
|
|
63
65
|
"@biomejs/biome": "^2.4.4",
|
|
64
66
|
"@vitest/coverage-v8": "^3.2.4",
|
|
67
|
+
"conventional-changelog-conventionalcommits": "^8.0.0",
|
|
68
|
+
"semantic-release": "^24.2.9",
|
|
65
69
|
"tsup": "^8.5.0",
|
|
66
70
|
"typescript": "^5.9.2",
|
|
67
71
|
"vitest": "^3.2.4"
|