@uwmd/core 1.1.0
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 +79 -0
- package/dist/agents/bancroft.d.ts +32 -0
- package/dist/agents/bancroft.d.ts.map +1 -0
- package/dist/agents/bancroft.js +292 -0
- package/dist/agents/bancroft.js.map +1 -0
- package/dist/agents/schemas.d.ts +13 -0
- package/dist/agents/schemas.d.ts.map +1 -0
- package/dist/agents/schemas.js +74 -0
- package/dist/agents/schemas.js.map +1 -0
- package/dist/bindings.d.ts +85 -0
- package/dist/bindings.d.ts.map +1 -0
- package/dist/bindings.js +293 -0
- package/dist/bindings.js.map +1 -0
- package/dist/browser.d.ts +66 -0
- package/dist/browser.d.ts.map +1 -0
- package/dist/browser.js +53 -0
- package/dist/browser.js.map +1 -0
- package/dist/calc/builtins.d.ts +4 -0
- package/dist/calc/builtins.d.ts.map +1 -0
- package/dist/calc/builtins.js +329 -0
- package/dist/calc/builtins.js.map +1 -0
- package/dist/calc/dependencies.d.ts +34 -0
- package/dist/calc/dependencies.d.ts.map +1 -0
- package/dist/calc/dependencies.js +101 -0
- package/dist/calc/dependencies.js.map +1 -0
- package/dist/calc/errors.d.ts +8 -0
- package/dist/calc/errors.d.ts.map +1 -0
- package/dist/calc/errors.js +18 -0
- package/dist/calc/errors.js.map +1 -0
- package/dist/calc/evaluator.d.ts +5 -0
- package/dist/calc/evaluator.d.ts.map +1 -0
- package/dist/calc/evaluator.js +184 -0
- package/dist/calc/evaluator.js.map +1 -0
- package/dist/calc/index.d.ts +14 -0
- package/dist/calc/index.d.ts.map +1 -0
- package/dist/calc/index.js +56 -0
- package/dist/calc/index.js.map +1 -0
- package/dist/calc/parser.d.ts +32 -0
- package/dist/calc/parser.d.ts.map +1 -0
- package/dist/calc/parser.js +361 -0
- package/dist/calc/parser.js.map +1 -0
- package/dist/cascade.d.ts +85 -0
- package/dist/cascade.d.ts.map +1 -0
- package/dist/cascade.js +172 -0
- package/dist/cascade.js.map +1 -0
- package/dist/cli.d.ts +3 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +843 -0
- package/dist/cli.js.map +1 -0
- package/dist/codec.d.ts +25 -0
- package/dist/codec.d.ts.map +1 -0
- package/dist/codec.js +62 -0
- package/dist/codec.js.map +1 -0
- package/dist/codecs.d.ts +6 -0
- package/dist/codecs.d.ts.map +1 -0
- package/dist/codecs.js +12 -0
- package/dist/codecs.js.map +1 -0
- package/dist/compactor.d.ts +11 -0
- package/dist/compactor.d.ts.map +1 -0
- package/dist/compactor.js +84 -0
- package/dist/compactor.js.map +1 -0
- package/dist/context-profiles.d.ts +30 -0
- package/dist/context-profiles.d.ts.map +1 -0
- package/dist/context-profiles.js +225 -0
- package/dist/context-profiles.js.map +1 -0
- package/dist/context.d.ts +55 -0
- package/dist/context.d.ts.map +1 -0
- package/dist/context.js +288 -0
- package/dist/context.js.map +1 -0
- package/dist/dcf.d.ts +9 -0
- package/dist/dcf.d.ts.map +1 -0
- package/dist/dcf.js +75 -0
- package/dist/dcf.js.map +1 -0
- package/dist/debt.d.ts +11 -0
- package/dist/debt.d.ts.map +1 -0
- package/dist/debt.js +85 -0
- package/dist/debt.js.map +1 -0
- package/dist/defaults.d.ts +104 -0
- package/dist/defaults.d.ts.map +1 -0
- package/dist/defaults.js +622 -0
- package/dist/defaults.js.map +1 -0
- package/dist/derived.d.ts +17 -0
- package/dist/derived.d.ts.map +1 -0
- package/dist/derived.js +29 -0
- package/dist/derived.js.map +1 -0
- package/dist/editor.d.ts +76 -0
- package/dist/editor.d.ts.map +1 -0
- package/dist/editor.js +502 -0
- package/dist/editor.js.map +1 -0
- package/dist/envelope.d.ts +51 -0
- package/dist/envelope.d.ts.map +1 -0
- package/dist/envelope.js +213 -0
- package/dist/envelope.js.map +1 -0
- package/dist/format.d.ts +60 -0
- package/dist/format.d.ts.map +1 -0
- package/dist/format.js +115 -0
- package/dist/format.js.map +1 -0
- package/dist/gaps.d.ts +62 -0
- package/dist/gaps.d.ts.map +1 -0
- package/dist/gaps.js +272 -0
- package/dist/gaps.js.map +1 -0
- package/dist/index.d.ts +75 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +47 -0
- package/dist/index.js.map +1 -0
- package/dist/init.d.ts +15 -0
- package/dist/init.d.ts.map +1 -0
- package/dist/init.js +169 -0
- package/dist/init.js.map +1 -0
- package/dist/integrity-canonical.d.ts +17 -0
- package/dist/integrity-canonical.d.ts.map +1 -0
- package/dist/integrity-canonical.js +124 -0
- package/dist/integrity-canonical.js.map +1 -0
- package/dist/integrity.d.ts +54 -0
- package/dist/integrity.d.ts.map +1 -0
- package/dist/integrity.js +244 -0
- package/dist/integrity.js.map +1 -0
- package/dist/modules.d.ts +24 -0
- package/dist/modules.d.ts.map +1 -0
- package/dist/modules.js +322 -0
- package/dist/modules.js.map +1 -0
- package/dist/negotiation.d.ts +19 -0
- package/dist/negotiation.d.ts.map +1 -0
- package/dist/negotiation.js +70 -0
- package/dist/negotiation.js.map +1 -0
- package/dist/opstatement.d.ts +9 -0
- package/dist/opstatement.d.ts.map +1 -0
- package/dist/opstatement.js +80 -0
- package/dist/opstatement.js.map +1 -0
- package/dist/packs/excel-emit.d.ts +21 -0
- package/dist/packs/excel-emit.d.ts.map +1 -0
- package/dist/packs/excel-emit.js +135 -0
- package/dist/packs/excel-emit.js.map +1 -0
- package/dist/packs/index.d.ts +13 -0
- package/dist/packs/index.d.ts.map +1 -0
- package/dist/packs/index.js +37 -0
- package/dist/packs/index.js.map +1 -0
- package/dist/packs/industrial.d.ts +3 -0
- package/dist/packs/industrial.d.ts.map +1 -0
- package/dist/packs/industrial.js +115 -0
- package/dist/packs/industrial.js.map +1 -0
- package/dist/packs/multifamily.d.ts +3 -0
- package/dist/packs/multifamily.d.ts.map +1 -0
- package/dist/packs/multifamily.js +82 -0
- package/dist/packs/multifamily.js.map +1 -0
- package/dist/packs/office.d.ts +3 -0
- package/dist/packs/office.d.ts.map +1 -0
- package/dist/packs/office.js +108 -0
- package/dist/packs/office.js.map +1 -0
- package/dist/packs/retail.d.ts +3 -0
- package/dist/packs/retail.d.ts.map +1 -0
- package/dist/packs/retail.js +115 -0
- package/dist/packs/retail.js.map +1 -0
- package/dist/packs/self-storage.d.ts +3 -0
- package/dist/packs/self-storage.d.ts.map +1 -0
- package/dist/packs/self-storage.js +105 -0
- package/dist/packs/self-storage.js.map +1 -0
- package/dist/parser.d.ts +15 -0
- package/dist/parser.d.ts.map +1 -0
- package/dist/parser.js +430 -0
- package/dist/parser.js.map +1 -0
- package/dist/protocol.d.ts +389 -0
- package/dist/protocol.d.ts.map +1 -0
- package/dist/protocol.js +714 -0
- package/dist/protocol.js.map +1 -0
- package/dist/refinement.d.ts +63 -0
- package/dist/refinement.d.ts.map +1 -0
- package/dist/refinement.js +242 -0
- package/dist/refinement.js.map +1 -0
- package/dist/renderer.d.ts +22 -0
- package/dist/renderer.d.ts.map +1 -0
- package/dist/renderer.js +478 -0
- package/dist/renderer.js.map +1 -0
- package/dist/rentroll.d.ts +21 -0
- package/dist/rentroll.d.ts.map +1 -0
- package/dist/rentroll.js +256 -0
- package/dist/rentroll.js.map +1 -0
- package/dist/report.d.ts +29 -0
- package/dist/report.d.ts.map +1 -0
- package/dist/report.js +924 -0
- package/dist/report.js.map +1 -0
- package/dist/runner.d.ts +43 -0
- package/dist/runner.d.ts.map +1 -0
- package/dist/runner.js +288 -0
- package/dist/runner.js.map +1 -0
- package/dist/sourcesuses.d.ts +14 -0
- package/dist/sourcesuses.d.ts.map +1 -0
- package/dist/sourcesuses.js +63 -0
- package/dist/sourcesuses.js.map +1 -0
- package/dist/types.d.ts +248 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +15 -0
- package/dist/types.js.map +1 -0
- package/dist/uwcsv.d.ts +23 -0
- package/dist/uwcsv.d.ts.map +1 -0
- package/dist/uwcsv.js +877 -0
- package/dist/uwcsv.js.map +1 -0
- package/dist/uwjson.d.ts +19 -0
- package/dist/uwjson.d.ts.map +1 -0
- package/dist/uwjson.js +61 -0
- package/dist/uwjson.js.map +1 -0
- package/dist/uwxml.d.ts +18 -0
- package/dist/uwxml.d.ts.map +1 -0
- package/dist/uwxml.js +297 -0
- package/dist/uwxml.js.map +1 -0
- package/dist/validator.d.ts +35 -0
- package/dist/validator.d.ts.map +1 -0
- package/dist/validator.js +553 -0
- package/dist/validator.js.map +1 -0
- package/dist/valuation.d.ts +9 -0
- package/dist/valuation.d.ts.map +1 -0
- package/dist/valuation.js +34 -0
- package/dist/valuation.js.map +1 -0
- package/package.json +58 -0
|
@@ -0,0 +1,329 @@
|
|
|
1
|
+
// Tier-3 Calc Host — built-in function implementations.
|
|
2
|
+
// Signatures and semantics per UW_PROTOCOL_v1.md §VIII.3.
|
|
3
|
+
import { CalcError } from './errors.js';
|
|
4
|
+
function asNumberOrNull(v, fnName) {
|
|
5
|
+
if (v === null)
|
|
6
|
+
return null;
|
|
7
|
+
if (typeof v === 'number')
|
|
8
|
+
return v;
|
|
9
|
+
throw new CalcError('CALC-TYPE-001', `${fnName}: expected number or null, got ${typeof v}.`);
|
|
10
|
+
}
|
|
11
|
+
function asNumber(v, fnName) {
|
|
12
|
+
if (typeof v === 'number')
|
|
13
|
+
return v;
|
|
14
|
+
throw new CalcError('CALC-TYPE-001', `${fnName}: expected number, got ${v === null ? 'null' : typeof v}.`);
|
|
15
|
+
}
|
|
16
|
+
export const BUILTINS = Object.freeze({
|
|
17
|
+
// sum(...nums) — nulls treated as 0.
|
|
18
|
+
sum(args) {
|
|
19
|
+
let acc = 0;
|
|
20
|
+
for (const a of args) {
|
|
21
|
+
const n = asNumberOrNull(a, 'sum');
|
|
22
|
+
acc += n ?? 0;
|
|
23
|
+
}
|
|
24
|
+
return acc;
|
|
25
|
+
},
|
|
26
|
+
// avg(...nums) — null if no non-null inputs.
|
|
27
|
+
avg(args) {
|
|
28
|
+
let acc = 0;
|
|
29
|
+
let count = 0;
|
|
30
|
+
for (const a of args) {
|
|
31
|
+
const n = asNumberOrNull(a, 'avg');
|
|
32
|
+
if (n !== null) {
|
|
33
|
+
acc += n;
|
|
34
|
+
count++;
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
return count === 0 ? null : acc / count;
|
|
38
|
+
},
|
|
39
|
+
min(args) {
|
|
40
|
+
let best = null;
|
|
41
|
+
for (const a of args) {
|
|
42
|
+
const n = asNumberOrNull(a, 'min');
|
|
43
|
+
if (n === null)
|
|
44
|
+
continue;
|
|
45
|
+
best = best === null || n < best ? n : best;
|
|
46
|
+
}
|
|
47
|
+
return best;
|
|
48
|
+
},
|
|
49
|
+
max(args) {
|
|
50
|
+
let best = null;
|
|
51
|
+
for (const a of args) {
|
|
52
|
+
const n = asNumberOrNull(a, 'max');
|
|
53
|
+
if (n === null)
|
|
54
|
+
continue;
|
|
55
|
+
best = best === null || n > best ? n : best;
|
|
56
|
+
}
|
|
57
|
+
return best;
|
|
58
|
+
},
|
|
59
|
+
// coalesce(...args) — first non-null.
|
|
60
|
+
coalesce(args) {
|
|
61
|
+
for (const a of args)
|
|
62
|
+
if (a !== null)
|
|
63
|
+
return a;
|
|
64
|
+
return null;
|
|
65
|
+
},
|
|
66
|
+
// if(cond, then, else)
|
|
67
|
+
if(args) {
|
|
68
|
+
if (args.length !== 3) {
|
|
69
|
+
throw new CalcError('CALC-TYPE-001', `if: expected 3 arguments, got ${args.length}.`);
|
|
70
|
+
}
|
|
71
|
+
const cond = args[0];
|
|
72
|
+
if (typeof cond !== 'boolean') {
|
|
73
|
+
throw new CalcError('CALC-TYPE-001', `if: condition must be boolean, got ${cond === null ? 'null' : typeof cond}.`);
|
|
74
|
+
}
|
|
75
|
+
return cond ? args[1] : args[2];
|
|
76
|
+
},
|
|
77
|
+
// round(num, dec) — half-away-from-zero.
|
|
78
|
+
round(args) {
|
|
79
|
+
if (args.length !== 2) {
|
|
80
|
+
throw new CalcError('CALC-TYPE-001', `round: expected 2 arguments, got ${args.length}.`);
|
|
81
|
+
}
|
|
82
|
+
const num = args[0];
|
|
83
|
+
const dec = args[1];
|
|
84
|
+
if (num === null)
|
|
85
|
+
return null;
|
|
86
|
+
const n = asNumber(num, 'round');
|
|
87
|
+
const d = asNumber(dec, 'round');
|
|
88
|
+
if (!Number.isInteger(d)) {
|
|
89
|
+
throw new CalcError('CALC-TYPE-001', `round: decimals must be integer, got ${d}.`);
|
|
90
|
+
}
|
|
91
|
+
const factor = 10 ** d;
|
|
92
|
+
// Half-away-from-zero (Math.round in JS is half-up for positives, half-down for negatives).
|
|
93
|
+
const sign = n < 0 ? -1 : 1;
|
|
94
|
+
return sign * Math.floor(Math.abs(n) * factor + 0.5) / factor;
|
|
95
|
+
},
|
|
96
|
+
// pmt(rate, n, pv) — standard mortgage payment formula.
|
|
97
|
+
// Returns the *positive* periodic payment for a present value pv at periodic rate.
|
|
98
|
+
pmt(args) {
|
|
99
|
+
if (args.length !== 3) {
|
|
100
|
+
throw new CalcError('CALC-TYPE-001', `pmt: expected 3 arguments (rate, n, pv), got ${args.length}.`);
|
|
101
|
+
}
|
|
102
|
+
const rate = asNumber(args[0], 'pmt');
|
|
103
|
+
const n = asNumber(args[1], 'pmt');
|
|
104
|
+
const pv = asNumber(args[2], 'pmt');
|
|
105
|
+
if (n === 0) {
|
|
106
|
+
throw new CalcError('CALC-TYPE-001', 'pmt: n must be > 0.');
|
|
107
|
+
}
|
|
108
|
+
if (rate === 0)
|
|
109
|
+
return pv / n;
|
|
110
|
+
return (pv * rate) / (1 - (1 + rate) ** -n);
|
|
111
|
+
},
|
|
112
|
+
// npv(rate, ...flows) — flow at index 0 is at t=0 (undiscounted).
|
|
113
|
+
npv(args) {
|
|
114
|
+
if (args.length < 2) {
|
|
115
|
+
throw new CalcError('CALC-TYPE-001', `npv: expected (rate, ...flows), got ${args.length} args.`);
|
|
116
|
+
}
|
|
117
|
+
const rate = asNumber(args[0], 'npv');
|
|
118
|
+
let acc = 0;
|
|
119
|
+
for (let t = 0; t < args.length - 1; t++) {
|
|
120
|
+
const flow = asNumber(args[t + 1], 'npv');
|
|
121
|
+
acc += flow / (1 + rate) ** t;
|
|
122
|
+
}
|
|
123
|
+
return acc;
|
|
124
|
+
},
|
|
125
|
+
// ─── Math builtins ──────────────────────────────────────────────────────────
|
|
126
|
+
// abs(num) — null propagates.
|
|
127
|
+
abs(args) {
|
|
128
|
+
if (args.length !== 1) {
|
|
129
|
+
throw new CalcError('CALC-TYPE-001', `abs: expected 1 argument, got ${args.length}.`);
|
|
130
|
+
}
|
|
131
|
+
const n = asNumberOrNull(args[0], 'abs');
|
|
132
|
+
return n === null ? null : Math.abs(n);
|
|
133
|
+
},
|
|
134
|
+
// floor(num) — null propagates.
|
|
135
|
+
floor(args) {
|
|
136
|
+
if (args.length !== 1) {
|
|
137
|
+
throw new CalcError('CALC-TYPE-001', `floor: expected 1 argument, got ${args.length}.`);
|
|
138
|
+
}
|
|
139
|
+
const n = asNumberOrNull(args[0], 'floor');
|
|
140
|
+
return n === null ? null : Math.floor(n);
|
|
141
|
+
},
|
|
142
|
+
// ceil(num) — null propagates.
|
|
143
|
+
ceil(args) {
|
|
144
|
+
if (args.length !== 1) {
|
|
145
|
+
throw new CalcError('CALC-TYPE-001', `ceil: expected 1 argument, got ${args.length}.`);
|
|
146
|
+
}
|
|
147
|
+
const n = asNumberOrNull(args[0], 'ceil');
|
|
148
|
+
return n === null ? null : Math.ceil(n);
|
|
149
|
+
},
|
|
150
|
+
// sqrt(num) — null propagates; negative input → CALC-TYPE-001.
|
|
151
|
+
sqrt(args) {
|
|
152
|
+
if (args.length !== 1) {
|
|
153
|
+
throw new CalcError('CALC-TYPE-001', `sqrt: expected 1 argument, got ${args.length}.`);
|
|
154
|
+
}
|
|
155
|
+
const n = asNumberOrNull(args[0], 'sqrt');
|
|
156
|
+
if (n === null)
|
|
157
|
+
return null;
|
|
158
|
+
if (n < 0) {
|
|
159
|
+
throw new CalcError('CALC-TYPE-001', `sqrt: negative input ${n} produces non-real result.`);
|
|
160
|
+
}
|
|
161
|
+
return Math.sqrt(n);
|
|
162
|
+
},
|
|
163
|
+
// pow(base, exp) — null propagates.
|
|
164
|
+
pow(args) {
|
|
165
|
+
if (args.length !== 2) {
|
|
166
|
+
throw new CalcError('CALC-TYPE-001', `pow: expected 2 arguments, got ${args.length}.`);
|
|
167
|
+
}
|
|
168
|
+
const base = asNumberOrNull(args[0], 'pow');
|
|
169
|
+
const exp = asNumberOrNull(args[1], 'pow');
|
|
170
|
+
if (base === null || exp === null)
|
|
171
|
+
return null;
|
|
172
|
+
const r = base ** exp;
|
|
173
|
+
if (!Number.isFinite(r)) {
|
|
174
|
+
throw new CalcError('CALC-TYPE-001', `pow: result is not finite (${base}^${exp}).`);
|
|
175
|
+
}
|
|
176
|
+
return r;
|
|
177
|
+
},
|
|
178
|
+
// log(num) — natural log; null propagates; non-positive → CALC-TYPE-001.
|
|
179
|
+
log(args) {
|
|
180
|
+
if (args.length !== 1) {
|
|
181
|
+
throw new CalcError('CALC-TYPE-001', `log: expected 1 argument, got ${args.length}.`);
|
|
182
|
+
}
|
|
183
|
+
const n = asNumberOrNull(args[0], 'log');
|
|
184
|
+
if (n === null)
|
|
185
|
+
return null;
|
|
186
|
+
if (n <= 0) {
|
|
187
|
+
throw new CalcError('CALC-TYPE-001', `log: input must be positive, got ${n}.`);
|
|
188
|
+
}
|
|
189
|
+
return Math.log(n);
|
|
190
|
+
},
|
|
191
|
+
// exp(num) — null propagates.
|
|
192
|
+
exp(args) {
|
|
193
|
+
if (args.length !== 1) {
|
|
194
|
+
throw new CalcError('CALC-TYPE-001', `exp: expected 1 argument, got ${args.length}.`);
|
|
195
|
+
}
|
|
196
|
+
const n = asNumberOrNull(args[0], 'exp');
|
|
197
|
+
if (n === null)
|
|
198
|
+
return null;
|
|
199
|
+
const r = Math.exp(n);
|
|
200
|
+
if (!Number.isFinite(r)) {
|
|
201
|
+
throw new CalcError('CALC-TYPE-001', `exp: result is not finite (exp(${n})).`);
|
|
202
|
+
}
|
|
203
|
+
return r;
|
|
204
|
+
},
|
|
205
|
+
// ─── Financial builtins ─────────────────────────────────────────────────────
|
|
206
|
+
// fv(rate, n, pmt, pv?) — future value of a series of equal payments + initial pv.
|
|
207
|
+
// Sign convention: returns the *positive* future value of pv invested at `rate`
|
|
208
|
+
// with `pmt` deposits per period. Mirrors Excel's FV with type=0 (end of period)
|
|
209
|
+
// but without Excel's signed convention.
|
|
210
|
+
fv(args) {
|
|
211
|
+
if (args.length < 3 || args.length > 4) {
|
|
212
|
+
throw new CalcError('CALC-TYPE-001', `fv: expected (rate, n, pmt[, pv]), got ${args.length} args.`);
|
|
213
|
+
}
|
|
214
|
+
const rate = asNumber(args[0], 'fv');
|
|
215
|
+
const n = asNumber(args[1], 'fv');
|
|
216
|
+
const pmt = asNumber(args[2], 'fv');
|
|
217
|
+
const pv = args[3] === undefined ? 0 : asNumber(args[3], 'fv');
|
|
218
|
+
if (rate === 0)
|
|
219
|
+
return pv + pmt * n;
|
|
220
|
+
const growth = (1 + rate) ** n;
|
|
221
|
+
return pv * growth + pmt * (growth - 1) / rate;
|
|
222
|
+
},
|
|
223
|
+
// pv(rate, n, pmt, fv?) — present value of a series of equal payments + future value.
|
|
224
|
+
// Inverse of fv: returns the lump-sum today equivalent to receiving `pmt` per
|
|
225
|
+
// period for `n` periods at `rate`, plus a final `fv` payoff.
|
|
226
|
+
pv(args) {
|
|
227
|
+
if (args.length < 3 || args.length > 4) {
|
|
228
|
+
throw new CalcError('CALC-TYPE-001', `pv: expected (rate, n, pmt[, fv]), got ${args.length} args.`);
|
|
229
|
+
}
|
|
230
|
+
const rate = asNumber(args[0], 'pv');
|
|
231
|
+
const n = asNumber(args[1], 'pv');
|
|
232
|
+
const pmt = asNumber(args[2], 'pv');
|
|
233
|
+
const fv = args[3] === undefined ? 0 : asNumber(args[3], 'pv');
|
|
234
|
+
if (rate === 0)
|
|
235
|
+
return pmt * n + fv;
|
|
236
|
+
const discount = (1 + rate) ** -n;
|
|
237
|
+
return pmt * (1 - discount) / rate + fv * discount;
|
|
238
|
+
},
|
|
239
|
+
// nper(rate, pmt, pv, fv?) — number of periods to pay down pv with pmt payments.
|
|
240
|
+
// Unsigned convention matching pmt(): pv > 0 is the loan balance, pmt > 0 is
|
|
241
|
+
// the periodic payment, fv (default 0) is the residual balloon.
|
|
242
|
+
// Closed-form: pv*(1+r)^n - pmt*((1+r)^n - 1)/r = fv →
|
|
243
|
+
// n = log((pmt - fv*r) / (pmt - pv*r)) / log(1+r).
|
|
244
|
+
// Throws CALC-TYPE-001 if the equation has no real solution.
|
|
245
|
+
nper(args) {
|
|
246
|
+
if (args.length < 3 || args.length > 4) {
|
|
247
|
+
throw new CalcError('CALC-TYPE-001', `nper: expected (rate, pmt, pv[, fv]), got ${args.length} args.`);
|
|
248
|
+
}
|
|
249
|
+
const rate = asNumber(args[0], 'nper');
|
|
250
|
+
const pmt = asNumber(args[1], 'nper');
|
|
251
|
+
const pv = asNumber(args[2], 'nper');
|
|
252
|
+
const fv = args[3] === undefined ? 0 : asNumber(args[3], 'nper');
|
|
253
|
+
if (rate === 0) {
|
|
254
|
+
if (pmt === 0) {
|
|
255
|
+
throw new CalcError('CALC-TYPE-001', 'nper: pmt must be non-zero when rate is zero.');
|
|
256
|
+
}
|
|
257
|
+
return (pv - fv) / pmt;
|
|
258
|
+
}
|
|
259
|
+
const num = pmt - fv * rate;
|
|
260
|
+
const den = pmt - pv * rate;
|
|
261
|
+
if (den === 0 || num / den <= 0) {
|
|
262
|
+
throw new CalcError('CALC-TYPE-001', 'nper: no real solution for the given inputs.');
|
|
263
|
+
}
|
|
264
|
+
return Math.log(num / den) / Math.log(1 + rate);
|
|
265
|
+
},
|
|
266
|
+
// irr(...flows) — bisection + Newton fallback. Null if no real root.
|
|
267
|
+
irr(args) {
|
|
268
|
+
if (args.length < 2) {
|
|
269
|
+
throw new CalcError('CALC-TYPE-001', 'irr: requires at least 2 cash flows.');
|
|
270
|
+
}
|
|
271
|
+
const flows = args.map((a, _i) => asNumber(a, 'irr'));
|
|
272
|
+
// Newton-Raphson starting at 0.1.
|
|
273
|
+
const npvAt = (r) => {
|
|
274
|
+
let acc = 0;
|
|
275
|
+
for (let t = 0; t < flows.length; t++)
|
|
276
|
+
acc += flows[t] / (1 + r) ** t;
|
|
277
|
+
return acc;
|
|
278
|
+
};
|
|
279
|
+
const dnpvAt = (r) => {
|
|
280
|
+
let acc = 0;
|
|
281
|
+
for (let t = 1; t < flows.length; t++)
|
|
282
|
+
acc += -t * flows[t] / (1 + r) ** (t + 1);
|
|
283
|
+
return acc;
|
|
284
|
+
};
|
|
285
|
+
let r = 0.1;
|
|
286
|
+
const MAX_ITER = 100;
|
|
287
|
+
const TOL = 1e-9;
|
|
288
|
+
for (let i = 0; i < MAX_ITER; i++) {
|
|
289
|
+
const f = npvAt(r);
|
|
290
|
+
if (!Number.isFinite(f))
|
|
291
|
+
break;
|
|
292
|
+
if (Math.abs(f) < TOL)
|
|
293
|
+
return r;
|
|
294
|
+
const df = dnpvAt(r);
|
|
295
|
+
if (df === 0 || !Number.isFinite(df))
|
|
296
|
+
break;
|
|
297
|
+
const next = r - f / df;
|
|
298
|
+
if (!Number.isFinite(next) || next <= -1)
|
|
299
|
+
break;
|
|
300
|
+
if (Math.abs(next - r) < TOL)
|
|
301
|
+
return next;
|
|
302
|
+
r = next;
|
|
303
|
+
}
|
|
304
|
+
// Fallback: bisection over [-0.999, 10].
|
|
305
|
+
let lo = -0.999;
|
|
306
|
+
let hi = 10;
|
|
307
|
+
let flo = npvAt(lo);
|
|
308
|
+
let fhi = npvAt(hi);
|
|
309
|
+
if (!Number.isFinite(flo) || !Number.isFinite(fhi) || flo * fhi > 0) {
|
|
310
|
+
throw new CalcError('CALC-IRR-DIVERGE', 'irr: no root in [-99.9%, 1000%] bracket.');
|
|
311
|
+
}
|
|
312
|
+
for (let i = 0; i < 200; i++) {
|
|
313
|
+
const mid = (lo + hi) / 2;
|
|
314
|
+
const fmid = npvAt(mid);
|
|
315
|
+
if (Math.abs(fmid) < TOL || (hi - lo) / 2 < TOL)
|
|
316
|
+
return mid;
|
|
317
|
+
if (flo * fmid < 0) {
|
|
318
|
+
hi = mid;
|
|
319
|
+
fhi = fmid;
|
|
320
|
+
}
|
|
321
|
+
else {
|
|
322
|
+
lo = mid;
|
|
323
|
+
flo = fmid;
|
|
324
|
+
}
|
|
325
|
+
}
|
|
326
|
+
throw new CalcError('CALC-IRR-DIVERGE', 'irr: failed to converge after 200 iterations.');
|
|
327
|
+
},
|
|
328
|
+
});
|
|
329
|
+
//# sourceMappingURL=builtins.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"builtins.js","sourceRoot":"","sources":["../../src/calc/builtins.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import type { Expr } from './parser.js';
|
|
2
|
+
import type { ParsedUWFile } from '../types.js';
|
|
3
|
+
import type { ModuleManifest } from '../protocol.js';
|
|
4
|
+
export interface DependencyGraph {
|
|
5
|
+
/** calc id → set of input field paths it reads */
|
|
6
|
+
outputs: Map<string, Set<string>>;
|
|
7
|
+
/** input field path → set of calc ids that read it */
|
|
8
|
+
inputs: Map<string, Set<string>>;
|
|
9
|
+
/** calc id → original formula string */
|
|
10
|
+
formulas: Map<string, string>;
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Walk an Expr AST and return the unique set of `path` and `ident`
|
|
14
|
+
* references — every "leaf" the formula reads. Identifiers are
|
|
15
|
+
* returned as-is (e.g. `purchase_price`); paths are joined with dots
|
|
16
|
+
* (e.g. `noi_model.net_operating_income`).
|
|
17
|
+
*/
|
|
18
|
+
export declare function getExprDependencies(expr: Expr): string[];
|
|
19
|
+
export interface ExtractDependencyGraphOptions {
|
|
20
|
+
/** Calc packs to include. Default: caller passes [MULTIFAMILY_PACK] explicitly. */
|
|
21
|
+
packs?: ModuleManifest[];
|
|
22
|
+
/** Whether to include `parsed.custom_calculations[]`. Default: true. */
|
|
23
|
+
includeCustomCalculations?: boolean;
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Build the full dependency graph for a parsed file: every calc declared in
|
|
27
|
+
* the supplied packs plus every entry in `parsed.custom_calculations` that
|
|
28
|
+
* carries a `formula` string.
|
|
29
|
+
*
|
|
30
|
+
* Invalid formulas are skipped silently — the graph is descriptive, not
|
|
31
|
+
* prescriptive. Callers that want strict failure should pre-validate.
|
|
32
|
+
*/
|
|
33
|
+
export declare function extractDependencyGraph(parsed: ParsedUWFile, options?: ExtractDependencyGraphOptions): DependencyGraph;
|
|
34
|
+
//# sourceMappingURL=dependencies.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dependencies.d.ts","sourceRoot":"","sources":["../../src/calc/dependencies.ts"],"names":[],"mappings":"AAWA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,aAAa,CAAC;AAExC,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAChD,OAAO,KAAK,EAAE,cAAc,EAAkB,MAAM,gBAAgB,CAAC;AAErE,MAAM,WAAW,eAAe;IAC9B,kDAAkD;IAClD,OAAO,EAAE,GAAG,CAAC,MAAM,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC;IAClC,sDAAsD;IACtD,MAAM,EAAE,GAAG,CAAC,MAAM,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC;IACjC,wCAAwC;IACxC,QAAQ,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAC/B;AAED;;;;;GAKG;AACH,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,IAAI,GAAG,MAAM,EAAE,CAIxD;AA+BD,MAAM,WAAW,6BAA6B;IAC5C,mFAAmF;IACnF,KAAK,CAAC,EAAE,cAAc,EAAE,CAAC;IACzB,wEAAwE;IACxE,yBAAyB,CAAC,EAAE,OAAO,CAAC;CACrC;AAED;;;;;;;GAOG;AACH,wBAAgB,sBAAsB,CACpC,MAAM,EAAE,YAAY,EACpB,OAAO,GAAE,6BAAkC,GAC1C,eAAe,CAyCjB"}
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
// Dependency graph extraction for calc formulas.
|
|
2
|
+
// Spec: UW_PROTOCOL_v1.md §X.4 (refinement engine inputs)
|
|
3
|
+
//
|
|
4
|
+
// Walks the AST of every calc formula and emits the set of input field paths
|
|
5
|
+
// it reads. Used by refinement.ts to compute value-of-information rankings:
|
|
6
|
+
// which gap, if filled, would tighten the most outputs?
|
|
7
|
+
//
|
|
8
|
+
// Descriptive, not prescriptive: a formula that references a non-existent
|
|
9
|
+
// path is still recorded — the graph reflects what the formula says, not
|
|
10
|
+
// what the file currently has.
|
|
11
|
+
import { parseExpression } from './parser.js';
|
|
12
|
+
/**
|
|
13
|
+
* Walk an Expr AST and return the unique set of `path` and `ident`
|
|
14
|
+
* references — every "leaf" the formula reads. Identifiers are
|
|
15
|
+
* returned as-is (e.g. `purchase_price`); paths are joined with dots
|
|
16
|
+
* (e.g. `noi_model.net_operating_income`).
|
|
17
|
+
*/
|
|
18
|
+
export function getExprDependencies(expr) {
|
|
19
|
+
const out = new Set();
|
|
20
|
+
walk(expr, out);
|
|
21
|
+
return [...out];
|
|
22
|
+
}
|
|
23
|
+
function walk(expr, acc) {
|
|
24
|
+
switch (expr.kind) {
|
|
25
|
+
case 'literal':
|
|
26
|
+
return;
|
|
27
|
+
case 'ident':
|
|
28
|
+
acc.add(expr.name);
|
|
29
|
+
return;
|
|
30
|
+
case 'path':
|
|
31
|
+
acc.add([expr.head, ...expr.segments].join('.'));
|
|
32
|
+
return;
|
|
33
|
+
case 'call':
|
|
34
|
+
// Function name is not a dependency; arguments are.
|
|
35
|
+
for (const a of expr.args)
|
|
36
|
+
walk(a, acc);
|
|
37
|
+
return;
|
|
38
|
+
case 'unary':
|
|
39
|
+
walk(expr.operand, acc);
|
|
40
|
+
return;
|
|
41
|
+
case 'binary':
|
|
42
|
+
walk(expr.left, acc);
|
|
43
|
+
walk(expr.right, acc);
|
|
44
|
+
return;
|
|
45
|
+
case 'cond':
|
|
46
|
+
walk(expr.test, acc);
|
|
47
|
+
walk(expr.consequent, acc);
|
|
48
|
+
walk(expr.else, acc);
|
|
49
|
+
return;
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Build the full dependency graph for a parsed file: every calc declared in
|
|
54
|
+
* the supplied packs plus every entry in `parsed.custom_calculations` that
|
|
55
|
+
* carries a `formula` string.
|
|
56
|
+
*
|
|
57
|
+
* Invalid formulas are skipped silently — the graph is descriptive, not
|
|
58
|
+
* prescriptive. Callers that want strict failure should pre-validate.
|
|
59
|
+
*/
|
|
60
|
+
export function extractDependencyGraph(parsed, options = {}) {
|
|
61
|
+
const outputs = new Map();
|
|
62
|
+
const inputs = new Map();
|
|
63
|
+
const formulas = new Map();
|
|
64
|
+
const decls = [];
|
|
65
|
+
for (const pack of options.packs ?? []) {
|
|
66
|
+
for (const c of pack.calculations ?? [])
|
|
67
|
+
decls.push(c);
|
|
68
|
+
}
|
|
69
|
+
if (options.includeCustomCalculations !== false) {
|
|
70
|
+
for (const block of parsed.custom_calculations) {
|
|
71
|
+
const content = block.content;
|
|
72
|
+
const id = (content.id ?? content.calc_id);
|
|
73
|
+
const formula = content.formula;
|
|
74
|
+
if (typeof id === 'string' && typeof formula === 'string') {
|
|
75
|
+
decls.push({ id, label: id, formula, deterministic: true });
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
for (const decl of decls) {
|
|
80
|
+
let deps;
|
|
81
|
+
try {
|
|
82
|
+
const ast = parseExpression(decl.formula);
|
|
83
|
+
deps = getExprDependencies(ast);
|
|
84
|
+
}
|
|
85
|
+
catch {
|
|
86
|
+
// Bad formula — skip; refinement engine will note it via diagnostics.
|
|
87
|
+
continue;
|
|
88
|
+
}
|
|
89
|
+
formulas.set(decl.id, decl.formula);
|
|
90
|
+
const set = outputs.get(decl.id) ?? new Set();
|
|
91
|
+
for (const d of deps) {
|
|
92
|
+
set.add(d);
|
|
93
|
+
const rev = inputs.get(d) ?? new Set();
|
|
94
|
+
rev.add(decl.id);
|
|
95
|
+
inputs.set(d, rev);
|
|
96
|
+
}
|
|
97
|
+
outputs.set(decl.id, set);
|
|
98
|
+
}
|
|
99
|
+
return { outputs, inputs, formulas };
|
|
100
|
+
}
|
|
101
|
+
//# sourceMappingURL=dependencies.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dependencies.js","sourceRoot":"","sources":["../../src/calc/dependencies.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { ProtocolError } from '../protocol.js';
|
|
2
|
+
export type CalcErrorCode = 'CALC-PARSE-001' | 'CALC-RESOLVE-001' | 'CALC-TYPE-001' | 'CALC-DIV-ZERO' | 'CALC-IRR-DIVERGE' | 'CALC-LIMIT-001';
|
|
3
|
+
export declare function calcError(code: CalcErrorCode, message: string, pointer?: string): ProtocolError;
|
|
4
|
+
export declare class CalcError extends Error {
|
|
5
|
+
readonly proto: ProtocolError;
|
|
6
|
+
constructor(code: CalcErrorCode, message: string, pointer?: string);
|
|
7
|
+
}
|
|
8
|
+
//# sourceMappingURL=errors.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../../src/calc/errors.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAEpD,MAAM,MAAM,aAAa,GACrB,gBAAgB,GAChB,kBAAkB,GAClB,eAAe,GACf,eAAe,GACf,kBAAkB,GAClB,gBAAgB,CAAC;AAErB,wBAAgB,SAAS,CAAC,IAAI,EAAE,aAAa,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,GAAG,aAAa,CAO/F;AAED,qBAAa,SAAU,SAAQ,KAAK;IAClC,QAAQ,CAAC,KAAK,EAAE,aAAa,CAAC;gBAClB,IAAI,EAAE,aAAa,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM;CAInE"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
// Tier-3 Calc Host — error factory
|
|
2
|
+
// Codes per UW_PROTOCOL_v1.md §VIII.5.
|
|
3
|
+
export function calcError(code, message, pointer) {
|
|
4
|
+
return {
|
|
5
|
+
category: 'calc',
|
|
6
|
+
code,
|
|
7
|
+
message,
|
|
8
|
+
...(pointer ? { pointer } : {}),
|
|
9
|
+
};
|
|
10
|
+
}
|
|
11
|
+
export class CalcError extends Error {
|
|
12
|
+
proto;
|
|
13
|
+
constructor(code, message, pointer) {
|
|
14
|
+
super(`[${code}] ${message}`);
|
|
15
|
+
this.proto = calcError(code, message, pointer);
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
//# sourceMappingURL=errors.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"errors.js","sourceRoot":"","sources":["../../src/calc/errors.ts"],"names":[],"mappings":"AAAA,mCAAmC;AACnC,uCAAuC;AAYvC,MAAM,UAAU,SAAS,CAAC,IAAmB,EAAE,OAAe,EAAE,OAAgB;IAC9E,OAAO;QACL,QAAQ,EAAE,MAAM;QAChB,IAAI;QACJ,OAAO;QACP,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;KAChC,CAAC;AACJ,CAAC;AAED,MAAM,OAAO,SAAU,SAAQ,KAAK;IACzB,KAAK,CAAgB;IAC9B,YAAY,IAAmB,EAAE,OAAe,EAAE,OAAgB;QAChE,KAAK,CAAC,IAAI,IAAI,KAAK,OAAO,EAAE,CAAC,CAAC;QAC9B,IAAI,CAAC,KAAK,GAAG,SAAS,CAAC,IAAI,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC;IACjD,CAAC;CACF"}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import type { CalcEvaluationContext } from '../protocol.js';
|
|
2
|
+
import { type CalcValue } from './builtins.js';
|
|
3
|
+
import type { Expr } from './parser.js';
|
|
4
|
+
export declare function evaluate(expr: Expr, ctx: CalcEvaluationContext): CalcValue;
|
|
5
|
+
//# sourceMappingURL=evaluator.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"evaluator.d.ts","sourceRoot":"","sources":["../../src/calc/evaluator.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,gBAAgB,CAAC;AAC5D,OAAO,EAAY,KAAK,SAAS,EAAE,MAAM,eAAe,CAAC;AAEzD,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,aAAa,CAAC;AAQxC,wBAAgB,QAAQ,CAAC,IAAI,EAAE,IAAI,EAAE,GAAG,EAAE,qBAAqB,GAAG,SAAS,CAG1E"}
|