@trajectonomics/tax 0.0.0-stage → 0.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/LICENSE +21 -0
- package/README.md +48 -2
- package/dist/clamp-BKG7kjVf.cjs +509 -0
- package/dist/clamp-BKG7kjVf.cjs.map +1 -0
- package/dist/clamp-Bse4u0H-.mjs +426 -0
- package/dist/clamp-Bse4u0H-.mjs.map +1 -0
- package/dist/index.cjs +27 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +102 -0
- package/dist/index.d.mts +102 -0
- package/dist/index.mjs +15 -0
- package/dist/index.mjs.map +1 -0
- package/dist/th/index.cjs +1480 -0
- package/dist/th/index.cjs.map +1 -0
- package/dist/th/index.d.cts +636 -0
- package/dist/th/index.d.mts +636 -0
- package/dist/th/index.mjs +1473 -0
- package/dist/th/index.mjs.map +1 -0
- package/dist/types-798sLpt6.d.cts +170 -0
- package/dist/types-798sLpt6.d.mts +170 -0
- package/dist/us/index.cjs +2921 -0
- package/dist/us/index.cjs.map +1 -0
- package/dist/us/index.d.cts +649 -0
- package/dist/us/index.d.mts +649 -0
- package/dist/us/index.mjs +2897 -0
- package/dist/us/index.mjs.map +1 -0
- package/package.json +78 -5
|
@@ -0,0 +1,2921 @@
|
|
|
1
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
|
+
const require_clamp = require("../clamp-BKG7kjVf.cjs");
|
|
3
|
+
// src/us/parameters/amt.ts
|
|
4
|
+
/**
|
|
5
|
+
* Statutory 2026 Alternative Minimum Tax (AMT) exemptions, phaseouts, and rates.
|
|
6
|
+
*
|
|
7
|
+
* @statute IRC § 55
|
|
8
|
+
*/
|
|
9
|
+
const US_2026_AMT = {
|
|
10
|
+
baseExemptions: {
|
|
11
|
+
single: 90100,
|
|
12
|
+
married_filing_jointly: 140200,
|
|
13
|
+
married_filing_separately: 70100,
|
|
14
|
+
head_of_household: 90100
|
|
15
|
+
},
|
|
16
|
+
phaseoutThresholds: {
|
|
17
|
+
single: 643250,
|
|
18
|
+
married_filing_jointly: 1286500,
|
|
19
|
+
married_filing_separately: 643250,
|
|
20
|
+
head_of_household: 643250
|
|
21
|
+
},
|
|
22
|
+
phaseoutRate: .25,
|
|
23
|
+
rate26Thresholds: {
|
|
24
|
+
single: 239100,
|
|
25
|
+
married_filing_jointly: 239100,
|
|
26
|
+
married_filing_separately: 119550,
|
|
27
|
+
head_of_household: 239100
|
|
28
|
+
},
|
|
29
|
+
rate26: .26,
|
|
30
|
+
rate28: .28
|
|
31
|
+
};
|
|
32
|
+
// src/us/parameters/brackets.ts
|
|
33
|
+
/**
|
|
34
|
+
* Statutory 2026 US Federal ordinary income progressive brackets in minor units (cents).
|
|
35
|
+
*
|
|
36
|
+
* @statute IRC § 1(j), Rev. Proc. 2025-XX
|
|
37
|
+
*/
|
|
38
|
+
const US_2026_ORDINARY_BRACKETS = {
|
|
39
|
+
single: [
|
|
40
|
+
{
|
|
41
|
+
upTo: 124e4,
|
|
42
|
+
rate: .1
|
|
43
|
+
},
|
|
44
|
+
{
|
|
45
|
+
upTo: 504e4,
|
|
46
|
+
rate: .12
|
|
47
|
+
},
|
|
48
|
+
{
|
|
49
|
+
upTo: 1057e4,
|
|
50
|
+
rate: .22
|
|
51
|
+
},
|
|
52
|
+
{
|
|
53
|
+
upTo: 20177500,
|
|
54
|
+
rate: .24
|
|
55
|
+
},
|
|
56
|
+
{
|
|
57
|
+
upTo: 25622500,
|
|
58
|
+
rate: .32
|
|
59
|
+
},
|
|
60
|
+
{
|
|
61
|
+
upTo: 6406e4,
|
|
62
|
+
rate: .35
|
|
63
|
+
},
|
|
64
|
+
{
|
|
65
|
+
upTo: null,
|
|
66
|
+
rate: .37
|
|
67
|
+
}
|
|
68
|
+
],
|
|
69
|
+
married_filing_jointly: [
|
|
70
|
+
{
|
|
71
|
+
upTo: 248e4,
|
|
72
|
+
rate: .1
|
|
73
|
+
},
|
|
74
|
+
{
|
|
75
|
+
upTo: 1008e4,
|
|
76
|
+
rate: .12
|
|
77
|
+
},
|
|
78
|
+
{
|
|
79
|
+
upTo: 2114e4,
|
|
80
|
+
rate: .22
|
|
81
|
+
},
|
|
82
|
+
{
|
|
83
|
+
upTo: 40355e3,
|
|
84
|
+
rate: .24
|
|
85
|
+
},
|
|
86
|
+
{
|
|
87
|
+
upTo: 51245e3,
|
|
88
|
+
rate: .32
|
|
89
|
+
},
|
|
90
|
+
{
|
|
91
|
+
upTo: 7687e4,
|
|
92
|
+
rate: .35
|
|
93
|
+
},
|
|
94
|
+
{
|
|
95
|
+
upTo: null,
|
|
96
|
+
rate: .37
|
|
97
|
+
}
|
|
98
|
+
],
|
|
99
|
+
married_filing_separately: [
|
|
100
|
+
{
|
|
101
|
+
upTo: 124e4,
|
|
102
|
+
rate: .1
|
|
103
|
+
},
|
|
104
|
+
{
|
|
105
|
+
upTo: 504e4,
|
|
106
|
+
rate: .12
|
|
107
|
+
},
|
|
108
|
+
{
|
|
109
|
+
upTo: 1057e4,
|
|
110
|
+
rate: .22
|
|
111
|
+
},
|
|
112
|
+
{
|
|
113
|
+
upTo: 20177500,
|
|
114
|
+
rate: .24
|
|
115
|
+
},
|
|
116
|
+
{
|
|
117
|
+
upTo: 25622500,
|
|
118
|
+
rate: .32
|
|
119
|
+
},
|
|
120
|
+
{
|
|
121
|
+
upTo: 38435e3,
|
|
122
|
+
rate: .35
|
|
123
|
+
},
|
|
124
|
+
{
|
|
125
|
+
upTo: null,
|
|
126
|
+
rate: .37
|
|
127
|
+
}
|
|
128
|
+
],
|
|
129
|
+
head_of_household: [
|
|
130
|
+
{
|
|
131
|
+
upTo: 177e4,
|
|
132
|
+
rate: .1
|
|
133
|
+
},
|
|
134
|
+
{
|
|
135
|
+
upTo: 6745e3,
|
|
136
|
+
rate: .12
|
|
137
|
+
},
|
|
138
|
+
{
|
|
139
|
+
upTo: 1057e4,
|
|
140
|
+
rate: .22
|
|
141
|
+
},
|
|
142
|
+
{
|
|
143
|
+
upTo: 20175e3,
|
|
144
|
+
rate: .24
|
|
145
|
+
},
|
|
146
|
+
{
|
|
147
|
+
upTo: 2562e4,
|
|
148
|
+
rate: .32
|
|
149
|
+
},
|
|
150
|
+
{
|
|
151
|
+
upTo: 6406e4,
|
|
152
|
+
rate: .35
|
|
153
|
+
},
|
|
154
|
+
{
|
|
155
|
+
upTo: null,
|
|
156
|
+
rate: .37
|
|
157
|
+
}
|
|
158
|
+
]
|
|
159
|
+
};
|
|
160
|
+
/**
|
|
161
|
+
* Statutory 2026 US Federal preferential capital gains brackets in minor units (cents).
|
|
162
|
+
*
|
|
163
|
+
* @statute IRC § 1(h), Rev. Proc. 2025-XX
|
|
164
|
+
*/
|
|
165
|
+
const US_2026_PREFERENTIAL_BRACKETS = {
|
|
166
|
+
single: [
|
|
167
|
+
{
|
|
168
|
+
upTo: 4945e3,
|
|
169
|
+
rate: 0
|
|
170
|
+
},
|
|
171
|
+
{
|
|
172
|
+
upTo: 5455e4,
|
|
173
|
+
rate: .15
|
|
174
|
+
},
|
|
175
|
+
{
|
|
176
|
+
upTo: null,
|
|
177
|
+
rate: .2
|
|
178
|
+
}
|
|
179
|
+
],
|
|
180
|
+
married_filing_jointly: [
|
|
181
|
+
{
|
|
182
|
+
upTo: 989e4,
|
|
183
|
+
rate: 0
|
|
184
|
+
},
|
|
185
|
+
{
|
|
186
|
+
upTo: 6137e4,
|
|
187
|
+
rate: .15
|
|
188
|
+
},
|
|
189
|
+
{
|
|
190
|
+
upTo: null,
|
|
191
|
+
rate: .2
|
|
192
|
+
}
|
|
193
|
+
],
|
|
194
|
+
married_filing_separately: [
|
|
195
|
+
{
|
|
196
|
+
upTo: 4945e3,
|
|
197
|
+
rate: 0
|
|
198
|
+
},
|
|
199
|
+
{
|
|
200
|
+
upTo: 30685e3,
|
|
201
|
+
rate: .15
|
|
202
|
+
},
|
|
203
|
+
{
|
|
204
|
+
upTo: null,
|
|
205
|
+
rate: .2
|
|
206
|
+
}
|
|
207
|
+
],
|
|
208
|
+
head_of_household: [
|
|
209
|
+
{
|
|
210
|
+
upTo: 662e4,
|
|
211
|
+
rate: 0
|
|
212
|
+
},
|
|
213
|
+
{
|
|
214
|
+
upTo: 5796e4,
|
|
215
|
+
rate: .15
|
|
216
|
+
},
|
|
217
|
+
{
|
|
218
|
+
upTo: null,
|
|
219
|
+
rate: .2
|
|
220
|
+
}
|
|
221
|
+
]
|
|
222
|
+
};
|
|
223
|
+
// src/us/parameters/constants.ts
|
|
224
|
+
/**
|
|
225
|
+
* Statutory 2026 US Federal base standard deduction amounts in major dollars.
|
|
226
|
+
*
|
|
227
|
+
* @statute IRC § 63(c)(2), Rev. Proc. 2025-XX
|
|
228
|
+
*/
|
|
229
|
+
const US_2026_STANDARD_DEDUCTION = {
|
|
230
|
+
single: 16100,
|
|
231
|
+
married_filing_jointly: 32200,
|
|
232
|
+
married_filing_separately: 16100,
|
|
233
|
+
head_of_household: 24150
|
|
234
|
+
};
|
|
235
|
+
/**
|
|
236
|
+
* Statutory 2026 additional standard deduction for age 65+ and blindness per condition.
|
|
237
|
+
*
|
|
238
|
+
* @statute IRC § 63(f), Rev. Proc. 2025-XX
|
|
239
|
+
*/
|
|
240
|
+
const US_2026_ADDITIONAL_STANDARD_DEDUCTION = {
|
|
241
|
+
unmarried: 2050,
|
|
242
|
+
married: 1650
|
|
243
|
+
};
|
|
244
|
+
/**
|
|
245
|
+
* Statutory 2026 Schedule 1 Above-the-Line deduction limits in major dollars.
|
|
246
|
+
*
|
|
247
|
+
* @statute IRC § 62, § 219, § 221, § 223, § 402(g)
|
|
248
|
+
*/
|
|
249
|
+
const US_2026_ABOVE_THE_LINE_CAPS = {
|
|
250
|
+
educatorSingle: 350,
|
|
251
|
+
educatorMfjBoth: 700,
|
|
252
|
+
studentLoanInterest: 2500,
|
|
253
|
+
traditional401kBase: 24500,
|
|
254
|
+
traditional401kCatchUpAge50: 8e3,
|
|
255
|
+
traditionalIraBase: 7500,
|
|
256
|
+
traditionalIraCatchUpAge50: 1100,
|
|
257
|
+
hsaSelfOnlyBase: 4400,
|
|
258
|
+
hsaFamilyBase: 8750,
|
|
259
|
+
hsaCatchUpAge55: 1e3
|
|
260
|
+
};
|
|
261
|
+
/**
|
|
262
|
+
* Statutory 2026 Schedule A Itemized Deduction thresholds and caps.
|
|
263
|
+
*
|
|
264
|
+
* @statute IRC §§ 164, 170, 213
|
|
265
|
+
*/
|
|
266
|
+
const US_2026_ITEMIZED = {
|
|
267
|
+
medicalFloorRate: .075,
|
|
268
|
+
saltCap: 1e4,
|
|
269
|
+
saltCapMfs: 5e3,
|
|
270
|
+
charityCeilingRate: .6
|
|
271
|
+
};
|
|
272
|
+
/**
|
|
273
|
+
* Statutory Net Investment Income Tax (NIIT) rates and MAGI thresholds.
|
|
274
|
+
*
|
|
275
|
+
* @statute IRC § 1411
|
|
276
|
+
*/
|
|
277
|
+
const US_2026_NIIT = {
|
|
278
|
+
rate: .038,
|
|
279
|
+
thresholds: {
|
|
280
|
+
single: 2e5,
|
|
281
|
+
head_of_household: 2e5,
|
|
282
|
+
married_filing_jointly: 25e4,
|
|
283
|
+
married_filing_separately: 125e3
|
|
284
|
+
}
|
|
285
|
+
};
|
|
286
|
+
// src/us/parameters/credits.ts
|
|
287
|
+
/**
|
|
288
|
+
* Statutory 2026 Federal Tax Credits parameters.
|
|
289
|
+
*
|
|
290
|
+
* @statute IRC § 21, § 24, § 25A, § 32
|
|
291
|
+
*/
|
|
292
|
+
const US_2026_CREDITS = {
|
|
293
|
+
ctcAmountPerChild: 2e3,
|
|
294
|
+
actcMaxPerChild: 1700,
|
|
295
|
+
actcEarnedIncomeThreshold: 2500,
|
|
296
|
+
actcRate: .15,
|
|
297
|
+
ctcPhaseoutThresholds: {
|
|
298
|
+
single: 2e5,
|
|
299
|
+
married_filing_jointly: 4e5,
|
|
300
|
+
married_filing_separately: 2e5,
|
|
301
|
+
head_of_household: 2e5
|
|
302
|
+
},
|
|
303
|
+
ctcPhaseoutStepAmount: 1e3,
|
|
304
|
+
ctcPhaseoutStepRate: 50,
|
|
305
|
+
odcAmountPerDependent: 500,
|
|
306
|
+
eitcInvestmentIncomeLimit: 11950,
|
|
307
|
+
eitcTiers: {
|
|
308
|
+
0: {
|
|
309
|
+
creditRate: .0765,
|
|
310
|
+
maxEarnedIncome: 8490,
|
|
311
|
+
maxCredit: 649,
|
|
312
|
+
phaseoutThresholdSingle: 10620,
|
|
313
|
+
phaseoutThresholdMfj: 17990,
|
|
314
|
+
phaseoutRate: .0765
|
|
315
|
+
},
|
|
316
|
+
1: {
|
|
317
|
+
creditRate: .34,
|
|
318
|
+
maxEarnedIncome: 12730,
|
|
319
|
+
maxCredit: 4328,
|
|
320
|
+
phaseoutThresholdSingle: 23340,
|
|
321
|
+
phaseoutThresholdMfj: 30710,
|
|
322
|
+
phaseoutRate: .1598
|
|
323
|
+
},
|
|
324
|
+
2: {
|
|
325
|
+
creditRate: .4,
|
|
326
|
+
maxEarnedIncome: 17880,
|
|
327
|
+
maxCredit: 7152,
|
|
328
|
+
phaseoutThresholdSingle: 23340,
|
|
329
|
+
phaseoutThresholdMfj: 30710,
|
|
330
|
+
phaseoutRate: .2106
|
|
331
|
+
},
|
|
332
|
+
3: {
|
|
333
|
+
creditRate: .45,
|
|
334
|
+
maxEarnedIncome: 17880,
|
|
335
|
+
maxCredit: 8046,
|
|
336
|
+
phaseoutThresholdSingle: 23340,
|
|
337
|
+
phaseoutThresholdMfj: 30710,
|
|
338
|
+
phaseoutRate: .2106
|
|
339
|
+
}
|
|
340
|
+
},
|
|
341
|
+
careMaxExpenseOne: 3e3,
|
|
342
|
+
careMaxExpenseTwoPlus: 6e3,
|
|
343
|
+
careBaseRate: .35,
|
|
344
|
+
careFloorRate: .2,
|
|
345
|
+
carePhaseoutAgiThreshold: 15e3,
|
|
346
|
+
carePhaseoutStepAgi: 2e3,
|
|
347
|
+
carePhaseoutStepRate: .01,
|
|
348
|
+
aotcMaxPerStudent: 2500,
|
|
349
|
+
aotcTier1MaxExpense: 2e3,
|
|
350
|
+
aotcTier1Rate: 1,
|
|
351
|
+
aotcTier2MaxExpense: 2e3,
|
|
352
|
+
aotcTier2Rate: .25,
|
|
353
|
+
aotcRefundableRate: .4,
|
|
354
|
+
aotcPhaseoutMin: {
|
|
355
|
+
single: 8e4,
|
|
356
|
+
head_of_household: 8e4,
|
|
357
|
+
married_filing_jointly: 16e4,
|
|
358
|
+
married_filing_separately: 0
|
|
359
|
+
},
|
|
360
|
+
aotcPhaseoutMax: {
|
|
361
|
+
single: 9e4,
|
|
362
|
+
head_of_household: 9e4,
|
|
363
|
+
married_filing_jointly: 18e4,
|
|
364
|
+
married_filing_separately: 0
|
|
365
|
+
},
|
|
366
|
+
llcMaxExpensePerReturn: 1e4,
|
|
367
|
+
llcRate: .2
|
|
368
|
+
};
|
|
369
|
+
// src/us/parameters/payroll.ts
|
|
370
|
+
/**
|
|
371
|
+
* Statutory 2026 FICA & SECA Payroll parameters.
|
|
372
|
+
*
|
|
373
|
+
* @statute IRC § 1401, § 1402, § 3101
|
|
374
|
+
*/
|
|
375
|
+
const US_2026_PAYROLL = {
|
|
376
|
+
socialSecurityWageBase: 181800,
|
|
377
|
+
ficaSocialSecurityRate: .062,
|
|
378
|
+
ficaMedicareRate: .0145,
|
|
379
|
+
additionalMedicareRate: .009,
|
|
380
|
+
additionalMedicareThresholds: {
|
|
381
|
+
single: 2e5,
|
|
382
|
+
married_filing_jointly: 25e4,
|
|
383
|
+
married_filing_separately: 125e3,
|
|
384
|
+
head_of_household: 2e5
|
|
385
|
+
},
|
|
386
|
+
seNetEarningsFactor: .9235,
|
|
387
|
+
seThresholdFloor: 400,
|
|
388
|
+
seSocialSecurityRate: .124,
|
|
389
|
+
seMedicareRate: .029,
|
|
390
|
+
seDeductibleRate: .5
|
|
391
|
+
};
|
|
392
|
+
// src/us/parameters.ts
|
|
393
|
+
/**
|
|
394
|
+
* Consolidated statutory parameter table for US Federal Income Tax (Tax Year 2026).
|
|
395
|
+
*
|
|
396
|
+
* @statute IRC § 1 et seq.
|
|
397
|
+
*/
|
|
398
|
+
const US_2026_PARAMETERS = {
|
|
399
|
+
taxYear: 2026,
|
|
400
|
+
currency: "USD",
|
|
401
|
+
standardDeduction: US_2026_STANDARD_DEDUCTION,
|
|
402
|
+
additionalStandardDeduction: US_2026_ADDITIONAL_STANDARD_DEDUCTION,
|
|
403
|
+
aboveTheLineCaps: US_2026_ABOVE_THE_LINE_CAPS,
|
|
404
|
+
itemized: US_2026_ITEMIZED,
|
|
405
|
+
niit: US_2026_NIIT,
|
|
406
|
+
ordinaryBrackets: US_2026_ORDINARY_BRACKETS,
|
|
407
|
+
preferentialBrackets: US_2026_PREFERENTIAL_BRACKETS,
|
|
408
|
+
payroll: US_2026_PAYROLL,
|
|
409
|
+
amt: US_2026_AMT,
|
|
410
|
+
credits: US_2026_CREDITS
|
|
411
|
+
};
|
|
412
|
+
// src/us/types/state-fields.ts
|
|
413
|
+
/**
|
|
414
|
+
* Diagnostic and reporting field identifiers for state income tax calculations.
|
|
415
|
+
*/
|
|
416
|
+
let UsStateField = /* @__PURE__ */ function(UsStateField) {
|
|
417
|
+
UsStateField["BracketBound"] = "state.bracketBound";
|
|
418
|
+
UsStateField["Agi"] = "state.agi";
|
|
419
|
+
UsStateField["StandardDeduction"] = "state.standardDeduction";
|
|
420
|
+
UsStateField["PersonalExemption"] = "state.personalExemption";
|
|
421
|
+
UsStateField["DependentExemption"] = "state.dependentExemption";
|
|
422
|
+
UsStateField["TaxableIncome"] = "state.taxableIncome";
|
|
423
|
+
UsStateField["BracketTax"] = "state.bracketTax";
|
|
424
|
+
UsStateField["Surtax"] = "state.surtax";
|
|
425
|
+
UsStateField["SurtaxThreshold"] = "state.surtaxThreshold";
|
|
426
|
+
UsStateField["PhaseOutThreshold"] = "state.phaseOutThreshold";
|
|
427
|
+
UsStateField["CreditsPersonal"] = "state.credits.personal";
|
|
428
|
+
UsStateField["CreditsDependent"] = "state.credits.dependent";
|
|
429
|
+
UsStateField["CreditsClaimedNonRefundable"] = "state.credits.claimedNonRefundable";
|
|
430
|
+
UsStateField["CreditsNonRefundable"] = "state.credits.nonRefundable";
|
|
431
|
+
UsStateField["CreditsRefundable"] = "state.credits.refundable";
|
|
432
|
+
UsStateField["Withholding"] = "state.withholding";
|
|
433
|
+
UsStateField["TaxBeforeCredits"] = "state.taxBeforeCredits";
|
|
434
|
+
UsStateField["TotalTax"] = "state.totalTax";
|
|
435
|
+
UsStateField["NetTaxPayable"] = "state.netTaxPayable";
|
|
436
|
+
return UsStateField;
|
|
437
|
+
}({});
|
|
438
|
+
// src/us/state/parameters/helpers.ts
|
|
439
|
+
function tiersToBrackets(tiers) {
|
|
440
|
+
const bounds = tiers.map(([lower]) => require_clamp.toMinorUnits(lower, US_2026_PARAMETERS.currency, "state.bracketBound"));
|
|
441
|
+
const brackets = [];
|
|
442
|
+
const first = bounds[0] ?? 0;
|
|
443
|
+
if (first > 0) brackets.push({
|
|
444
|
+
upTo: first,
|
|
445
|
+
rate: 0
|
|
446
|
+
});
|
|
447
|
+
for (let index = 0; index < tiers.length; index++) {
|
|
448
|
+
const tier = tiers[index];
|
|
449
|
+
if (!tier) continue;
|
|
450
|
+
brackets.push({
|
|
451
|
+
upTo: bounds[index + 1] ?? null,
|
|
452
|
+
rate: tier[1]
|
|
453
|
+
});
|
|
454
|
+
}
|
|
455
|
+
return brackets;
|
|
456
|
+
}
|
|
457
|
+
function standardAmounts(single, mfj, hoh, mfs) {
|
|
458
|
+
return {
|
|
459
|
+
single,
|
|
460
|
+
married_filing_jointly: mfj,
|
|
461
|
+
married_filing_separately: mfs ?? (mfj === single ? single : Math.round(mfj / 2)),
|
|
462
|
+
head_of_household: hoh ?? (single > 0 ? Math.round(single * 1.5) : 0)
|
|
463
|
+
};
|
|
464
|
+
}
|
|
465
|
+
function exemptionAmounts(single, mfj, hoh, mfs = void 0) {
|
|
466
|
+
return {
|
|
467
|
+
single,
|
|
468
|
+
married_filing_jointly: mfj,
|
|
469
|
+
married_filing_separately: mfs ?? single,
|
|
470
|
+
head_of_household: hoh ?? single
|
|
471
|
+
};
|
|
472
|
+
}
|
|
473
|
+
function resolveMfsTiers(def) {
|
|
474
|
+
if (def.mfs === "half-mfj") return def.mfj.map(([lower, rate]) => [lower / 2, rate]);
|
|
475
|
+
return def.mfs ?? def.single;
|
|
476
|
+
}
|
|
477
|
+
function resolveHohTiers(def) {
|
|
478
|
+
if (def.hoh === "mfj") return def.mfj;
|
|
479
|
+
return def.hoh ?? def.single;
|
|
480
|
+
}
|
|
481
|
+
function optionalRules(def) {
|
|
482
|
+
return {
|
|
483
|
+
...def.surtax ? { surtax: def.surtax } : {},
|
|
484
|
+
...def.standardDeductionPhaseOut ? { standardDeductionPhaseOut: def.standardDeductionPhaseOut } : {},
|
|
485
|
+
...def.dependentExemptionPhaseOut ? { dependentExemptionPhaseOut: def.dependentExemptionPhaseOut } : {}
|
|
486
|
+
};
|
|
487
|
+
}
|
|
488
|
+
/**
|
|
489
|
+
* Builds a complete state parameter table from a compact statutory definition.
|
|
490
|
+
*
|
|
491
|
+
* Math: Converts dollar thresholds to integer cents; derives vertical-equity defaults
|
|
492
|
+
* (MFS uses single brackets, HoH uses single brackets and 1.5x single standard deduction).
|
|
493
|
+
* Units: Definition amounts are major dollars; emitted bracket bounds are integer cents.
|
|
494
|
+
* Throws: TaxValidationError if a threshold cannot be represented as safe integer cents.
|
|
495
|
+
*
|
|
496
|
+
* @param def Compact state statutory definition.
|
|
497
|
+
* @returns Complete state parameter table.
|
|
498
|
+
*/
|
|
499
|
+
function defineState(def) {
|
|
500
|
+
const personalExemption = def.personalExemption ?? [0, 0];
|
|
501
|
+
const personalCredit = def.personalCredit ?? [0, 0];
|
|
502
|
+
return {
|
|
503
|
+
code: def.code,
|
|
504
|
+
name: def.name,
|
|
505
|
+
type: def.type,
|
|
506
|
+
brackets: {
|
|
507
|
+
single: tiersToBrackets(def.single),
|
|
508
|
+
married_filing_jointly: tiersToBrackets(def.mfj),
|
|
509
|
+
married_filing_separately: tiersToBrackets(resolveMfsTiers(def)),
|
|
510
|
+
head_of_household: tiersToBrackets(resolveHohTiers(def))
|
|
511
|
+
},
|
|
512
|
+
standardDeduction: standardAmounts(def.std[0], def.std[1], def.std[2], def.stdMfs),
|
|
513
|
+
personalExemption: exemptionAmounts(personalExemption[0], personalExemption[1], personalExemption[2], def.personalExemptionMfs),
|
|
514
|
+
personalCredit: exemptionAmounts(personalCredit[0], personalCredit[1], personalCredit[2]),
|
|
515
|
+
dependentExemption: def.dependentExemption ?? 0,
|
|
516
|
+
dependentCredit: def.dependentCredit ?? 0,
|
|
517
|
+
...optionalRules(def)
|
|
518
|
+
};
|
|
519
|
+
}
|
|
520
|
+
/**
|
|
521
|
+
* Indexes a complete list of state parameter tables by state code.
|
|
522
|
+
*
|
|
523
|
+
* @param states All supported state parameter tables.
|
|
524
|
+
* @returns Record keyed by every supported state code.
|
|
525
|
+
*/
|
|
526
|
+
function indexStates(states) {
|
|
527
|
+
const record = {};
|
|
528
|
+
for (const state of states) record[state.code] = state;
|
|
529
|
+
return record;
|
|
530
|
+
}
|
|
531
|
+
/** Statutory parameter table for the 2026 flat-rate states in group A. */
|
|
532
|
+
const FLAT_STATES_A = [
|
|
533
|
+
defineState({
|
|
534
|
+
code: "AZ",
|
|
535
|
+
name: "Arizona",
|
|
536
|
+
type: "flat",
|
|
537
|
+
single: [[0, .025]],
|
|
538
|
+
mfj: [[0, .025]],
|
|
539
|
+
std: [
|
|
540
|
+
16100,
|
|
541
|
+
32200,
|
|
542
|
+
24150
|
|
543
|
+
],
|
|
544
|
+
dependentCredit: 100
|
|
545
|
+
}),
|
|
546
|
+
defineState({
|
|
547
|
+
code: "CO",
|
|
548
|
+
name: "Colorado",
|
|
549
|
+
type: "flat",
|
|
550
|
+
single: [[0, .044]],
|
|
551
|
+
mfj: [[0, .044]],
|
|
552
|
+
std: [16100, 32200]
|
|
553
|
+
}),
|
|
554
|
+
defineState({
|
|
555
|
+
code: "GA",
|
|
556
|
+
name: "Georgia",
|
|
557
|
+
type: "flat",
|
|
558
|
+
single: [[0, .0499]],
|
|
559
|
+
mfj: [[0, .0499]],
|
|
560
|
+
std: [
|
|
561
|
+
15e3,
|
|
562
|
+
3e4,
|
|
563
|
+
15e3
|
|
564
|
+
],
|
|
565
|
+
dependentExemption: 5e3
|
|
566
|
+
}),
|
|
567
|
+
defineState({
|
|
568
|
+
code: "ID",
|
|
569
|
+
name: "Idaho",
|
|
570
|
+
type: "flat",
|
|
571
|
+
single: [[4811, .053]],
|
|
572
|
+
mfj: [[9622, .053]],
|
|
573
|
+
std: [16100, 32200]
|
|
574
|
+
}),
|
|
575
|
+
defineState({
|
|
576
|
+
code: "IL",
|
|
577
|
+
name: "Illinois",
|
|
578
|
+
type: "flat",
|
|
579
|
+
single: [[0, .0495]],
|
|
580
|
+
mfj: [[0, .0495]],
|
|
581
|
+
std: [0, 0],
|
|
582
|
+
personalExemption: [2925, 5850],
|
|
583
|
+
dependentExemption: 2925
|
|
584
|
+
}),
|
|
585
|
+
defineState({
|
|
586
|
+
code: "IN",
|
|
587
|
+
name: "Indiana",
|
|
588
|
+
type: "flat",
|
|
589
|
+
single: [[0, .0295]],
|
|
590
|
+
mfj: [[0, .0295]],
|
|
591
|
+
std: [0, 0],
|
|
592
|
+
personalExemption: [1e3, 2e3],
|
|
593
|
+
dependentExemption: 1e3
|
|
594
|
+
}),
|
|
595
|
+
defineState({
|
|
596
|
+
code: "IA",
|
|
597
|
+
name: "Iowa",
|
|
598
|
+
type: "flat",
|
|
599
|
+
single: [[0, .038]],
|
|
600
|
+
mfj: [[0, .038]],
|
|
601
|
+
std: [16100, 32200],
|
|
602
|
+
personalCredit: [40, 80],
|
|
603
|
+
dependentCredit: 40
|
|
604
|
+
})
|
|
605
|
+
];
|
|
606
|
+
/** Statutory parameter table for the 2026 flat-rate states in group B. */
|
|
607
|
+
const FLAT_STATES_B = [
|
|
608
|
+
defineState({
|
|
609
|
+
code: "KY",
|
|
610
|
+
name: "Kentucky",
|
|
611
|
+
type: "flat",
|
|
612
|
+
single: [[0, .035]],
|
|
613
|
+
mfj: [[0, .035]],
|
|
614
|
+
std: [
|
|
615
|
+
3360,
|
|
616
|
+
3360,
|
|
617
|
+
3360
|
|
618
|
+
]
|
|
619
|
+
}),
|
|
620
|
+
defineState({
|
|
621
|
+
code: "MA",
|
|
622
|
+
name: "Massachusetts",
|
|
623
|
+
type: "flat",
|
|
624
|
+
single: [[0, .05]],
|
|
625
|
+
mfj: [[0, .05]],
|
|
626
|
+
std: [0, 0],
|
|
627
|
+
personalExemption: [
|
|
628
|
+
4400,
|
|
629
|
+
8800,
|
|
630
|
+
6800
|
|
631
|
+
],
|
|
632
|
+
dependentExemption: 1e3,
|
|
633
|
+
surtax: {
|
|
634
|
+
threshold: 1107750,
|
|
635
|
+
rate: .04
|
|
636
|
+
}
|
|
637
|
+
}),
|
|
638
|
+
defineState({
|
|
639
|
+
code: "MI",
|
|
640
|
+
name: "Michigan",
|
|
641
|
+
type: "flat",
|
|
642
|
+
single: [[0, .0425]],
|
|
643
|
+
mfj: [[0, .0425]],
|
|
644
|
+
std: [0, 0],
|
|
645
|
+
personalExemption: [5900, 11800],
|
|
646
|
+
dependentExemption: 5900
|
|
647
|
+
}),
|
|
648
|
+
defineState({
|
|
649
|
+
code: "MS",
|
|
650
|
+
name: "Mississippi",
|
|
651
|
+
type: "flat",
|
|
652
|
+
single: [[1e4, .04]],
|
|
653
|
+
mfj: [[1e4, .04]],
|
|
654
|
+
std: [2300, 4600],
|
|
655
|
+
personalExemption: [6e3, 12e3],
|
|
656
|
+
dependentExemption: 1500
|
|
657
|
+
}),
|
|
658
|
+
defineState({
|
|
659
|
+
code: "NC",
|
|
660
|
+
name: "North Carolina",
|
|
661
|
+
type: "flat",
|
|
662
|
+
single: [[0, .0399]],
|
|
663
|
+
mfj: [[0, .0399]],
|
|
664
|
+
std: [12750, 25500]
|
|
665
|
+
}),
|
|
666
|
+
defineState({
|
|
667
|
+
code: "PA",
|
|
668
|
+
name: "Pennsylvania",
|
|
669
|
+
type: "flat",
|
|
670
|
+
single: [[0, .0307]],
|
|
671
|
+
mfj: [[0, .0307]],
|
|
672
|
+
std: [0, 0]
|
|
673
|
+
}),
|
|
674
|
+
defineState({
|
|
675
|
+
code: "UT",
|
|
676
|
+
name: "Utah",
|
|
677
|
+
type: "flat",
|
|
678
|
+
single: [[0, .0445]],
|
|
679
|
+
mfj: [[0, .0445]],
|
|
680
|
+
std: [0, 0],
|
|
681
|
+
personalCredit: [
|
|
682
|
+
966,
|
|
683
|
+
1932,
|
|
684
|
+
1449
|
|
685
|
+
],
|
|
686
|
+
dependentCredit: 126.66
|
|
687
|
+
})
|
|
688
|
+
];
|
|
689
|
+
/** Statutory parameter table for Louisiana and Ohio flat-rate individual income taxes. */
|
|
690
|
+
const FLAT_STATES_C = [defineState({
|
|
691
|
+
code: "LA",
|
|
692
|
+
name: "Louisiana",
|
|
693
|
+
type: "flat",
|
|
694
|
+
single: [[0, .03]],
|
|
695
|
+
mfj: [[0, .03]],
|
|
696
|
+
std: [
|
|
697
|
+
12875,
|
|
698
|
+
25750,
|
|
699
|
+
25750
|
|
700
|
+
]
|
|
701
|
+
}), defineState({
|
|
702
|
+
code: "OH",
|
|
703
|
+
name: "Ohio",
|
|
704
|
+
type: "flat",
|
|
705
|
+
single: [[26050, .0275]],
|
|
706
|
+
mfj: [[26050, .0275]],
|
|
707
|
+
std: [0, 0],
|
|
708
|
+
personalExemption: [2400, 4800],
|
|
709
|
+
dependentExemption: 2400
|
|
710
|
+
})];
|
|
711
|
+
// src/us/state/parameters/flat/index.ts
|
|
712
|
+
/** Statutory parameter table for all 2026 flat-rate state individual income taxes. */
|
|
713
|
+
const FLAT_STATES = [
|
|
714
|
+
...FLAT_STATES_A,
|
|
715
|
+
...FLAT_STATES_B,
|
|
716
|
+
...FLAT_STATES_C
|
|
717
|
+
];
|
|
718
|
+
// src/us/state/parameters/none.ts
|
|
719
|
+
/**
|
|
720
|
+
* Builds the zero-rate parameter table for a state with no 2026 wage income tax.
|
|
721
|
+
*
|
|
722
|
+
* Units: All amounts are zero major dollars.
|
|
723
|
+
*/
|
|
724
|
+
function noTaxState(code, name) {
|
|
725
|
+
return defineState({
|
|
726
|
+
code,
|
|
727
|
+
name,
|
|
728
|
+
type: "none",
|
|
729
|
+
single: [[0, 0]],
|
|
730
|
+
mfj: [[0, 0]],
|
|
731
|
+
std: [0, 0]
|
|
732
|
+
});
|
|
733
|
+
}
|
|
734
|
+
/**
|
|
735
|
+
* Statutory parameter table for the nine states with no 2026 wage income tax.
|
|
736
|
+
*
|
|
737
|
+
* Washington taxes only long-term capital gains above a high threshold, and New Hampshire and
|
|
738
|
+
* Tennessee repealed their interest and dividends taxes, so none taxes wage or ordinary income.
|
|
739
|
+
*
|
|
740
|
+
* @statute State constitutions and statutes repealing or prohibiting an individual income tax.
|
|
741
|
+
*/
|
|
742
|
+
const NO_TAX_STATES = [
|
|
743
|
+
noTaxState("AK", "Alaska"),
|
|
744
|
+
noTaxState("FL", "Florida"),
|
|
745
|
+
noTaxState("NV", "Nevada"),
|
|
746
|
+
noTaxState("NH", "New Hampshire"),
|
|
747
|
+
noTaxState("SD", "South Dakota"),
|
|
748
|
+
noTaxState("TN", "Tennessee"),
|
|
749
|
+
noTaxState("TX", "Texas"),
|
|
750
|
+
noTaxState("WA", "Washington"),
|
|
751
|
+
noTaxState("WY", "Wyoming")
|
|
752
|
+
];
|
|
753
|
+
// src/us/state/parameters/progressive/al.ts
|
|
754
|
+
/**
|
|
755
|
+
* 2026 Alabama individual income tax parameters.
|
|
756
|
+
*
|
|
757
|
+
* @statute Ala. Code § 40-18-5
|
|
758
|
+
*/
|
|
759
|
+
const US_2026_STATE_AL = defineState({
|
|
760
|
+
code: "AL",
|
|
761
|
+
name: "Alabama",
|
|
762
|
+
type: "progressive",
|
|
763
|
+
single: [
|
|
764
|
+
[0, .02],
|
|
765
|
+
[500, .04],
|
|
766
|
+
[3e3, .05]
|
|
767
|
+
],
|
|
768
|
+
mfj: [
|
|
769
|
+
[0, .02],
|
|
770
|
+
[1e3, .04],
|
|
771
|
+
[6e3, .05]
|
|
772
|
+
],
|
|
773
|
+
std: [
|
|
774
|
+
3e3,
|
|
775
|
+
8500,
|
|
776
|
+
5200
|
|
777
|
+
],
|
|
778
|
+
personalExemption: [
|
|
779
|
+
1500,
|
|
780
|
+
3e3,
|
|
781
|
+
3e3
|
|
782
|
+
],
|
|
783
|
+
dependentExemption: 1e3
|
|
784
|
+
});
|
|
785
|
+
// src/us/state/parameters/progressive/ar.ts
|
|
786
|
+
/**
|
|
787
|
+
* 2026 Arkansas individual income tax parameters.
|
|
788
|
+
*
|
|
789
|
+
* Brackets from the DFA 2026 withholding formula (0% to $5,599, then 2%, 3%, 3.4%); the top rate is
|
|
790
|
+
* 3.7% after H.B. 1001 (retroactive to 2026-01-01), as reported by EY and Bloomberg Tax.
|
|
791
|
+
*
|
|
792
|
+
* @statute Ark. Code Ann. § 26-51-201
|
|
793
|
+
*/
|
|
794
|
+
const US_2026_STATE_AR = defineState({
|
|
795
|
+
code: "AR",
|
|
796
|
+
name: "Arkansas",
|
|
797
|
+
type: "progressive",
|
|
798
|
+
single: [
|
|
799
|
+
[5600, .02],
|
|
800
|
+
[11200, .03],
|
|
801
|
+
[16e3, .034],
|
|
802
|
+
[26400, .037]
|
|
803
|
+
],
|
|
804
|
+
mfj: [
|
|
805
|
+
[5600, .02],
|
|
806
|
+
[11200, .03],
|
|
807
|
+
[16e3, .034],
|
|
808
|
+
[26400, .037]
|
|
809
|
+
],
|
|
810
|
+
std: [2470, 4940],
|
|
811
|
+
personalCredit: [29, 58],
|
|
812
|
+
dependentCredit: 29
|
|
813
|
+
});
|
|
814
|
+
// src/us/state/parameters/progressive/ca.ts
|
|
815
|
+
/**
|
|
816
|
+
* 2026 California individual income tax parameters.
|
|
817
|
+
*
|
|
818
|
+
* FTB 2026 indexed schedules, deduction ($5,900/$11,800) and exemption credits ($158/$316,
|
|
819
|
+
* $491 per dependent). 1% mental health services surtax above $1,000,000.
|
|
820
|
+
*
|
|
821
|
+
* @statute Cal. Rev. & Tax. Code § 17041
|
|
822
|
+
*/
|
|
823
|
+
const US_2026_STATE_CA = defineState({
|
|
824
|
+
code: "CA",
|
|
825
|
+
name: "California",
|
|
826
|
+
type: "progressive",
|
|
827
|
+
single: [
|
|
828
|
+
[0, .01],
|
|
829
|
+
[11456, .02],
|
|
830
|
+
[27157, .04],
|
|
831
|
+
[42861, .06],
|
|
832
|
+
[59498, .08],
|
|
833
|
+
[75197, .093],
|
|
834
|
+
[384109, .103],
|
|
835
|
+
[460927, .113],
|
|
836
|
+
[768213, .123]
|
|
837
|
+
],
|
|
838
|
+
mfj: [
|
|
839
|
+
[0, .01],
|
|
840
|
+
[22912, .02],
|
|
841
|
+
[54314, .04],
|
|
842
|
+
[85722, .06],
|
|
843
|
+
[118996, .08],
|
|
844
|
+
[150394, .093],
|
|
845
|
+
[768218, .103],
|
|
846
|
+
[921854, .113],
|
|
847
|
+
[1536426, .123]
|
|
848
|
+
],
|
|
849
|
+
hoh: [
|
|
850
|
+
[0, .01],
|
|
851
|
+
[22927, .02],
|
|
852
|
+
[54316, .04],
|
|
853
|
+
[70018, .06],
|
|
854
|
+
[86654, .08],
|
|
855
|
+
[102356, .093],
|
|
856
|
+
[522385, .103],
|
|
857
|
+
[626864, .113],
|
|
858
|
+
[1044771, .123]
|
|
859
|
+
],
|
|
860
|
+
std: [
|
|
861
|
+
5900,
|
|
862
|
+
11800,
|
|
863
|
+
11800
|
|
864
|
+
],
|
|
865
|
+
personalCredit: [158, 316],
|
|
866
|
+
dependentCredit: 491,
|
|
867
|
+
surtax: {
|
|
868
|
+
threshold: 1e6,
|
|
869
|
+
rate: .01
|
|
870
|
+
}
|
|
871
|
+
});
|
|
872
|
+
// src/us/state/parameters/progressive/ct.ts
|
|
873
|
+
/**
|
|
874
|
+
* 2026 Connecticut individual income tax parameters.
|
|
875
|
+
*
|
|
876
|
+
* @statute Conn. Gen. Stat. § 12-700
|
|
877
|
+
*/
|
|
878
|
+
const US_2026_STATE_CT = defineState({
|
|
879
|
+
code: "CT",
|
|
880
|
+
name: "Connecticut",
|
|
881
|
+
type: "progressive",
|
|
882
|
+
single: [
|
|
883
|
+
[0, .02],
|
|
884
|
+
[1e4, .045],
|
|
885
|
+
[5e4, .055],
|
|
886
|
+
[1e5, .06],
|
|
887
|
+
[2e5, .065],
|
|
888
|
+
[25e4, .069],
|
|
889
|
+
[5e5, .0699]
|
|
890
|
+
],
|
|
891
|
+
mfj: [
|
|
892
|
+
[0, .02],
|
|
893
|
+
[2e4, .045],
|
|
894
|
+
[1e5, .055],
|
|
895
|
+
[2e5, .06],
|
|
896
|
+
[4e5, .065],
|
|
897
|
+
[5e5, .069],
|
|
898
|
+
[1e6, .0699]
|
|
899
|
+
],
|
|
900
|
+
hoh: [
|
|
901
|
+
[0, .02],
|
|
902
|
+
[16e3, .045],
|
|
903
|
+
[8e4, .055],
|
|
904
|
+
[16e4, .06],
|
|
905
|
+
[32e4, .065],
|
|
906
|
+
[4e5, .069],
|
|
907
|
+
[8e5, .0699]
|
|
908
|
+
],
|
|
909
|
+
std: [0, 0],
|
|
910
|
+
personalExemptionMfs: 12e3,
|
|
911
|
+
personalExemption: [
|
|
912
|
+
15e3,
|
|
913
|
+
24e3,
|
|
914
|
+
19e3
|
|
915
|
+
]
|
|
916
|
+
});
|
|
917
|
+
// src/us/state/parameters/progressive/dc.ts
|
|
918
|
+
/**
|
|
919
|
+
* 2026 District of Columbia individual income tax parameters.
|
|
920
|
+
*
|
|
921
|
+
* @statute D.C. Code § 47-1806.03
|
|
922
|
+
*/
|
|
923
|
+
const US_2026_STATE_DC = defineState({
|
|
924
|
+
code: "DC",
|
|
925
|
+
name: "District of Columbia",
|
|
926
|
+
type: "progressive",
|
|
927
|
+
single: [
|
|
928
|
+
[0, .04],
|
|
929
|
+
[1e4, .06],
|
|
930
|
+
[4e4, .065],
|
|
931
|
+
[6e4, .085],
|
|
932
|
+
[25e4, .0925],
|
|
933
|
+
[5e5, .0975],
|
|
934
|
+
[1e6, .1075]
|
|
935
|
+
],
|
|
936
|
+
mfj: [
|
|
937
|
+
[0, .04],
|
|
938
|
+
[1e4, .06],
|
|
939
|
+
[4e4, .065],
|
|
940
|
+
[6e4, .085],
|
|
941
|
+
[25e4, .0925],
|
|
942
|
+
[5e5, .0975],
|
|
943
|
+
[1e6, .1075]
|
|
944
|
+
],
|
|
945
|
+
std: [
|
|
946
|
+
16100,
|
|
947
|
+
32200,
|
|
948
|
+
24150
|
|
949
|
+
]
|
|
950
|
+
});
|
|
951
|
+
// src/us/state/parameters/progressive/de.ts
|
|
952
|
+
/**
|
|
953
|
+
* 2026 Delaware individual income tax parameters.
|
|
954
|
+
*
|
|
955
|
+
* @statute Del. Code Ann. tit. 30, § 1102
|
|
956
|
+
*/
|
|
957
|
+
const US_2026_STATE_DE = defineState({
|
|
958
|
+
code: "DE",
|
|
959
|
+
name: "Delaware",
|
|
960
|
+
type: "progressive",
|
|
961
|
+
single: [
|
|
962
|
+
[2e3, .022],
|
|
963
|
+
[5e3, .039],
|
|
964
|
+
[1e4, .048],
|
|
965
|
+
[2e4, .052],
|
|
966
|
+
[25e3, .0555],
|
|
967
|
+
[6e4, .066]
|
|
968
|
+
],
|
|
969
|
+
mfj: [
|
|
970
|
+
[2e3, .022],
|
|
971
|
+
[5e3, .039],
|
|
972
|
+
[1e4, .048],
|
|
973
|
+
[2e4, .052],
|
|
974
|
+
[25e3, .0555],
|
|
975
|
+
[6e4, .066]
|
|
976
|
+
],
|
|
977
|
+
std: [
|
|
978
|
+
3250,
|
|
979
|
+
6500,
|
|
980
|
+
3250
|
|
981
|
+
],
|
|
982
|
+
personalCredit: [110, 220],
|
|
983
|
+
dependentCredit: 110
|
|
984
|
+
});
|
|
985
|
+
// src/us/state/parameters/progressive/hi.ts
|
|
986
|
+
/**
|
|
987
|
+
* 2026 Hawaii individual income tax parameters.
|
|
988
|
+
*
|
|
989
|
+
* @statute Haw. Rev. Stat. § 235-51
|
|
990
|
+
*/
|
|
991
|
+
const US_2026_STATE_HI = defineState({
|
|
992
|
+
code: "HI",
|
|
993
|
+
name: "Hawaii",
|
|
994
|
+
type: "progressive",
|
|
995
|
+
single: [
|
|
996
|
+
[0, .014],
|
|
997
|
+
[9600, .032],
|
|
998
|
+
[14400, .055],
|
|
999
|
+
[19200, .064],
|
|
1000
|
+
[24e3, .068],
|
|
1001
|
+
[36e3, .072],
|
|
1002
|
+
[48e3, .076],
|
|
1003
|
+
[125e3, .079],
|
|
1004
|
+
[175e3, .0825],
|
|
1005
|
+
[225e3, .09],
|
|
1006
|
+
[275e3, .1],
|
|
1007
|
+
[325e3, .11]
|
|
1008
|
+
],
|
|
1009
|
+
mfj: [
|
|
1010
|
+
[0, .014],
|
|
1011
|
+
[19200, .032],
|
|
1012
|
+
[28800, .055],
|
|
1013
|
+
[38400, .064],
|
|
1014
|
+
[48e3, .068],
|
|
1015
|
+
[72e3, .072],
|
|
1016
|
+
[96e3, .076],
|
|
1017
|
+
[25e4, .079],
|
|
1018
|
+
[35e4, .0825],
|
|
1019
|
+
[45e4, .09],
|
|
1020
|
+
[55e4, .1],
|
|
1021
|
+
[65e4, .11]
|
|
1022
|
+
],
|
|
1023
|
+
hoh: [
|
|
1024
|
+
[0, .014],
|
|
1025
|
+
[14400, .032],
|
|
1026
|
+
[21600, .055],
|
|
1027
|
+
[28800, .064],
|
|
1028
|
+
[36e3, .068],
|
|
1029
|
+
[54e3, .072],
|
|
1030
|
+
[72e3, .076],
|
|
1031
|
+
[187500, .079],
|
|
1032
|
+
[262500, .0825],
|
|
1033
|
+
[337500, .09],
|
|
1034
|
+
[412500, .1],
|
|
1035
|
+
[487500, .11]
|
|
1036
|
+
],
|
|
1037
|
+
std: [
|
|
1038
|
+
8e3,
|
|
1039
|
+
16e3,
|
|
1040
|
+
12e3
|
|
1041
|
+
],
|
|
1042
|
+
personalExemption: [1144, 2288],
|
|
1043
|
+
dependentExemption: 1144
|
|
1044
|
+
});
|
|
1045
|
+
// src/us/state/parameters/progressive/ks.ts
|
|
1046
|
+
/**
|
|
1047
|
+
* 2026 Kansas individual income tax parameters.
|
|
1048
|
+
*
|
|
1049
|
+
* @statute Kan. Stat. Ann. § 79-32,110
|
|
1050
|
+
*/
|
|
1051
|
+
const US_2026_STATE_KS = defineState({
|
|
1052
|
+
code: "KS",
|
|
1053
|
+
name: "Kansas",
|
|
1054
|
+
type: "progressive",
|
|
1055
|
+
single: [[0, .052], [23e3, .0558]],
|
|
1056
|
+
mfj: [[0, .052], [46e3, .0558]],
|
|
1057
|
+
std: [
|
|
1058
|
+
3605,
|
|
1059
|
+
8240,
|
|
1060
|
+
6180
|
|
1061
|
+
],
|
|
1062
|
+
personalExemption: [9160, 18320],
|
|
1063
|
+
dependentExemption: 2320
|
|
1064
|
+
});
|
|
1065
|
+
// src/us/state/parameters/progressive/md.ts
|
|
1066
|
+
/**
|
|
1067
|
+
* 2026 Maryland individual income tax parameters.
|
|
1068
|
+
*
|
|
1069
|
+
* @statute Md. Code, Tax-Gen. § 10-105
|
|
1070
|
+
*/
|
|
1071
|
+
const US_2026_STATE_MD = defineState({
|
|
1072
|
+
code: "MD",
|
|
1073
|
+
name: "Maryland",
|
|
1074
|
+
type: "progressive",
|
|
1075
|
+
single: [
|
|
1076
|
+
[0, .02],
|
|
1077
|
+
[1e3, .03],
|
|
1078
|
+
[2e3, .04],
|
|
1079
|
+
[3e3, .0475],
|
|
1080
|
+
[1e5, .05],
|
|
1081
|
+
[125e3, .0525],
|
|
1082
|
+
[15e4, .055],
|
|
1083
|
+
[25e4, .0575],
|
|
1084
|
+
[5e5, .0625],
|
|
1085
|
+
[1e6, .065]
|
|
1086
|
+
],
|
|
1087
|
+
mfj: [
|
|
1088
|
+
[0, .02],
|
|
1089
|
+
[1e3, .03],
|
|
1090
|
+
[2e3, .04],
|
|
1091
|
+
[3e3, .0475],
|
|
1092
|
+
[15e4, .05],
|
|
1093
|
+
[175e3, .0525],
|
|
1094
|
+
[225e3, .055],
|
|
1095
|
+
[3e5, .0575],
|
|
1096
|
+
[6e5, .0625],
|
|
1097
|
+
[12e5, .065]
|
|
1098
|
+
],
|
|
1099
|
+
hoh: "mfj",
|
|
1100
|
+
std: [
|
|
1101
|
+
3400,
|
|
1102
|
+
6800,
|
|
1103
|
+
6800
|
|
1104
|
+
],
|
|
1105
|
+
personalExemption: [3200, 6400],
|
|
1106
|
+
dependentExemption: 3200
|
|
1107
|
+
});
|
|
1108
|
+
// src/us/state/parameters/progressive/me.ts
|
|
1109
|
+
/**
|
|
1110
|
+
* 2026 Maine individual income tax parameters.
|
|
1111
|
+
*
|
|
1112
|
+
* Standard deduction phased out linearly over $75,000 (single, separate), $112,500 (head of
|
|
1113
|
+
* household) and $150,000 (joint) of AGI above $102,250, $153,400 and $204,550; the head of
|
|
1114
|
+
* household start is the statutory $120,000 indexed with the single and joint starts.
|
|
1115
|
+
* 2% surcharge on Maine taxable income above $1,000,000 (single), $1,500,000 (joint and head
|
|
1116
|
+
* of household) and $750,000 (separate), effective for tax years beginning in 2026.
|
|
1117
|
+
*
|
|
1118
|
+
* @statute Me. Rev. Stat. tit. 36, § 5111, sub-§ 7 (P.L. 2025, c. 650, Pt. DDDD)
|
|
1119
|
+
*/
|
|
1120
|
+
const US_2026_STATE_ME = defineState({
|
|
1121
|
+
code: "ME",
|
|
1122
|
+
name: "Maine",
|
|
1123
|
+
type: "progressive",
|
|
1124
|
+
single: [
|
|
1125
|
+
[0, .058],
|
|
1126
|
+
[27400, .0675],
|
|
1127
|
+
[64850, .0715]
|
|
1128
|
+
],
|
|
1129
|
+
mfj: [
|
|
1130
|
+
[0, .058],
|
|
1131
|
+
[54850, .0675],
|
|
1132
|
+
[129750, .0715]
|
|
1133
|
+
],
|
|
1134
|
+
hoh: [
|
|
1135
|
+
[0, .058],
|
|
1136
|
+
[41100, .0675],
|
|
1137
|
+
[97300, .0715]
|
|
1138
|
+
],
|
|
1139
|
+
std: [
|
|
1140
|
+
15700,
|
|
1141
|
+
31400,
|
|
1142
|
+
23550
|
|
1143
|
+
],
|
|
1144
|
+
personalExemption: [5300, 10600],
|
|
1145
|
+
dependentCredit: 305,
|
|
1146
|
+
standardDeductionPhaseOut: {
|
|
1147
|
+
kind: "linear",
|
|
1148
|
+
start: {
|
|
1149
|
+
single: 102250,
|
|
1150
|
+
married_filing_jointly: 204550,
|
|
1151
|
+
married_filing_separately: 102250,
|
|
1152
|
+
head_of_household: 153400
|
|
1153
|
+
},
|
|
1154
|
+
width: {
|
|
1155
|
+
single: 75e3,
|
|
1156
|
+
married_filing_jointly: 15e4,
|
|
1157
|
+
married_filing_separately: 75e3,
|
|
1158
|
+
head_of_household: 112500
|
|
1159
|
+
}
|
|
1160
|
+
},
|
|
1161
|
+
surtax: {
|
|
1162
|
+
threshold: {
|
|
1163
|
+
single: 1e6,
|
|
1164
|
+
married_filing_jointly: 15e5,
|
|
1165
|
+
married_filing_separately: 75e4,
|
|
1166
|
+
head_of_household: 15e5
|
|
1167
|
+
},
|
|
1168
|
+
rate: .02
|
|
1169
|
+
}
|
|
1170
|
+
});
|
|
1171
|
+
// src/us/state/parameters/progressive/mn.ts
|
|
1172
|
+
/**
|
|
1173
|
+
* 2026 Minnesota individual income tax parameters.
|
|
1174
|
+
*
|
|
1175
|
+
* Standard deduction reduced by 3% of AGI over $244,400 plus 10% over $337,800 (halved for
|
|
1176
|
+
* separate filers), capped at 80% of the deduction; the dependent exemption is disallowed 2%
|
|
1177
|
+
* per $2,500 (separate: $1,250) of AGI over the threshold. Amounts are the 2026 values published
|
|
1178
|
+
* by the Minnesota Department of Revenue. The statutory 80% cut-off above $1,107,750 is always
|
|
1179
|
+
* reached earlier through the 80% cap and is not modeled separately.
|
|
1180
|
+
*
|
|
1181
|
+
* @statute Minn. Stat. §§ 290.06, 290.0121 subd. 2, 290.0123 subd. 5
|
|
1182
|
+
*/
|
|
1183
|
+
const US_2026_STATE_MN = defineState({
|
|
1184
|
+
code: "MN",
|
|
1185
|
+
name: "Minnesota",
|
|
1186
|
+
type: "progressive",
|
|
1187
|
+
single: [
|
|
1188
|
+
[0, .0535],
|
|
1189
|
+
[33310, .068],
|
|
1190
|
+
[109430, .0785],
|
|
1191
|
+
[203150, .0985]
|
|
1192
|
+
],
|
|
1193
|
+
mfj: [
|
|
1194
|
+
[0, .0535],
|
|
1195
|
+
[48700, .068],
|
|
1196
|
+
[193480, .0785],
|
|
1197
|
+
[337930, .0985]
|
|
1198
|
+
],
|
|
1199
|
+
hoh: [
|
|
1200
|
+
[0, .0535],
|
|
1201
|
+
[41010, .068],
|
|
1202
|
+
[164800, .0785],
|
|
1203
|
+
[270060, .0985]
|
|
1204
|
+
],
|
|
1205
|
+
std: [
|
|
1206
|
+
15300,
|
|
1207
|
+
30600,
|
|
1208
|
+
23e3
|
|
1209
|
+
],
|
|
1210
|
+
mfs: "half-mfj",
|
|
1211
|
+
dependentExemption: 5300,
|
|
1212
|
+
standardDeductionPhaseOut: {
|
|
1213
|
+
kind: "tiered",
|
|
1214
|
+
start: {
|
|
1215
|
+
single: 244400,
|
|
1216
|
+
married_filing_jointly: 244400,
|
|
1217
|
+
married_filing_separately: 122200,
|
|
1218
|
+
head_of_household: 244400
|
|
1219
|
+
},
|
|
1220
|
+
second: {
|
|
1221
|
+
single: 337800,
|
|
1222
|
+
married_filing_jointly: 337800,
|
|
1223
|
+
married_filing_separately: 168900,
|
|
1224
|
+
head_of_household: 337800
|
|
1225
|
+
},
|
|
1226
|
+
rate: .03,
|
|
1227
|
+
secondRate: .1,
|
|
1228
|
+
maxShare: .8
|
|
1229
|
+
},
|
|
1230
|
+
dependentExemptionPhaseOut: {
|
|
1231
|
+
kind: "stepped",
|
|
1232
|
+
start: {
|
|
1233
|
+
single: 244500,
|
|
1234
|
+
married_filing_jointly: 366700,
|
|
1235
|
+
married_filing_separately: 183350,
|
|
1236
|
+
head_of_household: 305600
|
|
1237
|
+
},
|
|
1238
|
+
step: {
|
|
1239
|
+
single: 2500,
|
|
1240
|
+
married_filing_jointly: 2500,
|
|
1241
|
+
married_filing_separately: 1250,
|
|
1242
|
+
head_of_household: 2500
|
|
1243
|
+
},
|
|
1244
|
+
ratePerStep: .02
|
|
1245
|
+
}
|
|
1246
|
+
});
|
|
1247
|
+
// src/us/state/parameters/progressive/mo.ts
|
|
1248
|
+
/**
|
|
1249
|
+
* 2026 Missouri individual income tax parameters.
|
|
1250
|
+
*
|
|
1251
|
+
* @statute Mo. Rev. Stat. § 143.011
|
|
1252
|
+
*/
|
|
1253
|
+
const US_2026_STATE_MO = defineState({
|
|
1254
|
+
code: "MO",
|
|
1255
|
+
name: "Missouri",
|
|
1256
|
+
type: "progressive",
|
|
1257
|
+
single: [
|
|
1258
|
+
[1348, .02],
|
|
1259
|
+
[2696, .025],
|
|
1260
|
+
[4044, .03],
|
|
1261
|
+
[5392, .035],
|
|
1262
|
+
[6740, .04],
|
|
1263
|
+
[8088, .045],
|
|
1264
|
+
[9436, .047]
|
|
1265
|
+
],
|
|
1266
|
+
mfj: [
|
|
1267
|
+
[2696, .02],
|
|
1268
|
+
[5392, .025],
|
|
1269
|
+
[8088, .03],
|
|
1270
|
+
[10784, .035],
|
|
1271
|
+
[13480, .04],
|
|
1272
|
+
[16176, .045],
|
|
1273
|
+
[18872, .047]
|
|
1274
|
+
],
|
|
1275
|
+
std: [16100, 32200]
|
|
1276
|
+
});
|
|
1277
|
+
// src/us/state/parameters/progressive/mt.ts
|
|
1278
|
+
/**
|
|
1279
|
+
* 2026 Montana individual income tax parameters.
|
|
1280
|
+
*
|
|
1281
|
+
* @statute Mont. Code Ann. § 15-30-2103
|
|
1282
|
+
*/
|
|
1283
|
+
const US_2026_STATE_MT = defineState({
|
|
1284
|
+
code: "MT",
|
|
1285
|
+
name: "Montana",
|
|
1286
|
+
type: "progressive",
|
|
1287
|
+
single: [[0, .047], [47500, .0565]],
|
|
1288
|
+
mfj: [[0, .047], [95e3, .0565]],
|
|
1289
|
+
std: [16100, 32200]
|
|
1290
|
+
});
|
|
1291
|
+
// src/us/state/parameters/progressive/nd.ts
|
|
1292
|
+
/**
|
|
1293
|
+
* 2026 North Dakota individual income tax parameters.
|
|
1294
|
+
*
|
|
1295
|
+
* @statute N.D. Cent. Code § 57-38-30.3
|
|
1296
|
+
*/
|
|
1297
|
+
const US_2026_STATE_ND = defineState({
|
|
1298
|
+
code: "ND",
|
|
1299
|
+
name: "North Dakota",
|
|
1300
|
+
type: "progressive",
|
|
1301
|
+
single: [[48475, .0195], [244825, .025]],
|
|
1302
|
+
mfj: [[80975, .0195], [298075, .025]],
|
|
1303
|
+
mfs: [[40475, .0195], [149025, .025]],
|
|
1304
|
+
hoh: [[64950, .0195], [271450, .025]],
|
|
1305
|
+
std: [16100, 32200]
|
|
1306
|
+
});
|
|
1307
|
+
// src/us/state/parameters/progressive/ne.ts
|
|
1308
|
+
/**
|
|
1309
|
+
* 2026 Nebraska individual income tax parameters.
|
|
1310
|
+
*
|
|
1311
|
+
* @statute Neb. Rev. Stat. § 77-2715.03
|
|
1312
|
+
*/
|
|
1313
|
+
const US_2026_STATE_NE = defineState({
|
|
1314
|
+
code: "NE",
|
|
1315
|
+
name: "Nebraska",
|
|
1316
|
+
type: "progressive",
|
|
1317
|
+
single: [
|
|
1318
|
+
[0, .0246],
|
|
1319
|
+
[4130, .0351],
|
|
1320
|
+
[24760, .0455]
|
|
1321
|
+
],
|
|
1322
|
+
mfj: [
|
|
1323
|
+
[0, .0246],
|
|
1324
|
+
[8250, .0351],
|
|
1325
|
+
[49530, .0455]
|
|
1326
|
+
],
|
|
1327
|
+
std: [8850, 17700],
|
|
1328
|
+
personalCredit: [176, 352],
|
|
1329
|
+
dependentCredit: 176
|
|
1330
|
+
});
|
|
1331
|
+
// src/us/state/parameters/progressive/nj.ts
|
|
1332
|
+
/**
|
|
1333
|
+
* 2026 New Jersey individual income tax parameters.
|
|
1334
|
+
*
|
|
1335
|
+
* @statute N.J. Stat. Ann. § 54A:2-1
|
|
1336
|
+
*/
|
|
1337
|
+
const US_2026_STATE_NJ = defineState({
|
|
1338
|
+
code: "NJ",
|
|
1339
|
+
name: "New Jersey",
|
|
1340
|
+
type: "progressive",
|
|
1341
|
+
single: [
|
|
1342
|
+
[0, .014],
|
|
1343
|
+
[2e4, .0175],
|
|
1344
|
+
[35e3, .035],
|
|
1345
|
+
[4e4, .05525],
|
|
1346
|
+
[75e3, .0637],
|
|
1347
|
+
[5e5, .0897],
|
|
1348
|
+
[1e6, .1075]
|
|
1349
|
+
],
|
|
1350
|
+
mfj: [
|
|
1351
|
+
[0, .014],
|
|
1352
|
+
[2e4, .0175],
|
|
1353
|
+
[5e4, .0245],
|
|
1354
|
+
[7e4, .035],
|
|
1355
|
+
[8e4, .05525],
|
|
1356
|
+
[15e4, .0637],
|
|
1357
|
+
[5e5, .0897],
|
|
1358
|
+
[1e6, .1075]
|
|
1359
|
+
],
|
|
1360
|
+
hoh: "mfj",
|
|
1361
|
+
std: [0, 0],
|
|
1362
|
+
personalExemption: [1e3, 2e3],
|
|
1363
|
+
dependentExemption: 1500
|
|
1364
|
+
});
|
|
1365
|
+
// src/us/state/parameters/progressive/nm.ts
|
|
1366
|
+
/**
|
|
1367
|
+
* 2026 New Mexico individual income tax parameters.
|
|
1368
|
+
*
|
|
1369
|
+
* @statute N.M. Stat. Ann. § 7-2-7
|
|
1370
|
+
*/
|
|
1371
|
+
const US_2026_STATE_NM = defineState({
|
|
1372
|
+
code: "NM",
|
|
1373
|
+
name: "New Mexico",
|
|
1374
|
+
type: "progressive",
|
|
1375
|
+
single: [
|
|
1376
|
+
[0, .015],
|
|
1377
|
+
[5500, .032],
|
|
1378
|
+
[16500, .043],
|
|
1379
|
+
[33500, .047],
|
|
1380
|
+
[66500, .049],
|
|
1381
|
+
[21e4, .059]
|
|
1382
|
+
],
|
|
1383
|
+
mfj: [
|
|
1384
|
+
[0, .015],
|
|
1385
|
+
[8e3, .032],
|
|
1386
|
+
[25e3, .043],
|
|
1387
|
+
[5e4, .047],
|
|
1388
|
+
[1e5, .049],
|
|
1389
|
+
[315e3, .059]
|
|
1390
|
+
],
|
|
1391
|
+
mfs: "half-mfj",
|
|
1392
|
+
hoh: "mfj",
|
|
1393
|
+
std: [16100, 32200],
|
|
1394
|
+
dependentExemption: 4e3
|
|
1395
|
+
});
|
|
1396
|
+
// src/us/state/parameters/progressive/ny.ts
|
|
1397
|
+
/**
|
|
1398
|
+
* 2026 New York individual income tax parameters.
|
|
1399
|
+
*
|
|
1400
|
+
* @statute N.Y. Tax Law § 601
|
|
1401
|
+
*/
|
|
1402
|
+
const US_2026_STATE_NY = defineState({
|
|
1403
|
+
code: "NY",
|
|
1404
|
+
name: "New York",
|
|
1405
|
+
type: "progressive",
|
|
1406
|
+
single: [
|
|
1407
|
+
[0, .039],
|
|
1408
|
+
[8500, .044],
|
|
1409
|
+
[11700, .0515],
|
|
1410
|
+
[13900, .054],
|
|
1411
|
+
[80650, .059],
|
|
1412
|
+
[215400, .0685],
|
|
1413
|
+
[1077550, .0965],
|
|
1414
|
+
[5e6, .103],
|
|
1415
|
+
[25e6, .109]
|
|
1416
|
+
],
|
|
1417
|
+
mfj: [
|
|
1418
|
+
[0, .039],
|
|
1419
|
+
[17150, .044],
|
|
1420
|
+
[23600, .0515],
|
|
1421
|
+
[27900, .054],
|
|
1422
|
+
[161550, .059],
|
|
1423
|
+
[323200, .0685],
|
|
1424
|
+
[2155350, .0965],
|
|
1425
|
+
[5e6, .103],
|
|
1426
|
+
[25e6, .109]
|
|
1427
|
+
],
|
|
1428
|
+
hoh: [
|
|
1429
|
+
[0, .039],
|
|
1430
|
+
[12800, .044],
|
|
1431
|
+
[17650, .0515],
|
|
1432
|
+
[20900, .054],
|
|
1433
|
+
[107650, .059],
|
|
1434
|
+
[269300, .0685],
|
|
1435
|
+
[1616450, .0965],
|
|
1436
|
+
[5e6, .103],
|
|
1437
|
+
[25e6, .109]
|
|
1438
|
+
],
|
|
1439
|
+
std: [
|
|
1440
|
+
8e3,
|
|
1441
|
+
16050,
|
|
1442
|
+
11200
|
|
1443
|
+
],
|
|
1444
|
+
stdMfs: 8e3,
|
|
1445
|
+
dependentExemption: 1e3
|
|
1446
|
+
});
|
|
1447
|
+
// src/us/state/parameters/progressive/ok.ts
|
|
1448
|
+
/**
|
|
1449
|
+
* 2026 Oklahoma individual income tax parameters.
|
|
1450
|
+
*
|
|
1451
|
+
* @statute Okla. Stat. tit. 68, § 2355
|
|
1452
|
+
*/
|
|
1453
|
+
const US_2026_STATE_OK = defineState({
|
|
1454
|
+
code: "OK",
|
|
1455
|
+
name: "Oklahoma",
|
|
1456
|
+
type: "progressive",
|
|
1457
|
+
single: [
|
|
1458
|
+
[3750, .025],
|
|
1459
|
+
[4900, .035],
|
|
1460
|
+
[7200, .045]
|
|
1461
|
+
],
|
|
1462
|
+
mfj: [
|
|
1463
|
+
[7500, .025],
|
|
1464
|
+
[9800, .035],
|
|
1465
|
+
[14400, .045]
|
|
1466
|
+
],
|
|
1467
|
+
hoh: "mfj",
|
|
1468
|
+
std: [
|
|
1469
|
+
6350,
|
|
1470
|
+
12700,
|
|
1471
|
+
9350
|
|
1472
|
+
],
|
|
1473
|
+
personalExemption: [1e3, 2e3],
|
|
1474
|
+
dependentExemption: 1e3
|
|
1475
|
+
});
|
|
1476
|
+
// src/us/state/parameters/progressive/or.ts
|
|
1477
|
+
/**
|
|
1478
|
+
* 2026 Oregon individual income tax parameters.
|
|
1479
|
+
*
|
|
1480
|
+
* @statute Or. Rev. Stat. § 316.037
|
|
1481
|
+
*/
|
|
1482
|
+
const US_2026_STATE_OR = defineState({
|
|
1483
|
+
code: "OR",
|
|
1484
|
+
name: "Oregon",
|
|
1485
|
+
type: "progressive",
|
|
1486
|
+
single: [
|
|
1487
|
+
[0, .0475],
|
|
1488
|
+
[4550, .0675],
|
|
1489
|
+
[11400, .0875],
|
|
1490
|
+
[125e3, .099]
|
|
1491
|
+
],
|
|
1492
|
+
mfj: [
|
|
1493
|
+
[0, .0475],
|
|
1494
|
+
[9100, .0675],
|
|
1495
|
+
[22800, .0875],
|
|
1496
|
+
[25e4, .099]
|
|
1497
|
+
],
|
|
1498
|
+
hoh: "mfj",
|
|
1499
|
+
std: [
|
|
1500
|
+
2910,
|
|
1501
|
+
5820,
|
|
1502
|
+
4420
|
|
1503
|
+
],
|
|
1504
|
+
personalCredit: [256, 512],
|
|
1505
|
+
dependentCredit: 256
|
|
1506
|
+
});
|
|
1507
|
+
// src/us/state/parameters/progressive/ri.ts
|
|
1508
|
+
/**
|
|
1509
|
+
* 2026 Rhode Island individual income tax parameters.
|
|
1510
|
+
*
|
|
1511
|
+
* @statute R.I. Gen. Laws § 44-30-2.6
|
|
1512
|
+
*/
|
|
1513
|
+
const US_2026_STATE_RI = defineState({
|
|
1514
|
+
code: "RI",
|
|
1515
|
+
name: "Rhode Island",
|
|
1516
|
+
type: "progressive",
|
|
1517
|
+
single: [
|
|
1518
|
+
[0, .0375],
|
|
1519
|
+
[82050, .0475],
|
|
1520
|
+
[186450, .0599]
|
|
1521
|
+
],
|
|
1522
|
+
mfj: [
|
|
1523
|
+
[0, .0375],
|
|
1524
|
+
[82050, .0475],
|
|
1525
|
+
[186450, .0599]
|
|
1526
|
+
],
|
|
1527
|
+
std: [11200, 22400],
|
|
1528
|
+
personalExemption: [5250, 10500],
|
|
1529
|
+
dependentExemption: 5250
|
|
1530
|
+
});
|
|
1531
|
+
// src/us/state/parameters/progressive/sc.ts
|
|
1532
|
+
/**
|
|
1533
|
+
* 2026 South Carolina individual income tax parameters.
|
|
1534
|
+
*
|
|
1535
|
+
* @statute S.C. Code Ann. § 12-6-510
|
|
1536
|
+
*/
|
|
1537
|
+
const US_2026_STATE_SC = defineState({
|
|
1538
|
+
code: "SC",
|
|
1539
|
+
name: "South Carolina",
|
|
1540
|
+
type: "progressive",
|
|
1541
|
+
single: [
|
|
1542
|
+
[0, 0],
|
|
1543
|
+
[3640, .03],
|
|
1544
|
+
[18230, .06]
|
|
1545
|
+
],
|
|
1546
|
+
mfj: [
|
|
1547
|
+
[0, 0],
|
|
1548
|
+
[3640, .03],
|
|
1549
|
+
[18230, .06]
|
|
1550
|
+
],
|
|
1551
|
+
std: [
|
|
1552
|
+
16100,
|
|
1553
|
+
32200,
|
|
1554
|
+
24150
|
|
1555
|
+
],
|
|
1556
|
+
dependentExemption: 4930
|
|
1557
|
+
});
|
|
1558
|
+
// src/us/state/parameters/progressive/va.ts
|
|
1559
|
+
/**
|
|
1560
|
+
* 2026 Virginia individual income tax parameters.
|
|
1561
|
+
*
|
|
1562
|
+
* @statute Va. Code Ann. § 58.1-320
|
|
1563
|
+
*/
|
|
1564
|
+
const US_2026_STATE_VA = defineState({
|
|
1565
|
+
code: "VA",
|
|
1566
|
+
name: "Virginia",
|
|
1567
|
+
type: "progressive",
|
|
1568
|
+
single: [
|
|
1569
|
+
[0, .02],
|
|
1570
|
+
[3e3, .03],
|
|
1571
|
+
[5e3, .05],
|
|
1572
|
+
[17e3, .0575]
|
|
1573
|
+
],
|
|
1574
|
+
mfj: [
|
|
1575
|
+
[0, .02],
|
|
1576
|
+
[3e3, .03],
|
|
1577
|
+
[5e3, .05],
|
|
1578
|
+
[17e3, .0575]
|
|
1579
|
+
],
|
|
1580
|
+
std: [
|
|
1581
|
+
8750,
|
|
1582
|
+
17500,
|
|
1583
|
+
8750
|
|
1584
|
+
],
|
|
1585
|
+
personalExemption: [930, 1860],
|
|
1586
|
+
dependentExemption: 930
|
|
1587
|
+
});
|
|
1588
|
+
// src/us/state/parameters/progressive/vt.ts
|
|
1589
|
+
/**
|
|
1590
|
+
* 2026 Vermont individual income tax parameters.
|
|
1591
|
+
*
|
|
1592
|
+
* @statute Vt. Stat. Ann. tit. 32, § 5822
|
|
1593
|
+
*/
|
|
1594
|
+
const US_2026_STATE_VT = defineState({
|
|
1595
|
+
code: "VT",
|
|
1596
|
+
name: "Vermont",
|
|
1597
|
+
type: "progressive",
|
|
1598
|
+
single: [
|
|
1599
|
+
[0, .0335],
|
|
1600
|
+
[49400, .066],
|
|
1601
|
+
[119700, .076],
|
|
1602
|
+
[249700, .0875]
|
|
1603
|
+
],
|
|
1604
|
+
mfj: [
|
|
1605
|
+
[0, .0335],
|
|
1606
|
+
[82500, .066],
|
|
1607
|
+
[199450, .076],
|
|
1608
|
+
[304e3, .0875]
|
|
1609
|
+
],
|
|
1610
|
+
mfs: "half-mfj",
|
|
1611
|
+
std: [7650, 15300],
|
|
1612
|
+
personalExemption: [5300, 10600],
|
|
1613
|
+
dependentExemption: 5300
|
|
1614
|
+
});
|
|
1615
|
+
// src/us/state/parameters/progressive/wi.ts
|
|
1616
|
+
/**
|
|
1617
|
+
* 2026 Wisconsin individual income tax parameters.
|
|
1618
|
+
*
|
|
1619
|
+
* @statute Wis. Stat. § 71.06
|
|
1620
|
+
*/
|
|
1621
|
+
const US_2026_STATE_WI = defineState({
|
|
1622
|
+
code: "WI",
|
|
1623
|
+
name: "Wisconsin",
|
|
1624
|
+
type: "progressive",
|
|
1625
|
+
single: [
|
|
1626
|
+
[0, .035],
|
|
1627
|
+
[15110, .044],
|
|
1628
|
+
[51950, .053],
|
|
1629
|
+
[332720, .0765]
|
|
1630
|
+
],
|
|
1631
|
+
mfj: [
|
|
1632
|
+
[0, .035],
|
|
1633
|
+
[20150, .044],
|
|
1634
|
+
[69260, .053],
|
|
1635
|
+
[443630, .0765]
|
|
1636
|
+
],
|
|
1637
|
+
mfs: "half-mfj",
|
|
1638
|
+
std: [
|
|
1639
|
+
13960,
|
|
1640
|
+
25840,
|
|
1641
|
+
17950
|
|
1642
|
+
],
|
|
1643
|
+
personalExemption: [700, 1400],
|
|
1644
|
+
dependentExemption: 700
|
|
1645
|
+
});
|
|
1646
|
+
/** Statutory parameter table for all 2026 graduated-rate state individual income taxes. */
|
|
1647
|
+
const PROGRESSIVE_STATES = [
|
|
1648
|
+
US_2026_STATE_AL,
|
|
1649
|
+
US_2026_STATE_AR,
|
|
1650
|
+
US_2026_STATE_CA,
|
|
1651
|
+
US_2026_STATE_CT,
|
|
1652
|
+
US_2026_STATE_DE,
|
|
1653
|
+
US_2026_STATE_DC,
|
|
1654
|
+
US_2026_STATE_HI,
|
|
1655
|
+
US_2026_STATE_KS,
|
|
1656
|
+
US_2026_STATE_ME,
|
|
1657
|
+
US_2026_STATE_MD,
|
|
1658
|
+
US_2026_STATE_MN,
|
|
1659
|
+
US_2026_STATE_MO,
|
|
1660
|
+
US_2026_STATE_MT,
|
|
1661
|
+
US_2026_STATE_NE,
|
|
1662
|
+
US_2026_STATE_NJ,
|
|
1663
|
+
US_2026_STATE_NM,
|
|
1664
|
+
US_2026_STATE_NY,
|
|
1665
|
+
US_2026_STATE_ND,
|
|
1666
|
+
US_2026_STATE_OK,
|
|
1667
|
+
US_2026_STATE_OR,
|
|
1668
|
+
US_2026_STATE_RI,
|
|
1669
|
+
US_2026_STATE_SC,
|
|
1670
|
+
US_2026_STATE_VT,
|
|
1671
|
+
US_2026_STATE_VA,
|
|
1672
|
+
defineState({
|
|
1673
|
+
code: "WV",
|
|
1674
|
+
name: "West Virginia",
|
|
1675
|
+
type: "progressive",
|
|
1676
|
+
single: [
|
|
1677
|
+
[0, .0211],
|
|
1678
|
+
[1e4, .0281],
|
|
1679
|
+
[25e3, .0316],
|
|
1680
|
+
[4e4, .0422],
|
|
1681
|
+
[6e4, .0458]
|
|
1682
|
+
],
|
|
1683
|
+
mfj: [
|
|
1684
|
+
[0, .0211],
|
|
1685
|
+
[1e4, .0281],
|
|
1686
|
+
[25e3, .0316],
|
|
1687
|
+
[4e4, .0422],
|
|
1688
|
+
[6e4, .0458]
|
|
1689
|
+
],
|
|
1690
|
+
mfs: "half-mfj",
|
|
1691
|
+
std: [0, 0],
|
|
1692
|
+
personalExemption: [2e3, 4e3],
|
|
1693
|
+
dependentExemption: 2e3
|
|
1694
|
+
}),
|
|
1695
|
+
US_2026_STATE_WI
|
|
1696
|
+
];
|
|
1697
|
+
// src/us/state/parameters/index.ts
|
|
1698
|
+
/**
|
|
1699
|
+
* Consolidated statutory parameter table for all 50 US states and the District of Columbia
|
|
1700
|
+
* for Tax Year 2026.
|
|
1701
|
+
*
|
|
1702
|
+
* @statute State individual income tax statutes; 2026 schedules as published by the
|
|
1703
|
+
* state revenue departments and compiled by the Tax Foundation (February 2026).
|
|
1704
|
+
*/
|
|
1705
|
+
const US_2026_STATE_PARAMETERS = indexStates([
|
|
1706
|
+
...NO_TAX_STATES,
|
|
1707
|
+
...FLAT_STATES,
|
|
1708
|
+
...PROGRESSIVE_STATES
|
|
1709
|
+
]);
|
|
1710
|
+
// src/us/calculate-result.ts
|
|
1711
|
+
function buildUsTaxResult(p) {
|
|
1712
|
+
const effRate = p.agiRes.grossIncomeCents > 0 ? Math.max(0, p.totalTaxCents) / p.agiRes.grossIncomeCents : 0;
|
|
1713
|
+
const netPayable = require_clamp.usd(require_clamp.fromMinorUnits(p.netTaxCents, "USD", "netTaxPayable", { allowNegative: true }), "netTaxPayable", { allowNegative: true });
|
|
1714
|
+
return {
|
|
1715
|
+
jurisdiction: "US",
|
|
1716
|
+
taxYear: 2026,
|
|
1717
|
+
currency: "USD",
|
|
1718
|
+
grossIncome: p.agiRes.grossIncome,
|
|
1719
|
+
taxableIncome: p.dedRes.taxableIncome,
|
|
1720
|
+
totalTax: require_clamp.usd(require_clamp.fromMinorUnits(p.totalTaxCents, "USD")),
|
|
1721
|
+
effectiveRate: effRate,
|
|
1722
|
+
marginalRate: p.ordMarginalRate + (p.stateRes.breakdown?.marginalRate ?? 0),
|
|
1723
|
+
netTaxPayable: netPayable,
|
|
1724
|
+
breakdown: {
|
|
1725
|
+
ordinaryGrossIncome: p.agiRes.ordinaryGrossIncome,
|
|
1726
|
+
preferentialGrossIncome: p.agiRes.preferentialGrossIncome,
|
|
1727
|
+
grossIncome: p.agiRes.grossIncome,
|
|
1728
|
+
adjustments: p.agiRes.adjustments,
|
|
1729
|
+
agi: p.agiRes.agi,
|
|
1730
|
+
electedDeduction: p.dedRes.electedDeduction,
|
|
1731
|
+
standardDeduction: p.dedRes.standardBreakdown,
|
|
1732
|
+
itemizedDeductions: p.dedRes.itemizedBreakdown,
|
|
1733
|
+
allowableDeduction: p.dedRes.allowableDeduction,
|
|
1734
|
+
ordinaryTaxableIncome: p.dedRes.ordinaryTaxableIncome,
|
|
1735
|
+
preferentialTaxableIncome: p.dedRes.preferentialTaxableIncome,
|
|
1736
|
+
taxableIncome: p.dedRes.taxableIncome,
|
|
1737
|
+
ordinaryTax: require_clamp.usd(require_clamp.fromMinorUnits(p.ordTaxCents, "USD")),
|
|
1738
|
+
ordinarySlices: p.ordSlices,
|
|
1739
|
+
preferentialTax: p.prefRes.preferentialTax,
|
|
1740
|
+
preferentialSlices: p.prefRes.slices,
|
|
1741
|
+
regularIncomeTax: require_clamp.usd(require_clamp.fromMinorUnits(p.regularTaxCents, "USD")),
|
|
1742
|
+
amt: p.amtRes.breakdown,
|
|
1743
|
+
niit: p.niitRes.breakdown,
|
|
1744
|
+
fica: p.ficaRes.breakdown,
|
|
1745
|
+
scheduleSe: p.seRes.breakdown,
|
|
1746
|
+
credits: p.creditsRes.breakdown,
|
|
1747
|
+
state: p.stateRes.breakdown,
|
|
1748
|
+
totalTax: require_clamp.usd(require_clamp.fromMinorUnits(p.totalTaxCents, "USD")),
|
|
1749
|
+
withholding: require_clamp.usd(require_clamp.fromMinorUnits(p.withhCents, "USD")),
|
|
1750
|
+
netTaxPayable: netPayable
|
|
1751
|
+
}
|
|
1752
|
+
};
|
|
1753
|
+
}
|
|
1754
|
+
// src/us/stages/adjustments.ts
|
|
1755
|
+
function resolveAdjustmentClamped(amount, capDollars, field) {
|
|
1756
|
+
const reqCents = require_clamp.toMinorUnits(amount ?? 0, "USD", field);
|
|
1757
|
+
const capCents = require_clamp.toMinorUnits(capDollars, "USD", `${field}Cap`);
|
|
1758
|
+
const clampedCents = require_clamp.clampCap(reqCents, capCents, field);
|
|
1759
|
+
return {
|
|
1760
|
+
cents: clampedCents.allowed,
|
|
1761
|
+
clamped: {
|
|
1762
|
+
requested: require_clamp.fromMinorUnits(clampedCents.requested, "USD"),
|
|
1763
|
+
allowed: require_clamp.fromMinorUnits(clampedCents.allowed, "USD"),
|
|
1764
|
+
cap: require_clamp.fromMinorUnits(clampedCents.cap, "USD"),
|
|
1765
|
+
wasClamped: clampedCents.wasClamped
|
|
1766
|
+
}
|
|
1767
|
+
};
|
|
1768
|
+
}
|
|
1769
|
+
function resolveCaps(adj, status, params) {
|
|
1770
|
+
const p = params.aboveTheLineCaps;
|
|
1771
|
+
return {
|
|
1772
|
+
educator: status === "married_filing_jointly" && adj?.bothSpousesEducators ? p.educatorMfjBoth : p.educatorSingle,
|
|
1773
|
+
hsa: (adj?.hsaCoverageType === "family" ? p.hsaFamilyBase : p.hsaSelfOnlyBase) + (adj?.age55OrOlder ? p.hsaCatchUpAge55 : 0),
|
|
1774
|
+
ira: p.traditionalIraBase + (adj?.age50OrOlder ? p.traditionalIraCatchUpAge50 : 0),
|
|
1775
|
+
k401: p.traditional401kBase + (adj?.age50OrOlder ? p.traditional401kCatchUpAge50 : 0),
|
|
1776
|
+
student: p.studentLoanInterest
|
|
1777
|
+
};
|
|
1778
|
+
}
|
|
1779
|
+
/**
|
|
1780
|
+
* Evaluates Schedule 1 Above-the-Line Adjustments clamped to statutory caps.
|
|
1781
|
+
*
|
|
1782
|
+
* @statute IRC § 62, § 219, § 221, § 223, § 402(g)
|
|
1783
|
+
*/
|
|
1784
|
+
function calculateUsAdjustments(adjustments, filingStatus, params) {
|
|
1785
|
+
const caps = resolveCaps(adjustments, filingStatus, params);
|
|
1786
|
+
const edu = resolveAdjustmentClamped(adjustments?.educatorExpenses, caps.educator, "educatorExpenses");
|
|
1787
|
+
const hsa = resolveAdjustmentClamped(adjustments?.hsaContributions, caps.hsa, "hsaContributions");
|
|
1788
|
+
const ira = resolveAdjustmentClamped(adjustments?.traditionalIraContributions, caps.ira, "traditionalIra");
|
|
1789
|
+
const sl = resolveAdjustmentClamped(adjustments?.studentLoanInterest, caps.student, "studentLoanInterest");
|
|
1790
|
+
const k401 = resolveAdjustmentClamped(adjustments?.preTaxDeferrals401k, caps.k401, "preTaxDeferrals401k");
|
|
1791
|
+
const seCents = require_clamp.toMinorUnits(adjustments?.deductibleSelfEmploymentTax ?? 0, "USD", "deductibleSeTax");
|
|
1792
|
+
const totalAdjCents = edu.cents + hsa.cents + ira.cents + sl.cents + k401.cents + seCents;
|
|
1793
|
+
return {
|
|
1794
|
+
totalAdjCents,
|
|
1795
|
+
breakdown: {
|
|
1796
|
+
educatorExpenses: edu.clamped,
|
|
1797
|
+
hsa: hsa.clamped,
|
|
1798
|
+
traditionalIra: ira.clamped,
|
|
1799
|
+
studentLoanInterest: sl.clamped,
|
|
1800
|
+
preTaxDeferrals401k: k401.clamped,
|
|
1801
|
+
deductibleSelfEmploymentTax: require_clamp.usd(require_clamp.fromMinorUnits(seCents, "USD")),
|
|
1802
|
+
totalAdjustments: require_clamp.usd(require_clamp.fromMinorUnits(totalAdjCents, "USD"))
|
|
1803
|
+
}
|
|
1804
|
+
};
|
|
1805
|
+
}
|
|
1806
|
+
// src/us/stages/agi.ts
|
|
1807
|
+
function sumOrdinaryIncomeCents(income) {
|
|
1808
|
+
return require_clamp.toMinorUnits(income.w2Wages ?? 0, "USD", "w2Wages") + require_clamp.toMinorUnits(income.selfEmploymentNetEarnings ?? 0, "USD", "selfEmploymentNetEarnings", { allowNegative: true }) + require_clamp.toMinorUnits(income.ordinaryInterest ?? 0, "USD", "ordinaryInterest") + require_clamp.toMinorUnits(income.ordinaryDividends ?? 0, "USD", "ordinaryDividends") + require_clamp.toMinorUnits(income.shortTermCapitalGains ?? 0, "USD", "shortTermCapitalGains") + require_clamp.toMinorUnits(income.rentalAndOtherOrdinaryIncome ?? 0, "USD", "rentalAndOtherOrdinaryIncome");
|
|
1809
|
+
}
|
|
1810
|
+
function sumPreferentialIncomeCents(income) {
|
|
1811
|
+
return require_clamp.toMinorUnits(income.longTermCapitalGains ?? 0, "USD", "longTermCapitalGains") + require_clamp.toMinorUnits(income.qualifiedDividends ?? 0, "USD", "qualifiedDividends");
|
|
1812
|
+
}
|
|
1813
|
+
/**
|
|
1814
|
+
* Computes Gross Income, clamped Schedule 1 Adjustments, and AGI in minor units.
|
|
1815
|
+
*
|
|
1816
|
+
* @statute IRC § 61, § 62
|
|
1817
|
+
*/
|
|
1818
|
+
function calculateUsAgi(income, adjustments, filingStatus, params) {
|
|
1819
|
+
const ordinaryCents = sumOrdinaryIncomeCents(income);
|
|
1820
|
+
const prefCents = sumPreferentialIncomeCents(income);
|
|
1821
|
+
const grossCents = ordinaryCents + prefCents;
|
|
1822
|
+
const adjResult = calculateUsAdjustments(adjustments, filingStatus, params);
|
|
1823
|
+
const agiCents = Math.max(0, grossCents - adjResult.totalAdjCents);
|
|
1824
|
+
return {
|
|
1825
|
+
ordinaryGrossCents: ordinaryCents,
|
|
1826
|
+
preferentialGrossCents: prefCents,
|
|
1827
|
+
grossIncomeCents: grossCents,
|
|
1828
|
+
totalAdjustmentsCents: adjResult.totalAdjCents,
|
|
1829
|
+
agiCents,
|
|
1830
|
+
ordinaryGrossIncome: require_clamp.usd(require_clamp.fromMinorUnits(ordinaryCents, "USD", "ordinaryGrossIncome", { allowNegative: true }), "ordinaryGrossIncome", { allowNegative: true }),
|
|
1831
|
+
preferentialGrossIncome: require_clamp.usd(require_clamp.fromMinorUnits(prefCents, "USD")),
|
|
1832
|
+
grossIncome: require_clamp.usd(require_clamp.fromMinorUnits(grossCents, "USD", "grossIncome", { allowNegative: true }), "grossIncome", { allowNegative: true }),
|
|
1833
|
+
agi: require_clamp.usd(require_clamp.fromMinorUnits(agiCents, "USD")),
|
|
1834
|
+
adjustments: adjResult.breakdown
|
|
1835
|
+
};
|
|
1836
|
+
}
|
|
1837
|
+
// src/us/types/fields.ts
|
|
1838
|
+
/**
|
|
1839
|
+
* Diagnostic and reporting field identifiers for US income sources.
|
|
1840
|
+
*/
|
|
1841
|
+
let UsIncomeField = /* @__PURE__ */ function(UsIncomeField) {
|
|
1842
|
+
UsIncomeField["W2Wages"] = "income.w2Wages";
|
|
1843
|
+
UsIncomeField["SelfEmploymentNetEarnings"] = "income.selfEmploymentNetEarnings";
|
|
1844
|
+
UsIncomeField["OrdinaryInterest"] = "income.ordinaryInterest";
|
|
1845
|
+
UsIncomeField["OrdinaryDividends"] = "income.ordinaryDividends";
|
|
1846
|
+
UsIncomeField["ShortTermCapitalGains"] = "income.shortTermCapitalGains";
|
|
1847
|
+
UsIncomeField["RentalAndOtherOrdinaryIncome"] = "income.rentalAndOtherOrdinaryIncome";
|
|
1848
|
+
UsIncomeField["LongTermCapitalGains"] = "income.longTermCapitalGains";
|
|
1849
|
+
UsIncomeField["QualifiedDividends"] = "income.qualifiedDividends";
|
|
1850
|
+
return UsIncomeField;
|
|
1851
|
+
}({});
|
|
1852
|
+
/**
|
|
1853
|
+
* Diagnostic and reporting field identifiers for Schedule 1 adjustments.
|
|
1854
|
+
*/
|
|
1855
|
+
let UsAdjustmentField = /* @__PURE__ */ function(UsAdjustmentField) {
|
|
1856
|
+
UsAdjustmentField["EducatorExpenses"] = "adjustments.educatorExpenses";
|
|
1857
|
+
UsAdjustmentField["HsaContributions"] = "adjustments.hsaContributions";
|
|
1858
|
+
UsAdjustmentField["TraditionalIra"] = "adjustments.traditionalIra";
|
|
1859
|
+
UsAdjustmentField["StudentLoanInterest"] = "adjustments.studentLoanInterest";
|
|
1860
|
+
UsAdjustmentField["PreTaxDeferrals401k"] = "adjustments.preTaxDeferrals401k";
|
|
1861
|
+
UsAdjustmentField["DeductibleSeTax"] = "adjustments.deductibleSeTax";
|
|
1862
|
+
return UsAdjustmentField;
|
|
1863
|
+
}({});
|
|
1864
|
+
/**
|
|
1865
|
+
* Diagnostic and reporting field identifiers for Schedule A itemized deductions.
|
|
1866
|
+
*/
|
|
1867
|
+
let UsDeductionField = /* @__PURE__ */ function(UsDeductionField) {
|
|
1868
|
+
UsDeductionField["MedicalExpenses"] = "itemized.medicalExpenses";
|
|
1869
|
+
UsDeductionField["StateAndLocalTaxes"] = "itemized.stateAndLocalTaxes";
|
|
1870
|
+
UsDeductionField["MortgageInterest"] = "itemized.mortgageInterest";
|
|
1871
|
+
UsDeductionField["CharitableContributions"] = "itemized.charitableContributions";
|
|
1872
|
+
UsDeductionField["StandardDeduction"] = "deductions.standard";
|
|
1873
|
+
return UsDeductionField;
|
|
1874
|
+
}({});
|
|
1875
|
+
/**
|
|
1876
|
+
* Diagnostic and reporting field identifiers for Payroll and Self-Employment taxes.
|
|
1877
|
+
*/
|
|
1878
|
+
let UsPayrollField = /* @__PURE__ */ function(UsPayrollField) {
|
|
1879
|
+
UsPayrollField["FicaSocialSecurity"] = "payroll.fica.socialSecurity";
|
|
1880
|
+
UsPayrollField["FicaMedicare"] = "payroll.fica.medicare";
|
|
1881
|
+
UsPayrollField["FicaAdditionalMedicare"] = "payroll.fica.additionalMedicare";
|
|
1882
|
+
UsPayrollField["SeSocialSecurity"] = "payroll.se.socialSecurity";
|
|
1883
|
+
UsPayrollField["SeMedicare"] = "payroll.se.medicare";
|
|
1884
|
+
UsPayrollField["SeDeductiblePortion"] = "payroll.se.deductiblePortion";
|
|
1885
|
+
return UsPayrollField;
|
|
1886
|
+
}({});
|
|
1887
|
+
/**
|
|
1888
|
+
* Diagnostic and reporting field identifiers for Alternative Minimum Tax.
|
|
1889
|
+
*/
|
|
1890
|
+
let UsAmtField = /* @__PURE__ */ function(UsAmtField) {
|
|
1891
|
+
UsAmtField["Amti"] = "amt.amti";
|
|
1892
|
+
UsAmtField["Exemption"] = "amt.exemption";
|
|
1893
|
+
UsAmtField["Preferences"] = "amt.preferences";
|
|
1894
|
+
UsAmtField["TentativeMinimumTax"] = "amt.tentativeMinimumTax";
|
|
1895
|
+
UsAmtField["AmtTax"] = "amt.tax";
|
|
1896
|
+
return UsAmtField;
|
|
1897
|
+
}({});
|
|
1898
|
+
/**
|
|
1899
|
+
* Diagnostic and reporting field identifiers for Federal Tax Credits.
|
|
1900
|
+
*/
|
|
1901
|
+
let UsCreditField = /* @__PURE__ */ function(UsCreditField) {
|
|
1902
|
+
UsCreditField["ChildTaxCredit"] = "credits.ctc";
|
|
1903
|
+
UsCreditField["AdditionalChildTaxCredit"] = "credits.actc";
|
|
1904
|
+
UsCreditField["OtherDependentCredit"] = "credits.odc";
|
|
1905
|
+
UsCreditField["EarnedIncomeTaxCredit"] = "credits.eitc";
|
|
1906
|
+
UsCreditField["ChildAndDependentCare"] = "credits.care";
|
|
1907
|
+
UsCreditField["Aotc"] = "credits.aotc";
|
|
1908
|
+
UsCreditField["Llc"] = "credits.llc";
|
|
1909
|
+
UsCreditField["ForeignTaxCredit"] = "credits.ftc";
|
|
1910
|
+
UsCreditField["CustomNonRefundable"] = "credits.customNonRefundable";
|
|
1911
|
+
UsCreditField["CustomRefundable"] = "credits.customRefundable";
|
|
1912
|
+
return UsCreditField;
|
|
1913
|
+
}({});
|
|
1914
|
+
/**
|
|
1915
|
+
* Diagnostic and reporting field identifiers for US federal tax totals.
|
|
1916
|
+
*/
|
|
1917
|
+
let UsTaxField = /* @__PURE__ */ function(UsTaxField) {
|
|
1918
|
+
UsTaxField["GrossIncome"] = "grossIncome";
|
|
1919
|
+
UsTaxField["TaxableIncome"] = "taxableIncome";
|
|
1920
|
+
UsTaxField["RegularIncomeTax"] = "regularIncomeTax";
|
|
1921
|
+
UsTaxField["TotalTax"] = "totalTax";
|
|
1922
|
+
UsTaxField["Withholding"] = "withholding";
|
|
1923
|
+
UsTaxField["NetTaxPayable"] = "netTaxPayable";
|
|
1924
|
+
return UsTaxField;
|
|
1925
|
+
}({});
|
|
1926
|
+
// src/us/stages/amt.ts
|
|
1927
|
+
/**
|
|
1928
|
+
* Resolves the Schedule A SALT add-back for Form 6251.
|
|
1929
|
+
*
|
|
1930
|
+
* @param deductions Deduction stage result carrying the elected method and Schedule A.
|
|
1931
|
+
* @param currency Supported statutory currency threaded for minor-unit conversion.
|
|
1932
|
+
* @returns Allowed SALT deduction in integer cents (0 unless itemizing).
|
|
1933
|
+
* @throws {TaxValidationError} if the allowed SALT amount is not representable as cents.
|
|
1934
|
+
* @statute IRC § 56(b)(1)(A)(ii)
|
|
1935
|
+
*/
|
|
1936
|
+
function resolveAmtSaltCents(deductions, currency) {
|
|
1937
|
+
return deductions.electedDeduction === "itemized" && deductions.itemizedBreakdown ? require_clamp.toMinorUnits(deductions.itemizedBreakdown.salt.allowed, currency) : 0;
|
|
1938
|
+
}
|
|
1939
|
+
/**
|
|
1940
|
+
* Computes Form 6251 Alternative Minimum Tax (AMT).
|
|
1941
|
+
*
|
|
1942
|
+
* @statute IRC § 55
|
|
1943
|
+
*/
|
|
1944
|
+
function calculateUsAmt(taxableIncomeCents, saltDeductionCents, preferencesDollars, regularTaxCents, filingStatus, params) {
|
|
1945
|
+
const prefCents = require_clamp.toMinorUnits(preferencesDollars ?? 0, params.currency, "amt.preferences");
|
|
1946
|
+
const amtiCents = taxableIncomeCents + saltDeductionCents + prefCents;
|
|
1947
|
+
const baseExemptionCents = require_clamp.toMinorUnits(params.amt.baseExemptions[filingStatus], params.currency);
|
|
1948
|
+
const phaseoutCents = require_clamp.toMinorUnits(params.amt.phaseoutThresholds[filingStatus], params.currency);
|
|
1949
|
+
const excessAmtiCents = Math.max(0, amtiCents - phaseoutCents);
|
|
1950
|
+
const reductionCents = Math.round(excessAmtiCents * params.amt.phaseoutRate);
|
|
1951
|
+
const allowedExemptionCents = Math.max(0, baseExemptionCents - reductionCents);
|
|
1952
|
+
const amtBaseCents = Math.max(0, amtiCents - allowedExemptionCents);
|
|
1953
|
+
const cap26Cents = require_clamp.toMinorUnits(params.amt.rate26Thresholds[filingStatus], params.currency);
|
|
1954
|
+
let tmtCents;
|
|
1955
|
+
if (amtBaseCents <= cap26Cents) tmtCents = Math.round(amtBaseCents * params.amt.rate26);
|
|
1956
|
+
else tmtCents = Math.round(cap26Cents * params.amt.rate26 + (amtBaseCents - cap26Cents) * params.amt.rate28);
|
|
1957
|
+
const amtTaxCents = Math.max(0, tmtCents - regularTaxCents);
|
|
1958
|
+
return {
|
|
1959
|
+
amtTaxCents,
|
|
1960
|
+
tentativeMinimumTaxCents: tmtCents,
|
|
1961
|
+
breakdown: {
|
|
1962
|
+
taxableIncome: require_clamp.usd(require_clamp.fromMinorUnits(taxableIncomeCents, params.currency)),
|
|
1963
|
+
saltAddBack: require_clamp.usd(require_clamp.fromMinorUnits(saltDeductionCents, params.currency)),
|
|
1964
|
+
preferences: require_clamp.usd(require_clamp.fromMinorUnits(prefCents, params.currency, "amt.preferences")),
|
|
1965
|
+
amti: require_clamp.usd(require_clamp.fromMinorUnits(amtiCents, params.currency, "amt.amti")),
|
|
1966
|
+
baseExemption: require_clamp.usd(require_clamp.fromMinorUnits(baseExemptionCents, params.currency)),
|
|
1967
|
+
phaseoutThreshold: require_clamp.usd(require_clamp.fromMinorUnits(phaseoutCents, params.currency)),
|
|
1968
|
+
exemptionReduction: require_clamp.usd(require_clamp.fromMinorUnits(reductionCents, params.currency)),
|
|
1969
|
+
allowedExemption: require_clamp.usd(require_clamp.fromMinorUnits(allowedExemptionCents, params.currency, "amt.exemption")),
|
|
1970
|
+
amtTaxableBase: require_clamp.usd(require_clamp.fromMinorUnits(amtBaseCents, params.currency)),
|
|
1971
|
+
tentativeMinimumTax: require_clamp.usd(require_clamp.fromMinorUnits(tmtCents, params.currency, "amt.tentativeMinimumTax")),
|
|
1972
|
+
regularTax: require_clamp.usd(require_clamp.fromMinorUnits(regularTaxCents, params.currency)),
|
|
1973
|
+
amtTax: require_clamp.usd(require_clamp.fromMinorUnits(amtTaxCents, params.currency, "amt.tax"))
|
|
1974
|
+
}
|
|
1975
|
+
};
|
|
1976
|
+
}
|
|
1977
|
+
// src/us/stages/credits-child.ts
|
|
1978
|
+
function resolveCtcAllocation(initialCtc, initialOdc, reduction) {
|
|
1979
|
+
if (reduction <= initialOdc) return {
|
|
1980
|
+
allowedCtc: initialCtc,
|
|
1981
|
+
allowedOdc: initialOdc - reduction
|
|
1982
|
+
};
|
|
1983
|
+
const remReduction = reduction - initialOdc;
|
|
1984
|
+
return {
|
|
1985
|
+
allowedCtc: Math.max(0, initialCtc - remReduction),
|
|
1986
|
+
allowedOdc: 0
|
|
1987
|
+
};
|
|
1988
|
+
}
|
|
1989
|
+
/**
|
|
1990
|
+
* Computes Child Tax Credit (CTC), ODC, and refundable Additional Child Tax Credit (ACTC).
|
|
1991
|
+
*
|
|
1992
|
+
* @statute IRC § 24
|
|
1993
|
+
*/
|
|
1994
|
+
function calculateUsChildCredits(credits, magiDollars, earnedIncomeDollars, taxAvailableCents, status, params) {
|
|
1995
|
+
const children = Math.max(0, Math.floor(credits?.qualifyingChildrenForChildTaxCredit ?? 0));
|
|
1996
|
+
const otherDeps = Math.max(0, Math.floor(credits?.otherDependents ?? 0));
|
|
1997
|
+
const initCtc = children * params.credits.ctcAmountPerChild;
|
|
1998
|
+
const initOdc = otherDeps * params.credits.odcAmountPerDependent;
|
|
1999
|
+
const thresh = params.credits.ctcPhaseoutThresholds[status];
|
|
2000
|
+
const excessMagi = Math.max(0, magiDollars - thresh);
|
|
2001
|
+
const reduction = Math.ceil(excessMagi / params.credits.ctcPhaseoutStepAmount) * params.credits.ctcPhaseoutStepRate;
|
|
2002
|
+
const { allowedCtc, allowedOdc } = resolveCtcAllocation(initCtc, initOdc, reduction);
|
|
2003
|
+
const ctcCents = require_clamp.toMinorUnits(allowedCtc, params.currency);
|
|
2004
|
+
const odcCents = require_clamp.toMinorUnits(allowedOdc, params.currency);
|
|
2005
|
+
const nonRefCtcUsed = Math.min(ctcCents, taxAvailableCents);
|
|
2006
|
+
const nonRefOdcUsed = Math.min(odcCents, taxAvailableCents - nonRefCtcUsed);
|
|
2007
|
+
const unusedCtcDollars = allowedCtc - require_clamp.fromMinorUnits(nonRefCtcUsed, params.currency);
|
|
2008
|
+
const earnedFormula = Math.max(0, earnedIncomeDollars - params.credits.actcEarnedIncomeThreshold) * params.credits.actcRate;
|
|
2009
|
+
const maxActc = children * params.credits.actcMaxPerChild;
|
|
2010
|
+
const actcCents = require_clamp.toMinorUnits(Math.min(unusedCtcDollars, maxActc, earnedFormula), params.currency);
|
|
2011
|
+
return {
|
|
2012
|
+
nonRefundableUsedCents: nonRefCtcUsed + nonRefOdcUsed,
|
|
2013
|
+
actcRefundableCents: actcCents,
|
|
2014
|
+
breakdown: {
|
|
2015
|
+
qualifyingChildren: children,
|
|
2016
|
+
otherDependents: otherDeps,
|
|
2017
|
+
initialCtc: require_clamp.usd(require_clamp.fromMinorUnits(require_clamp.toMinorUnits(initCtc, params.currency), params.currency)),
|
|
2018
|
+
initialOdc: require_clamp.usd(require_clamp.fromMinorUnits(require_clamp.toMinorUnits(initOdc, params.currency), params.currency)),
|
|
2019
|
+
phaseoutReduction: require_clamp.usd(require_clamp.fromMinorUnits(require_clamp.toMinorUnits(reduction, params.currency), params.currency)),
|
|
2020
|
+
allowedCtc: require_clamp.usd(require_clamp.fromMinorUnits(ctcCents, params.currency)),
|
|
2021
|
+
allowedOdc: require_clamp.usd(require_clamp.fromMinorUnits(odcCents, params.currency)),
|
|
2022
|
+
nonRefundableCtcUsed: require_clamp.usd(require_clamp.fromMinorUnits(nonRefCtcUsed, params.currency, "credits.ctc")),
|
|
2023
|
+
nonRefundableOdcUsed: require_clamp.usd(require_clamp.fromMinorUnits(nonRefOdcUsed, params.currency, "credits.odc")),
|
|
2024
|
+
actcRefundable: require_clamp.usd(require_clamp.fromMinorUnits(actcCents, params.currency, "credits.actc"))
|
|
2025
|
+
}
|
|
2026
|
+
};
|
|
2027
|
+
}
|
|
2028
|
+
// src/us/stages/credits-eitc.ts
|
|
2029
|
+
function resolveTierKey(count) {
|
|
2030
|
+
if (count <= 0) return 0;
|
|
2031
|
+
if (count === 1) return 1;
|
|
2032
|
+
if (count === 2) return 2;
|
|
2033
|
+
return 3;
|
|
2034
|
+
}
|
|
2035
|
+
/**
|
|
2036
|
+
* Computes Earned Income Tax Credit (EITC) across child tiers 0, 1, 2, 3+.
|
|
2037
|
+
*
|
|
2038
|
+
* @statute IRC § 32
|
|
2039
|
+
*/
|
|
2040
|
+
function calculateUsEitc(credits, earnedIncomeDollars, investmentIncomeDollars, agiDollars, status, params) {
|
|
2041
|
+
const children = Math.max(0, Math.floor(credits?.eitcQualifyingChildren ?? 0));
|
|
2042
|
+
const invLimit = params.credits.eitcInvestmentIncomeLimit;
|
|
2043
|
+
if (investmentIncomeDollars > invLimit || status === "married_filing_separately" || earnedIncomeDollars <= 0) return {
|
|
2044
|
+
creditCents: 0,
|
|
2045
|
+
breakdown: {
|
|
2046
|
+
qualifyingChildren: children,
|
|
2047
|
+
earnedIncome: require_clamp.usd(require_clamp.fromMinorUnits(require_clamp.toMinorUnits(Math.max(0, earnedIncomeDollars), params.currency), params.currency)),
|
|
2048
|
+
disqualifiedByInvestmentIncome: investmentIncomeDollars > invLimit,
|
|
2049
|
+
credit: require_clamp.usd(0)
|
|
2050
|
+
}
|
|
2051
|
+
};
|
|
2052
|
+
const tierKey = resolveTierKey(children);
|
|
2053
|
+
const tier = params.credits.eitcTiers[tierKey];
|
|
2054
|
+
const tentative = Math.min(earnedIncomeDollars * tier.creditRate, tier.maxCredit);
|
|
2055
|
+
const phaseoutBasis = Math.max(earnedIncomeDollars, agiDollars);
|
|
2056
|
+
const thresh = status === "married_filing_jointly" ? tier.phaseoutThresholdMfj : tier.phaseoutThresholdSingle;
|
|
2057
|
+
const reduction = Math.max(0, phaseoutBasis - thresh) * tier.phaseoutRate;
|
|
2058
|
+
const creditDollars = Math.max(0, tentative - reduction);
|
|
2059
|
+
const creditCents = require_clamp.toMinorUnits(creditDollars, params.currency);
|
|
2060
|
+
return {
|
|
2061
|
+
creditCents,
|
|
2062
|
+
breakdown: {
|
|
2063
|
+
qualifyingChildren: children,
|
|
2064
|
+
earnedIncome: require_clamp.usd(require_clamp.fromMinorUnits(require_clamp.toMinorUnits(earnedIncomeDollars, params.currency), params.currency)),
|
|
2065
|
+
disqualifiedByInvestmentIncome: false,
|
|
2066
|
+
credit: require_clamp.usd(require_clamp.fromMinorUnits(creditCents, params.currency, "credits.eitc"))
|
|
2067
|
+
}
|
|
2068
|
+
};
|
|
2069
|
+
}
|
|
2070
|
+
// src/us/stages/credits-care.ts
|
|
2071
|
+
/**
|
|
2072
|
+
* Calculates Child and Dependent Care Credit (IRC § 21).
|
|
2073
|
+
*
|
|
2074
|
+
* @statute IRC § 21
|
|
2075
|
+
*/
|
|
2076
|
+
function calculateUsCareCredit(credits, earnedDollars, agiDollars, params) {
|
|
2077
|
+
const individuals = Math.max(0, credits?.qualifyingIndividualsForCare ?? 0);
|
|
2078
|
+
if (individuals <= 0) return 0;
|
|
2079
|
+
const maxExp = individuals >= 2 ? params.credits.careMaxExpenseTwoPlus : params.credits.careMaxExpenseOne;
|
|
2080
|
+
const expenses = Math.min(Math.max(0, credits?.childAndDependentCareExpenses ?? 0), maxExp, earnedDollars);
|
|
2081
|
+
const excessAgi = Math.max(0, agiDollars - params.credits.carePhaseoutAgiThreshold);
|
|
2082
|
+
const rateReduction = Math.ceil(excessAgi / params.credits.carePhaseoutStepAgi) * params.credits.carePhaseoutStepRate;
|
|
2083
|
+
const rate = Math.max(params.credits.careFloorRate, params.credits.careBaseRate - rateReduction);
|
|
2084
|
+
return require_clamp.toMinorUnits(expenses * rate, params.currency);
|
|
2085
|
+
}
|
|
2086
|
+
// src/us/stages/credits-other.ts
|
|
2087
|
+
function calculateEducationCredits(credits, magiDollars, status, params) {
|
|
2088
|
+
if (status === "married_filing_separately") return {
|
|
2089
|
+
nonRefAotc: 0,
|
|
2090
|
+
refAotc: 0,
|
|
2091
|
+
nonRefLlc: 0
|
|
2092
|
+
};
|
|
2093
|
+
const pMin = params.credits.aotcPhaseoutMin[status];
|
|
2094
|
+
const pMax = params.credits.aotcPhaseoutMax[status];
|
|
2095
|
+
const factor = magiDollars <= pMin ? 1 : magiDollars >= pMax ? 0 : (pMax - magiDollars) / (pMax - pMin);
|
|
2096
|
+
let rawAotc = 0;
|
|
2097
|
+
let llcExp = 0;
|
|
2098
|
+
for (const student of credits?.educationStudents ?? []) if (student.type === "aotc") {
|
|
2099
|
+
const exp = Math.max(0, student.qualifiedExpenses);
|
|
2100
|
+
const tier1 = Math.min(exp, params.credits.aotcTier1MaxExpense) * params.credits.aotcTier1Rate;
|
|
2101
|
+
const tier2 = Math.max(0, Math.min(exp - params.credits.aotcTier1MaxExpense, params.credits.aotcTier2MaxExpense)) * params.credits.aotcTier2Rate;
|
|
2102
|
+
const cappedStudentAotc = Math.min(tier1 + tier2, params.credits.aotcMaxPerStudent);
|
|
2103
|
+
rawAotc += cappedStudentAotc * factor;
|
|
2104
|
+
} else llcExp += Math.max(0, student.qualifiedExpenses);
|
|
2105
|
+
const refAotc = require_clamp.toMinorUnits(rawAotc * params.credits.aotcRefundableRate, params.currency);
|
|
2106
|
+
const nonRefAotc = require_clamp.toMinorUnits(rawAotc * (1 - params.credits.aotcRefundableRate), params.currency);
|
|
2107
|
+
const rawLlc = Math.min(llcExp, params.credits.llcMaxExpensePerReturn) * params.credits.llcRate * factor;
|
|
2108
|
+
return {
|
|
2109
|
+
nonRefAotc,
|
|
2110
|
+
refAotc,
|
|
2111
|
+
nonRefLlc: require_clamp.toMinorUnits(rawLlc, params.currency)
|
|
2112
|
+
};
|
|
2113
|
+
}
|
|
2114
|
+
/**
|
|
2115
|
+
* Computes Child and Dependent Care, Education, Foreign Tax, and Custom credits.
|
|
2116
|
+
*
|
|
2117
|
+
* @statute IRC §§ 21, 25A, 901
|
|
2118
|
+
*/
|
|
2119
|
+
function calculateUsOtherCredits(credits, earnedDollars, agiDollars, magiDollars, status, params) {
|
|
2120
|
+
const careCents = calculateUsCareCredit(credits, earnedDollars, agiDollars, params);
|
|
2121
|
+
const edu = calculateEducationCredits(credits, magiDollars, status, params);
|
|
2122
|
+
const ftcCents = require_clamp.toMinorUnits(Math.max(0, credits?.foreignTaxCredit ?? 0), params.currency);
|
|
2123
|
+
const custNonRefCents = require_clamp.toMinorUnits(Math.max(0, credits?.customNonRefundableCredits ?? 0), params.currency);
|
|
2124
|
+
const custRefCents = require_clamp.toMinorUnits(Math.max(0, credits?.customRefundableCredits ?? 0), params.currency);
|
|
2125
|
+
return {
|
|
2126
|
+
careNonRefundableCents: careCents,
|
|
2127
|
+
aotcNonRefundableCents: edu.nonRefAotc,
|
|
2128
|
+
aotcRefundableCents: edu.refAotc,
|
|
2129
|
+
llcNonRefundableCents: edu.nonRefLlc,
|
|
2130
|
+
foreignTaxCreditCents: ftcCents,
|
|
2131
|
+
customNonRefundableCents: custNonRefCents,
|
|
2132
|
+
customRefundableCents: custRefCents,
|
|
2133
|
+
educationBreakdown: {
|
|
2134
|
+
aotcNonRefundable: require_clamp.usd(require_clamp.fromMinorUnits(edu.nonRefAotc, params.currency)),
|
|
2135
|
+
aotcRefundable: require_clamp.usd(require_clamp.fromMinorUnits(edu.refAotc, params.currency)),
|
|
2136
|
+
llcNonRefundable: require_clamp.usd(require_clamp.fromMinorUnits(edu.nonRefLlc, params.currency)),
|
|
2137
|
+
totalNonRefundable: require_clamp.usd(require_clamp.fromMinorUnits(edu.nonRefAotc + edu.nonRefLlc, params.currency)),
|
|
2138
|
+
totalRefundable: require_clamp.usd(require_clamp.fromMinorUnits(edu.refAotc, params.currency))
|
|
2139
|
+
}
|
|
2140
|
+
};
|
|
2141
|
+
}
|
|
2142
|
+
// src/us/stages/se.ts
|
|
2143
|
+
/**
|
|
2144
|
+
* Calculates net earnings from self-employment subject to SECA/FICA tax (IRC § 1402(a)).
|
|
2145
|
+
*
|
|
2146
|
+
* @statute IRC § 1402(a)
|
|
2147
|
+
*/
|
|
2148
|
+
function calculateNetSelfEmploymentEarnings(earnings, seNetEarningsFactor) {
|
|
2149
|
+
return Math.max(0, (earnings ?? 0) * seNetEarningsFactor);
|
|
2150
|
+
}
|
|
2151
|
+
/**
|
|
2152
|
+
* Computes Schedule SE Self-Employment Tax (SECA).
|
|
2153
|
+
*
|
|
2154
|
+
* @statute IRC § 1401, § 1402
|
|
2155
|
+
*/
|
|
2156
|
+
function calculateUsScheduleSe(income, params) {
|
|
2157
|
+
const rawNetEarnings = Math.max(0, income.selfEmploymentNetEarnings ?? 0);
|
|
2158
|
+
const factor = params.payroll.seNetEarningsFactor;
|
|
2159
|
+
const subjectAmount = calculateNetSelfEmploymentEarnings(rawNetEarnings, factor);
|
|
2160
|
+
const applies = subjectAmount >= params.payroll.seThresholdFloor;
|
|
2161
|
+
const w2Dollars = Math.max(0, income.w2Wages ?? 0);
|
|
2162
|
+
const remainingWageBase = Math.max(0, params.payroll.socialSecurityWageBase - w2Dollars);
|
|
2163
|
+
const ssTaxableDollars = applies ? Math.min(subjectAmount, remainingWageBase) : 0;
|
|
2164
|
+
const ssTaxCents = Math.round(ssTaxableDollars * params.payroll.seSocialSecurityRate * 100);
|
|
2165
|
+
const medTaxCents = applies ? Math.round(subjectAmount * params.payroll.seMedicareRate * 100) : 0;
|
|
2166
|
+
const totalSeTaxCents = ssTaxCents + medTaxCents;
|
|
2167
|
+
const deductibleCents = Math.round(totalSeTaxCents * params.payroll.seDeductibleRate);
|
|
2168
|
+
return {
|
|
2169
|
+
totalSeTaxCents,
|
|
2170
|
+
deductiblePortionCents: deductibleCents,
|
|
2171
|
+
deductiblePortionDollars: require_clamp.fromMinorUnits(deductibleCents, params.currency),
|
|
2172
|
+
breakdown: {
|
|
2173
|
+
netEarnings: require_clamp.usd(require_clamp.fromMinorUnits(require_clamp.toMinorUnits(rawNetEarnings, params.currency), params.currency)),
|
|
2174
|
+
netEarningsMultiplier: factor,
|
|
2175
|
+
subjectEarnings: require_clamp.usd(require_clamp.fromMinorUnits(require_clamp.toMinorUnits(applies ? subjectAmount : 0, params.currency), params.currency)),
|
|
2176
|
+
socialSecurityTaxable: require_clamp.usd(require_clamp.fromMinorUnits(require_clamp.toMinorUnits(ssTaxableDollars, params.currency), params.currency)),
|
|
2177
|
+
socialSecurityTax: require_clamp.usd(require_clamp.fromMinorUnits(ssTaxCents, params.currency, "payroll.se.socialSecurity")),
|
|
2178
|
+
medicareTax: require_clamp.usd(require_clamp.fromMinorUnits(medTaxCents, params.currency, "payroll.se.medicare")),
|
|
2179
|
+
totalSelfEmploymentTax: require_clamp.usd(require_clamp.fromMinorUnits(totalSeTaxCents, params.currency)),
|
|
2180
|
+
deductiblePortion: require_clamp.usd(require_clamp.fromMinorUnits(deductibleCents, params.currency, "payroll.se.deductiblePortion"))
|
|
2181
|
+
}
|
|
2182
|
+
};
|
|
2183
|
+
}
|
|
2184
|
+
// src/us/stages/credits.ts
|
|
2185
|
+
/**
|
|
2186
|
+
* Coordinates and computes all statutory federal tax credits.
|
|
2187
|
+
*
|
|
2188
|
+
* @statute IRC §§ 21, 24, 25A, 32, 901
|
|
2189
|
+
*/
|
|
2190
|
+
function calculateUsCredits(input, agiCents, taxAvailableCents, params) {
|
|
2191
|
+
const agiDollars = require_clamp.fromMinorUnits(agiCents, params.currency);
|
|
2192
|
+
const magiDollars = input.magi ?? agiDollars;
|
|
2193
|
+
const earnedDollars = Math.max(0, input.income.w2Wages ?? 0) + calculateNetSelfEmploymentEarnings(input.income.selfEmploymentNetEarnings, params.payroll.seNetEarningsFactor);
|
|
2194
|
+
const invDollars = (input.credits?.eitcInvestmentIncome ?? 0) + Math.max(0, input.income.ordinaryInterest ?? 0) + Math.max(0, input.income.ordinaryDividends ?? 0) + Math.max(0, input.income.longTermCapitalGains ?? 0);
|
|
2195
|
+
const child = calculateUsChildCredits(input.credits, magiDollars, earnedDollars, taxAvailableCents, input.filingStatus, params);
|
|
2196
|
+
const eitc = calculateUsEitc(input.credits, earnedDollars, invDollars, agiDollars, input.filingStatus, params);
|
|
2197
|
+
const other = calculateUsOtherCredits(input.credits, earnedDollars, agiDollars, magiDollars, input.filingStatus, params);
|
|
2198
|
+
const totalNonRefClaimed = child.nonRefundableUsedCents + other.careNonRefundableCents + other.aotcNonRefundableCents + other.llcNonRefundableCents + other.foreignTaxCreditCents + other.customNonRefundableCents;
|
|
2199
|
+
const allowedNonRefCents = Math.min(totalNonRefClaimed, taxAvailableCents);
|
|
2200
|
+
const totalRefCents = child.actcRefundableCents + eitc.creditCents + other.aotcRefundableCents + other.customRefundableCents;
|
|
2201
|
+
return {
|
|
2202
|
+
allowedNonRefundableCents: allowedNonRefCents,
|
|
2203
|
+
totalRefundableCents: totalRefCents,
|
|
2204
|
+
breakdown: {
|
|
2205
|
+
childCredits: child.breakdown,
|
|
2206
|
+
eitc: eitc.breakdown,
|
|
2207
|
+
childAndDependentCare: require_clamp.usd(require_clamp.fromMinorUnits(other.careNonRefundableCents, params.currency)),
|
|
2208
|
+
education: other.educationBreakdown,
|
|
2209
|
+
foreignTaxCredit: require_clamp.usd(require_clamp.fromMinorUnits(other.foreignTaxCreditCents, params.currency)),
|
|
2210
|
+
customNonRefundable: require_clamp.usd(require_clamp.fromMinorUnits(other.customNonRefundableCents, params.currency)),
|
|
2211
|
+
customRefundable: require_clamp.usd(require_clamp.fromMinorUnits(other.customRefundableCents, params.currency)),
|
|
2212
|
+
totalNonRefundableClaimed: require_clamp.usd(require_clamp.fromMinorUnits(totalNonRefClaimed, params.currency)),
|
|
2213
|
+
totalNonRefundableAllowed: require_clamp.usd(require_clamp.fromMinorUnits(allowedNonRefCents, params.currency)),
|
|
2214
|
+
totalRefundable: require_clamp.usd(require_clamp.fromMinorUnits(totalRefCents, params.currency))
|
|
2215
|
+
}
|
|
2216
|
+
};
|
|
2217
|
+
}
|
|
2218
|
+
// src/us/stages/itemized-deduction.ts
|
|
2219
|
+
function resolveMedical(medDollars, agiCents, floorRate) {
|
|
2220
|
+
const reqCents = require_clamp.toMinorUnits(medDollars ?? 0, "USD", "medicalExpenses");
|
|
2221
|
+
const floorCents = require_clamp.applyPercentage(agiCents, floorRate);
|
|
2222
|
+
const allowedCents = Math.max(0, reqCents - floorCents);
|
|
2223
|
+
return {
|
|
2224
|
+
cents: allowedCents,
|
|
2225
|
+
clamped: {
|
|
2226
|
+
requested: require_clamp.fromMinorUnits(reqCents, "USD"),
|
|
2227
|
+
allowed: require_clamp.fromMinorUnits(allowedCents, "USD"),
|
|
2228
|
+
cap: require_clamp.fromMinorUnits(floorCents, "USD"),
|
|
2229
|
+
wasClamped: reqCents > 0 && allowedCents < reqCents
|
|
2230
|
+
}
|
|
2231
|
+
};
|
|
2232
|
+
}
|
|
2233
|
+
function resolveCharity(charityDollars, agiCents, ceilRate) {
|
|
2234
|
+
const reqCents = require_clamp.toMinorUnits(charityDollars ?? 0, "USD", "charitableContributions");
|
|
2235
|
+
const ceilCents = require_clamp.applyPercentage(agiCents, ceilRate);
|
|
2236
|
+
const clamped = require_clamp.clampCap(reqCents, ceilCents, "charitableContributions");
|
|
2237
|
+
return {
|
|
2238
|
+
cents: clamped.allowed,
|
|
2239
|
+
clamped: {
|
|
2240
|
+
requested: require_clamp.fromMinorUnits(clamped.requested, "USD"),
|
|
2241
|
+
allowed: require_clamp.fromMinorUnits(clamped.allowed, "USD"),
|
|
2242
|
+
cap: require_clamp.fromMinorUnits(clamped.cap, "USD"),
|
|
2243
|
+
wasClamped: clamped.wasClamped
|
|
2244
|
+
}
|
|
2245
|
+
};
|
|
2246
|
+
}
|
|
2247
|
+
/**
|
|
2248
|
+
* Computes Schedule A Itemized Deductions subject to floors and statutory caps.
|
|
2249
|
+
*
|
|
2250
|
+
* @statute IRC §§ 164, 170, 213
|
|
2251
|
+
*/
|
|
2252
|
+
function calculateUsItemizedDeductions(itemized, agiCents, filingStatus, params) {
|
|
2253
|
+
const med = resolveMedical(itemized.medicalExpenses, agiCents, params.itemized.medicalFloorRate);
|
|
2254
|
+
const saltCapDollars = filingStatus === "married_filing_separately" ? params.itemized.saltCapMfs : params.itemized.saltCap;
|
|
2255
|
+
const saltReqCents = require_clamp.toMinorUnits(itemized.stateAndLocalTaxes ?? 0, "USD", "stateAndLocalTaxes");
|
|
2256
|
+
const saltCapCents = require_clamp.toMinorUnits(saltCapDollars, "USD");
|
|
2257
|
+
const saltClamped = require_clamp.clampCap(saltReqCents, saltCapCents, "stateAndLocalTaxes");
|
|
2258
|
+
const mortCents = require_clamp.toMinorUnits(itemized.mortgageInterest ?? 0, "USD", "mortgageInterest");
|
|
2259
|
+
const charity = resolveCharity(itemized.charitableContributions, agiCents, params.itemized.charityCeilingRate);
|
|
2260
|
+
const totalCents = med.cents + saltClamped.allowed + mortCents + charity.cents;
|
|
2261
|
+
return {
|
|
2262
|
+
totalCents,
|
|
2263
|
+
breakdown: {
|
|
2264
|
+
medical: med.clamped,
|
|
2265
|
+
salt: {
|
|
2266
|
+
requested: require_clamp.fromMinorUnits(saltClamped.requested, "USD"),
|
|
2267
|
+
allowed: require_clamp.fromMinorUnits(saltClamped.allowed, "USD"),
|
|
2268
|
+
cap: require_clamp.fromMinorUnits(saltClamped.cap, "USD"),
|
|
2269
|
+
wasClamped: saltClamped.wasClamped
|
|
2270
|
+
},
|
|
2271
|
+
mortgageInterest: require_clamp.usd(require_clamp.fromMinorUnits(mortCents, "USD")),
|
|
2272
|
+
charity: charity.clamped,
|
|
2273
|
+
total: require_clamp.usd(require_clamp.fromMinorUnits(totalCents, "USD"))
|
|
2274
|
+
}
|
|
2275
|
+
};
|
|
2276
|
+
}
|
|
2277
|
+
// src/us/stages/standard-deduction.ts
|
|
2278
|
+
function countAdditionalConditions(input, isUnmarried) {
|
|
2279
|
+
let count = 0;
|
|
2280
|
+
if (input.taxpayerAge65OrOlder) count++;
|
|
2281
|
+
if (input.taxpayerBlind) count++;
|
|
2282
|
+
if (!isUnmarried) {
|
|
2283
|
+
if (input.spouseAge65OrOlder) count++;
|
|
2284
|
+
if (input.spouseBlind) count++;
|
|
2285
|
+
}
|
|
2286
|
+
return count;
|
|
2287
|
+
}
|
|
2288
|
+
/**
|
|
2289
|
+
* Computes base and additional standard deduction for age and blindness in minor units.
|
|
2290
|
+
*
|
|
2291
|
+
* @statute IRC § 63(c), § 63(f)
|
|
2292
|
+
*/
|
|
2293
|
+
function calculateUsStandardDeduction(input, filingStatus, params) {
|
|
2294
|
+
const baseDollars = params.standardDeduction[filingStatus];
|
|
2295
|
+
const baseCents = require_clamp.toMinorUnits(baseDollars, "USD");
|
|
2296
|
+
const isUnmarried = filingStatus === "single" || filingStatus === "head_of_household";
|
|
2297
|
+
const perCondDollars = isUnmarried ? params.additionalStandardDeduction.unmarried : params.additionalStandardDeduction.married;
|
|
2298
|
+
const perCondCents = require_clamp.toMinorUnits(perCondDollars, "USD");
|
|
2299
|
+
const condCount = countAdditionalConditions(input, isUnmarried);
|
|
2300
|
+
const addTotalCents = condCount * perCondCents;
|
|
2301
|
+
const totalCents = baseCents + addTotalCents;
|
|
2302
|
+
return {
|
|
2303
|
+
totalCents,
|
|
2304
|
+
breakdown: {
|
|
2305
|
+
base: require_clamp.usd(require_clamp.fromMinorUnits(baseCents, "USD")),
|
|
2306
|
+
additionalConditionsCount: condCount,
|
|
2307
|
+
additionalPerCondition: require_clamp.usd(require_clamp.fromMinorUnits(perCondCents, "USD")),
|
|
2308
|
+
additionalTotal: require_clamp.usd(require_clamp.fromMinorUnits(addTotalCents, "USD")),
|
|
2309
|
+
total: require_clamp.usd(require_clamp.fromMinorUnits(totalCents, "USD"))
|
|
2310
|
+
}
|
|
2311
|
+
};
|
|
2312
|
+
}
|
|
2313
|
+
// src/us/stages/deductions.ts
|
|
2314
|
+
function resolveElectedMethod(election, itemizedCents, standardCents, hasItemized) {
|
|
2315
|
+
if (election === "itemized") return "itemized";
|
|
2316
|
+
if (election === "standard") return "standard";
|
|
2317
|
+
return hasItemized && itemizedCents > standardCents ? "itemized" : "standard";
|
|
2318
|
+
}
|
|
2319
|
+
/**
|
|
2320
|
+
* Evaluates Standard vs. Schedule A Itemized Deduction election and slices taxable income.
|
|
2321
|
+
*
|
|
2322
|
+
* @statute IRC § 63, § 1(h)
|
|
2323
|
+
*/
|
|
2324
|
+
function calculateUsDeductions(input, agiCents, preferentialGrossCents, filingStatus, params) {
|
|
2325
|
+
const std = calculateUsStandardDeduction(input, filingStatus, params);
|
|
2326
|
+
const hasItemized = input.itemizedDeductions !== void 0;
|
|
2327
|
+
const itm = hasItemized ? calculateUsItemizedDeductions(input.itemizedDeductions, agiCents, filingStatus, params) : void 0;
|
|
2328
|
+
const elected = resolveElectedMethod(input.deductionElection, itm?.totalCents ?? 0, std.totalCents, hasItemized);
|
|
2329
|
+
const allowableCents = elected === "itemized" && itm ? itm.totalCents : std.totalCents;
|
|
2330
|
+
const taxableCents = Math.max(0, agiCents - allowableCents);
|
|
2331
|
+
const ordinaryTaxableCents = Math.max(0, taxableCents - preferentialGrossCents);
|
|
2332
|
+
const preferentialTaxableCents = taxableCents - ordinaryTaxableCents;
|
|
2333
|
+
return {
|
|
2334
|
+
electedDeduction: elected,
|
|
2335
|
+
allowableDeductionCents: allowableCents,
|
|
2336
|
+
allowableDeduction: require_clamp.usd(require_clamp.fromMinorUnits(allowableCents, "USD")),
|
|
2337
|
+
taxableIncomeCents: taxableCents,
|
|
2338
|
+
taxableIncome: require_clamp.usd(require_clamp.fromMinorUnits(taxableCents, "USD")),
|
|
2339
|
+
ordinaryTaxableCents,
|
|
2340
|
+
ordinaryTaxableIncome: require_clamp.usd(require_clamp.fromMinorUnits(ordinaryTaxableCents, "USD")),
|
|
2341
|
+
preferentialTaxableCents,
|
|
2342
|
+
preferentialTaxableIncome: require_clamp.usd(require_clamp.fromMinorUnits(preferentialTaxableCents, "USD")),
|
|
2343
|
+
standardBreakdown: std.breakdown,
|
|
2344
|
+
itemizedBreakdown: itm?.breakdown
|
|
2345
|
+
};
|
|
2346
|
+
}
|
|
2347
|
+
// src/us/stages/fica.ts
|
|
2348
|
+
/**
|
|
2349
|
+
* Computes W-2 FICA payroll taxes and Additional Medicare Tax on earned income.
|
|
2350
|
+
*
|
|
2351
|
+
* @statute IRC § 3101, § 1401(b)(2)
|
|
2352
|
+
*/
|
|
2353
|
+
function calculateUsFica(income, filingStatus, includeFica, params) {
|
|
2354
|
+
if (!includeFica) return {
|
|
2355
|
+
totalFicaCents: 0,
|
|
2356
|
+
breakdown: {
|
|
2357
|
+
enabled: false,
|
|
2358
|
+
socialSecurityWages: require_clamp.usd(0),
|
|
2359
|
+
socialSecurityTax: require_clamp.usd(0),
|
|
2360
|
+
medicareWages: require_clamp.usd(0),
|
|
2361
|
+
medicareTax: require_clamp.usd(0),
|
|
2362
|
+
additionalMedicareSubject: require_clamp.usd(0),
|
|
2363
|
+
additionalMedicareTax: require_clamp.usd(0),
|
|
2364
|
+
totalFicaTax: require_clamp.usd(0)
|
|
2365
|
+
}
|
|
2366
|
+
};
|
|
2367
|
+
const w2 = Math.max(0, income.w2Wages ?? 0);
|
|
2368
|
+
const ssWages = Math.min(w2, params.payroll.socialSecurityWageBase);
|
|
2369
|
+
const ssTaxCents = Math.round(ssWages * params.payroll.ficaSocialSecurityRate * 100);
|
|
2370
|
+
const medTaxCents = Math.round(w2 * params.payroll.ficaMedicareRate * 100);
|
|
2371
|
+
const combinedEarned = w2 + calculateNetSelfEmploymentEarnings(income.selfEmploymentNetEarnings, params.payroll.seNetEarningsFactor);
|
|
2372
|
+
const threshold = params.payroll.additionalMedicareThresholds[filingStatus];
|
|
2373
|
+
const addMedSubject = Math.max(0, combinedEarned - threshold);
|
|
2374
|
+
const addMedTaxCents = Math.round(addMedSubject * params.payroll.additionalMedicareRate * 100);
|
|
2375
|
+
const totalCents = ssTaxCents + medTaxCents + addMedTaxCents;
|
|
2376
|
+
return {
|
|
2377
|
+
totalFicaCents: totalCents,
|
|
2378
|
+
breakdown: {
|
|
2379
|
+
enabled: true,
|
|
2380
|
+
socialSecurityWages: require_clamp.usd(require_clamp.fromMinorUnits(require_clamp.toMinorUnits(ssWages, params.currency), params.currency)),
|
|
2381
|
+
socialSecurityTax: require_clamp.usd(require_clamp.fromMinorUnits(ssTaxCents, params.currency, "payroll.fica.socialSecurity")),
|
|
2382
|
+
medicareWages: require_clamp.usd(require_clamp.fromMinorUnits(require_clamp.toMinorUnits(w2, params.currency), params.currency)),
|
|
2383
|
+
medicareTax: require_clamp.usd(require_clamp.fromMinorUnits(medTaxCents, params.currency, "payroll.fica.medicare")),
|
|
2384
|
+
additionalMedicareSubject: require_clamp.usd(require_clamp.fromMinorUnits(require_clamp.toMinorUnits(addMedSubject, params.currency), params.currency)),
|
|
2385
|
+
additionalMedicareTax: require_clamp.usd(require_clamp.fromMinorUnits(addMedTaxCents, params.currency, "payroll.fica.additionalMedicare")),
|
|
2386
|
+
totalFicaTax: require_clamp.usd(require_clamp.fromMinorUnits(totalCents, params.currency))
|
|
2387
|
+
}
|
|
2388
|
+
};
|
|
2389
|
+
}
|
|
2390
|
+
// src/us/stages/niit.ts
|
|
2391
|
+
function resolveNiiCents(income, override) {
|
|
2392
|
+
if (override !== void 0) return require_clamp.toMinorUnits(override, "USD", "netInvestmentIncome");
|
|
2393
|
+
return require_clamp.toMinorUnits(income.ordinaryInterest ?? 0, "USD", "ordinaryInterest") + require_clamp.toMinorUnits(income.ordinaryDividends ?? 0, "USD", "ordinaryDividends") + require_clamp.toMinorUnits(income.qualifiedDividends ?? 0, "USD", "qualifiedDividends") + require_clamp.toMinorUnits(income.shortTermCapitalGains ?? 0, "USD", "shortTermCapitalGains") + require_clamp.toMinorUnits(income.longTermCapitalGains ?? 0, "USD", "longTermCapitalGains") + require_clamp.toMinorUnits(income.rentalAndOtherOrdinaryIncome ?? 0, "USD", "rentalAndOtherOrdinaryIncome");
|
|
2394
|
+
}
|
|
2395
|
+
/**
|
|
2396
|
+
* Computes 3.8% Net Investment Income Tax (NIIT) on the lesser of NII or excess MAGI.
|
|
2397
|
+
*
|
|
2398
|
+
* @statute IRC § 1411
|
|
2399
|
+
*/
|
|
2400
|
+
function calculateUsNiit(input, agiCents, filingStatus, params) {
|
|
2401
|
+
const niiCents = resolveNiiCents(input.income, input.netInvestmentIncome);
|
|
2402
|
+
const magiCents = input.magi !== void 0 ? require_clamp.toMinorUnits(input.magi, "USD", "magi") : agiCents;
|
|
2403
|
+
const thresholdDollars = params.niit.thresholds[filingStatus];
|
|
2404
|
+
const thresholdCents = require_clamp.toMinorUnits(thresholdDollars, "USD");
|
|
2405
|
+
const excessMagiCents = Math.max(0, magiCents - thresholdCents);
|
|
2406
|
+
const subjectCents = Math.min(niiCents, excessMagiCents);
|
|
2407
|
+
const taxCents = require_clamp.applyPercentage(subjectCents, params.niit.rate);
|
|
2408
|
+
return {
|
|
2409
|
+
taxCents,
|
|
2410
|
+
tax: require_clamp.usd(require_clamp.fromMinorUnits(taxCents, "USD")),
|
|
2411
|
+
breakdown: {
|
|
2412
|
+
netInvestmentIncome: require_clamp.usd(require_clamp.fromMinorUnits(niiCents, "USD")),
|
|
2413
|
+
magi: require_clamp.usd(require_clamp.fromMinorUnits(magiCents, "USD")),
|
|
2414
|
+
threshold: require_clamp.usd(require_clamp.fromMinorUnits(thresholdCents, "USD")),
|
|
2415
|
+
excessMagi: require_clamp.usd(require_clamp.fromMinorUnits(excessMagiCents, "USD")),
|
|
2416
|
+
subjectAmount: require_clamp.usd(require_clamp.fromMinorUnits(subjectCents, "USD")),
|
|
2417
|
+
tax: require_clamp.usd(require_clamp.fromMinorUnits(taxCents, "USD"))
|
|
2418
|
+
}
|
|
2419
|
+
};
|
|
2420
|
+
}
|
|
2421
|
+
// src/us/stages/preferential.ts
|
|
2422
|
+
function computePreferentialTier(tier, bracket, tierLower, ordinaryTaxableCents, taxableIncomeCents) {
|
|
2423
|
+
const tierUpper = bracket.upTo ?? Number.POSITIVE_INFINITY;
|
|
2424
|
+
const taxableInTier = Math.max(0, Math.min(taxableIncomeCents, tierUpper) - Math.max(ordinaryTaxableCents, tierLower));
|
|
2425
|
+
const taxCents = taxableInTier > 0 ? require_clamp.applyPercentage(taxableInTier, bracket.rate) : 0;
|
|
2426
|
+
return {
|
|
2427
|
+
slice: {
|
|
2428
|
+
tier,
|
|
2429
|
+
rate: bracket.rate,
|
|
2430
|
+
taxableAmount: require_clamp.usd(require_clamp.fromMinorUnits(taxableInTier, "USD")),
|
|
2431
|
+
tax: require_clamp.usd(require_clamp.fromMinorUnits(taxCents, "USD"))
|
|
2432
|
+
},
|
|
2433
|
+
taxCents,
|
|
2434
|
+
tierUpper
|
|
2435
|
+
};
|
|
2436
|
+
}
|
|
2437
|
+
/**
|
|
2438
|
+
* Evaluates preferential stacking for Long-Term Capital Gains and Qualified Dividends.
|
|
2439
|
+
*
|
|
2440
|
+
* @statute IRC § 1(h)
|
|
2441
|
+
*/
|
|
2442
|
+
function calculateUsPreferentialStacking(ordinaryTaxableCents, taxableIncomeCents, brackets) {
|
|
2443
|
+
let totalTaxCents = 0;
|
|
2444
|
+
let tierLower = 0;
|
|
2445
|
+
const slices = [];
|
|
2446
|
+
for (let i = 0; i < brackets.length; i++) {
|
|
2447
|
+
const bracket = brackets[i];
|
|
2448
|
+
if (!bracket) continue;
|
|
2449
|
+
const result = computePreferentialTier(i, bracket, tierLower, ordinaryTaxableCents, taxableIncomeCents);
|
|
2450
|
+
slices.push(result.slice);
|
|
2451
|
+
totalTaxCents += result.taxCents;
|
|
2452
|
+
if (bracket.upTo === null) break;
|
|
2453
|
+
tierLower = result.tierUpper;
|
|
2454
|
+
}
|
|
2455
|
+
return {
|
|
2456
|
+
preferentialTaxCents: totalTaxCents,
|
|
2457
|
+
preferentialTax: require_clamp.usd(require_clamp.fromMinorUnits(totalTaxCents, "USD")),
|
|
2458
|
+
slices
|
|
2459
|
+
};
|
|
2460
|
+
}
|
|
2461
|
+
// src/us/state/breakdown.ts
|
|
2462
|
+
/**
|
|
2463
|
+
* Converts integer cents to non-negative USD Money tagged with its diagnostic field.
|
|
2464
|
+
*
|
|
2465
|
+
* Units: Input is integer minor units; output is major-unit Money.
|
|
2466
|
+
* Throws: TaxValidationError if the amount is negative or not a safe integer.
|
|
2467
|
+
*/
|
|
2468
|
+
function money(cents, currency, field) {
|
|
2469
|
+
return require_clamp.usd(require_clamp.fromMinorUnits(cents, currency, field), field);
|
|
2470
|
+
}
|
|
2471
|
+
/**
|
|
2472
|
+
* Assembles the audit breakdown for one state individual income tax calculation.
|
|
2473
|
+
*
|
|
2474
|
+
* Purpose: Packages every deduction, exemption, bracket slice, surtax, credit, and withholding
|
|
2475
|
+
* figure so callers can audit the state liability.
|
|
2476
|
+
* Units: All monetary inputs are integer cents; outputs are major-unit Money.
|
|
2477
|
+
* Throws: TaxValidationError if any component amount is negative or not a safe integer
|
|
2478
|
+
* (net payable may be negative).
|
|
2479
|
+
*
|
|
2480
|
+
* @param p State calculation amounts and statutory parameters.
|
|
2481
|
+
* @returns Complete state tax audit breakdown.
|
|
2482
|
+
* @statute State individual income tax statutes; see per-state parameter tables.
|
|
2483
|
+
*/
|
|
2484
|
+
function buildUsStateBreakdown(p) {
|
|
2485
|
+
const { currency, deductions: d, credits: c } = p;
|
|
2486
|
+
return {
|
|
2487
|
+
code: p.params.code,
|
|
2488
|
+
name: p.params.name,
|
|
2489
|
+
type: p.params.type,
|
|
2490
|
+
agi: money(p.agiCents, currency, "state.agi"),
|
|
2491
|
+
standardDeduction: money(d.standardDeductionCents, currency, "state.standardDeduction"),
|
|
2492
|
+
personalExemption: money(d.personalExemptionCents, currency, "state.personalExemption"),
|
|
2493
|
+
dependentExemption: money(d.dependentExemptionCents, currency, "state.dependentExemption"),
|
|
2494
|
+
taxableIncome: money(d.taxableIncomeCents, currency, "state.taxableIncome"),
|
|
2495
|
+
slices: p.evaluation.slices,
|
|
2496
|
+
bracketTax: money(p.evaluation.totalTax, currency, "state.bracketTax"),
|
|
2497
|
+
surtax: money(p.surtaxCents, currency, "state.surtax"),
|
|
2498
|
+
taxBeforeCredits: money(p.taxBeforeCreditsCents, currency, "state.taxBeforeCredits"),
|
|
2499
|
+
credits: {
|
|
2500
|
+
personal: money(d.personalCreditCents, currency, "state.credits.personal"),
|
|
2501
|
+
dependent: money(d.dependentCreditCents, currency, "state.credits.dependent"),
|
|
2502
|
+
claimedNonRefundable: money(c.claimedNonRefundableCents, currency, "state.credits.claimedNonRefundable"),
|
|
2503
|
+
allowedNonRefundable: money(c.allowedNonRefundableCents, currency, "state.credits.nonRefundable"),
|
|
2504
|
+
refundable: money(c.refundableCents, currency, "state.credits.refundable")
|
|
2505
|
+
},
|
|
2506
|
+
totalTax: money(c.totalTaxCents, currency, "state.totalTax"),
|
|
2507
|
+
withholding: money(c.withholdingCents, currency, "state.withholding"),
|
|
2508
|
+
netTaxPayable: require_clamp.usd(require_clamp.fromMinorUnits(c.netTaxCents, currency, "state.netTaxPayable", { allowNegative: true }), "state.netTaxPayable", { allowNegative: true }),
|
|
2509
|
+
effectiveRate: p.effectiveRate,
|
|
2510
|
+
marginalRate: p.marginalRate
|
|
2511
|
+
};
|
|
2512
|
+
}
|
|
2513
|
+
// src/us/state/credits.ts
|
|
2514
|
+
/**
|
|
2515
|
+
* Applies state personal, dependent, and caller-supplied credits plus state withholding.
|
|
2516
|
+
*
|
|
2517
|
+
* Math: non-refundable credits are capped at tax before credits; refundable credits and
|
|
2518
|
+
* withholding reduce net tax payable (possibly below zero).
|
|
2519
|
+
* Units: All amounts are integer cents; caller credit and withholding inputs are major dollars.
|
|
2520
|
+
* Throws: TaxValidationError if a credit or withholding amount is negative or not representable
|
|
2521
|
+
* as safe integer cents.
|
|
2522
|
+
*
|
|
2523
|
+
* @param taxBeforeCreditsCents State bracket tax plus surtax in integer cents.
|
|
2524
|
+
* @param personalCreditCents State personal non-refundable credit in cents.
|
|
2525
|
+
* @param dependentCreditCents State dependent non-refundable credit in cents.
|
|
2526
|
+
* @param credits Caller-supplied state non-refundable and refundable credits.
|
|
2527
|
+
* @param withholding Caller-supplied state income tax withholding in major dollars.
|
|
2528
|
+
* @param currency Supported statutory currency threaded for minor-unit conversion.
|
|
2529
|
+
* @returns Allowed non-refundable credits, total state tax, refundable credits,
|
|
2530
|
+
* withholding, and net state tax payable in integer cents.
|
|
2531
|
+
* @statute State individual income tax statutes; see per-state parameter tables.
|
|
2532
|
+
*/
|
|
2533
|
+
function calculateUsStateCredits(taxBeforeCreditsCents, personalCreditCents, dependentCreditCents, credits, withholding, currency) {
|
|
2534
|
+
const claimedNonRefundableCents = personalCreditCents + dependentCreditCents + require_clamp.toMinorUnits(credits?.nonRefundable ?? 0, currency, "state.credits.nonRefundable");
|
|
2535
|
+
const allowedNonRefundableCents = Math.min(taxBeforeCreditsCents, claimedNonRefundableCents);
|
|
2536
|
+
const totalTaxCents = taxBeforeCreditsCents - allowedNonRefundableCents;
|
|
2537
|
+
const refundableCents = require_clamp.toMinorUnits(credits?.refundable ?? 0, currency, "state.credits.refundable");
|
|
2538
|
+
const withholdingCents = require_clamp.toMinorUnits(withholding ?? 0, currency, "state.withholding");
|
|
2539
|
+
return {
|
|
2540
|
+
claimedNonRefundableCents,
|
|
2541
|
+
allowedNonRefundableCents,
|
|
2542
|
+
totalTaxCents,
|
|
2543
|
+
refundableCents,
|
|
2544
|
+
withholdingCents,
|
|
2545
|
+
netTaxCents: totalTaxCents - refundableCents - withholdingCents
|
|
2546
|
+
};
|
|
2547
|
+
}
|
|
2548
|
+
// src/us/state/phase-out.ts
|
|
2549
|
+
function cents(amounts, status, currency) {
|
|
2550
|
+
return require_clamp.toMinorUnits(amounts[status], currency, "state.phaseOutThreshold");
|
|
2551
|
+
}
|
|
2552
|
+
function linearReduction(amountCents, excessCents, rule, status, currency) {
|
|
2553
|
+
const widthCents = cents(rule.width, status, currency);
|
|
2554
|
+
if (excessCents >= widthCents) return amountCents;
|
|
2555
|
+
return Math.round(amountCents * excessCents / widthCents);
|
|
2556
|
+
}
|
|
2557
|
+
function steppedReduction(amountCents, excessCents, rule, status, currency) {
|
|
2558
|
+
const steps = Math.ceil(excessCents / cents(rule.step, status, currency));
|
|
2559
|
+
return require_clamp.applyPercentage(amountCents, Math.min(1, steps * rule.ratePerStep));
|
|
2560
|
+
}
|
|
2561
|
+
function tieredReduction(amountCents, agiCents, rule, status, currency) {
|
|
2562
|
+
const startCents = cents(rule.start, status, currency);
|
|
2563
|
+
const secondCents = cents(rule.second, status, currency);
|
|
2564
|
+
const lower = require_clamp.applyPercentage(Math.min(agiCents, secondCents) - startCents, rule.rate);
|
|
2565
|
+
const upper = require_clamp.applyPercentage(Math.max(0, agiCents - secondCents), rule.secondRate);
|
|
2566
|
+
return Math.min(lower + upper, require_clamp.applyPercentage(amountCents, rule.maxShare));
|
|
2567
|
+
}
|
|
2568
|
+
/**
|
|
2569
|
+
* Applies a statutory income-based phase-out to a deduction or exemption.
|
|
2570
|
+
*
|
|
2571
|
+
* Math: linear removes amount x (AGI - start) / width; stepped removes ratePerStep of the
|
|
2572
|
+
* amount for each step or fraction above start (capped at 100%); tiered removes
|
|
2573
|
+
* rate x (AGI up to second - start) + secondRate x (AGI - second), capped at maxShare of the
|
|
2574
|
+
* amount. Nothing is removed at or below the start threshold.
|
|
2575
|
+
* Units: AGI and amounts are integer cents; thresholds are major dollars converted to cents.
|
|
2576
|
+
* Throws: TaxValidationError if a threshold cannot be represented as safe integer cents.
|
|
2577
|
+
*
|
|
2578
|
+
* @param amountCents Deduction or exemption before the phase-out, in integer cents.
|
|
2579
|
+
* @param agiCents Federal adjusted gross income in integer cents.
|
|
2580
|
+
* @param status Filing status selecting the thresholds.
|
|
2581
|
+
* @param phaseOut Optional statutory phase-out rule.
|
|
2582
|
+
* @param currency Supported statutory currency threaded for minor-unit conversion.
|
|
2583
|
+
* @returns The amount still allowed after the phase-out, in integer cents.
|
|
2584
|
+
* @statute 36 M.R.S. § 5124-C(2); Minn. Stat. §§ 290.0121 subd. 2, 290.0123 subd. 5.
|
|
2585
|
+
*/
|
|
2586
|
+
function applyUsStatePhaseOut(amountCents, agiCents, status, phaseOut, currency) {
|
|
2587
|
+
if (!phaseOut) return amountCents;
|
|
2588
|
+
const excessCents = agiCents - cents(phaseOut.start, status, currency);
|
|
2589
|
+
if (excessCents <= 0) return amountCents;
|
|
2590
|
+
if (phaseOut.kind === "tiered") return amountCents - tieredReduction(amountCents, agiCents, phaseOut, status, currency);
|
|
2591
|
+
return amountCents - (phaseOut.kind === "linear" ? linearReduction(amountCents, excessCents, phaseOut, status, currency) : steppedReduction(amountCents, excessCents, phaseOut, status, currency));
|
|
2592
|
+
}
|
|
2593
|
+
// src/us/state/deductions.ts
|
|
2594
|
+
/**
|
|
2595
|
+
* Resolves state standard deductions, personal/dependent exemptions, and credits.
|
|
2596
|
+
*
|
|
2597
|
+
* Math: taxable = max(0, AGI - standard deduction - personal exemption - dependent exemptions),
|
|
2598
|
+
* where the standard deduction and dependent exemptions first pass any statutory phase-out.
|
|
2599
|
+
* Units: AGI is integer cents; parameter amounts are major dollars converted to integer cents.
|
|
2600
|
+
* Throws: TaxValidationError if a parameter amount or the dependent product is not a safe
|
|
2601
|
+
* integer number of cents.
|
|
2602
|
+
*
|
|
2603
|
+
* @param agiCents Federal adjusted gross income in integer cents.
|
|
2604
|
+
* @param status Filing status.
|
|
2605
|
+
* @param dependents Validated non-negative dependent count.
|
|
2606
|
+
* @param params State statutory parameter table.
|
|
2607
|
+
* @param currency Supported statutory currency threaded for minor-unit conversion.
|
|
2608
|
+
* @returns Resolved deduction, exemption, credit, and taxable-income amounts.
|
|
2609
|
+
* @statute State individual income tax statutes; see per-state parameter tables.
|
|
2610
|
+
*/
|
|
2611
|
+
function calculateUsStateDeductions(agiCents, status, dependents, params, currency) {
|
|
2612
|
+
const standardDeductionCents = applyUsStatePhaseOut(require_clamp.toMinorUnits(params.standardDeduction[status], currency, "state.standardDeduction"), agiCents, status, params.standardDeductionPhaseOut, currency);
|
|
2613
|
+
const personalExemptionCents = require_clamp.toMinorUnits(params.personalExemption[status], currency, "state.personalExemption");
|
|
2614
|
+
const dependentExemptionCents = applyUsStatePhaseOut(require_clamp.multiplySafeInteger(require_clamp.toMinorUnits(params.dependentExemption, currency, "state.dependentExemption"), dependents, "state.dependentExemption"), agiCents, status, params.dependentExemptionPhaseOut, currency);
|
|
2615
|
+
return {
|
|
2616
|
+
standardDeductionCents,
|
|
2617
|
+
personalExemptionCents,
|
|
2618
|
+
dependentExemptionCents,
|
|
2619
|
+
personalCreditCents: require_clamp.toMinorUnits(params.personalCredit[status], currency, "state.credits.personal"),
|
|
2620
|
+
dependentCreditCents: require_clamp.multiplySafeInteger(require_clamp.toMinorUnits(params.dependentCredit, currency, "state.credits.dependent"), dependents, "state.credits.dependent"),
|
|
2621
|
+
taxableIncomeCents: Math.max(0, agiCents - standardDeductionCents - personalExemptionCents - dependentExemptionCents)
|
|
2622
|
+
};
|
|
2623
|
+
}
|
|
2624
|
+
// src/us/state/surtax.ts
|
|
2625
|
+
/**
|
|
2626
|
+
* Computes a state high-income or millionaire surtax above a taxable-income threshold.
|
|
2627
|
+
*
|
|
2628
|
+
* Math: surtax = rate * max(0, taxable income - threshold); active when taxable income
|
|
2629
|
+
* reaches the threshold. A per-status threshold is looked up by filing status.
|
|
2630
|
+
* Units: Taxable income and result are integer cents; threshold is major dollars.
|
|
2631
|
+
* Throws: TaxValidationError if the threshold or rate cannot be converted or is invalid.
|
|
2632
|
+
*
|
|
2633
|
+
* @param taxableIncomeCents State taxable income in integer cents.
|
|
2634
|
+
* @param surtax Optional statutory surtax threshold and rate.
|
|
2635
|
+
* @param status Filing status, used when the threshold varies by status.
|
|
2636
|
+
* @param currency Supported statutory currency threaded for minor-unit conversion.
|
|
2637
|
+
* @returns Surtax amount in cents, statutory rate, and whether it applies.
|
|
2638
|
+
*/
|
|
2639
|
+
function calculateUsStateSurtax(taxableIncomeCents, surtax, status, currency) {
|
|
2640
|
+
if (!surtax) return {
|
|
2641
|
+
taxCents: 0,
|
|
2642
|
+
rate: 0,
|
|
2643
|
+
active: false
|
|
2644
|
+
};
|
|
2645
|
+
const threshold = typeof surtax.threshold === "number" ? surtax.threshold : surtax.threshold[status];
|
|
2646
|
+
const thresholdCents = require_clamp.toMinorUnits(threshold, currency, "state.surtaxThreshold");
|
|
2647
|
+
const baseCents = Math.max(0, taxableIncomeCents - thresholdCents);
|
|
2648
|
+
return {
|
|
2649
|
+
taxCents: require_clamp.applyPercentage(baseCents, surtax.rate),
|
|
2650
|
+
rate: surtax.rate,
|
|
2651
|
+
active: taxableIncomeCents >= thresholdCents
|
|
2652
|
+
};
|
|
2653
|
+
}
|
|
2654
|
+
// src/us/stages/state.ts
|
|
2655
|
+
const EMPTY_RESULT = {
|
|
2656
|
+
totalTaxCents: 0,
|
|
2657
|
+
netTaxCents: 0,
|
|
2658
|
+
breakdown: void 0
|
|
2659
|
+
};
|
|
2660
|
+
/**
|
|
2661
|
+
* Computes 2026 state individual income tax from federal AGI, state deductions,
|
|
2662
|
+
* personal/dependent exemptions and credits, state surtaxes, and state withholding.
|
|
2663
|
+
*
|
|
2664
|
+
* Math: state taxable income = max(0, AGI - state standard deduction - exemptions);
|
|
2665
|
+
* tax = progressive bracket tax + surtax - non-refundable credits.
|
|
2666
|
+
* Units: AGI and all outputs are integer cents; parameter amounts are major dollars.
|
|
2667
|
+
*
|
|
2668
|
+
* @param input Complete US tax input including optional state code and state credits.
|
|
2669
|
+
* @param agiCents Federal adjusted gross income in integer cents.
|
|
2670
|
+
* @param filingStatus Federal and state filing status.
|
|
2671
|
+
* @param currency Supported statutory currency threaded for minor-unit conversion.
|
|
2672
|
+
* @returns State tax, refundable credits, withholding, net payable, and audit breakdown.
|
|
2673
|
+
* @statute State individual income tax statutes; see per-state parameter tables.
|
|
2674
|
+
*/
|
|
2675
|
+
function calculateUsStateTax(input, agiCents, filingStatus, currency) {
|
|
2676
|
+
if (input.state === void 0) return EMPTY_RESULT;
|
|
2677
|
+
const params = US_2026_STATE_PARAMETERS[input.state];
|
|
2678
|
+
const deductions = calculateUsStateDeductions(agiCents, filingStatus, input.stateDependents ?? 0, params, currency);
|
|
2679
|
+
const evaluation = require_clamp.evaluateBrackets(deductions.taxableIncomeCents, params.brackets[filingStatus], void 0, "state.taxableIncome");
|
|
2680
|
+
const surtax = calculateUsStateSurtax(deductions.taxableIncomeCents, params.surtax, filingStatus, currency);
|
|
2681
|
+
const taxBeforeCreditsCents = evaluation.totalTax + surtax.taxCents;
|
|
2682
|
+
const credits = calculateUsStateCredits(taxBeforeCreditsCents, deductions.personalCreditCents, deductions.dependentCreditCents, input.stateCredits, input.stateWithholding, currency);
|
|
2683
|
+
const effectiveRate = agiCents > 0 ? credits.totalTaxCents / agiCents : 0;
|
|
2684
|
+
const marginalRate = surtax.active ? evaluation.marginalRate + surtax.rate : evaluation.marginalRate;
|
|
2685
|
+
return {
|
|
2686
|
+
totalTaxCents: credits.totalTaxCents,
|
|
2687
|
+
netTaxCents: credits.netTaxCents,
|
|
2688
|
+
breakdown: buildUsStateBreakdown({
|
|
2689
|
+
params,
|
|
2690
|
+
agiCents,
|
|
2691
|
+
deductions,
|
|
2692
|
+
evaluation,
|
|
2693
|
+
surtaxCents: surtax.taxCents,
|
|
2694
|
+
taxBeforeCreditsCents,
|
|
2695
|
+
credits,
|
|
2696
|
+
effectiveRate,
|
|
2697
|
+
marginalRate,
|
|
2698
|
+
currency
|
|
2699
|
+
})
|
|
2700
|
+
};
|
|
2701
|
+
}
|
|
2702
|
+
/** Read-only runtime registry of every supported US state code. */
|
|
2703
|
+
const US_STATE_CODES = [
|
|
2704
|
+
"AL",
|
|
2705
|
+
"AK",
|
|
2706
|
+
"AZ",
|
|
2707
|
+
"AR",
|
|
2708
|
+
"CA",
|
|
2709
|
+
"CO",
|
|
2710
|
+
"CT",
|
|
2711
|
+
"DE",
|
|
2712
|
+
"DC",
|
|
2713
|
+
"FL",
|
|
2714
|
+
"GA",
|
|
2715
|
+
"HI",
|
|
2716
|
+
"ID",
|
|
2717
|
+
"IL",
|
|
2718
|
+
"IN",
|
|
2719
|
+
"IA",
|
|
2720
|
+
"KS",
|
|
2721
|
+
"KY",
|
|
2722
|
+
"LA",
|
|
2723
|
+
"ME",
|
|
2724
|
+
"MD",
|
|
2725
|
+
"MA",
|
|
2726
|
+
"MI",
|
|
2727
|
+
"MN",
|
|
2728
|
+
"MS",
|
|
2729
|
+
"MO",
|
|
2730
|
+
"MT",
|
|
2731
|
+
"NE",
|
|
2732
|
+
"NV",
|
|
2733
|
+
"NH",
|
|
2734
|
+
"NJ",
|
|
2735
|
+
"NM",
|
|
2736
|
+
"NY",
|
|
2737
|
+
"NC",
|
|
2738
|
+
"ND",
|
|
2739
|
+
"OH",
|
|
2740
|
+
"OK",
|
|
2741
|
+
"OR",
|
|
2742
|
+
"PA",
|
|
2743
|
+
"RI",
|
|
2744
|
+
"SC",
|
|
2745
|
+
"SD",
|
|
2746
|
+
"TN",
|
|
2747
|
+
"TX",
|
|
2748
|
+
"UT",
|
|
2749
|
+
"VT",
|
|
2750
|
+
"VA",
|
|
2751
|
+
"WA",
|
|
2752
|
+
"WV",
|
|
2753
|
+
"WI",
|
|
2754
|
+
"WY"
|
|
2755
|
+
];
|
|
2756
|
+
// src/us/validate.ts
|
|
2757
|
+
const VALID_STATUSES = [
|
|
2758
|
+
"single",
|
|
2759
|
+
"married_filing_jointly",
|
|
2760
|
+
"married_filing_separately",
|
|
2761
|
+
"head_of_household"
|
|
2762
|
+
];
|
|
2763
|
+
function checkFiniteNumber(field, val) {
|
|
2764
|
+
if (val === void 0) return;
|
|
2765
|
+
if (typeof val !== "number" || !Number.isFinite(val)) throw new require_clamp.TaxValidationError(field, val, "Must be a finite number");
|
|
2766
|
+
}
|
|
2767
|
+
function checkNonNegative(field, val) {
|
|
2768
|
+
if (val === void 0) return;
|
|
2769
|
+
if (typeof val !== "number" || !Number.isFinite(val) || val < 0) throw new require_clamp.TaxValidationError(field, val, "Must be a non-negative finite number");
|
|
2770
|
+
}
|
|
2771
|
+
function checkNonNegativeInt(field, val) {
|
|
2772
|
+
if (val === void 0) return;
|
|
2773
|
+
if (typeof val !== "number" || !Number.isSafeInteger(val) || val < 0) throw new require_clamp.TaxValidationError(field, val, "Must be a non-negative integer");
|
|
2774
|
+
}
|
|
2775
|
+
function validateNoOrphanStateInputs(input) {
|
|
2776
|
+
const orphan = [
|
|
2777
|
+
["stateDependents", input.stateDependents],
|
|
2778
|
+
["stateWithholding", input.stateWithholding],
|
|
2779
|
+
["stateCredits", input.stateCredits]
|
|
2780
|
+
].find(([, value]) => value !== void 0);
|
|
2781
|
+
if (orphan) throw new require_clamp.TaxValidationError(String(orphan[0]), orphan[1], "Requires a `state` code");
|
|
2782
|
+
}
|
|
2783
|
+
function validateStateCreditsInput(credits) {
|
|
2784
|
+
if (!credits) return;
|
|
2785
|
+
checkNonNegative("stateCredits.nonRefundable", credits.nonRefundable);
|
|
2786
|
+
checkNonNegative("stateCredits.refundable", credits.refundable);
|
|
2787
|
+
}
|
|
2788
|
+
function validateCreditsInput(credits) {
|
|
2789
|
+
if (!credits) return;
|
|
2790
|
+
checkNonNegativeInt("qualifyingChildrenForChildTaxCredit", credits.qualifyingChildrenForChildTaxCredit);
|
|
2791
|
+
checkNonNegativeInt("otherDependents", credits.otherDependents);
|
|
2792
|
+
checkNonNegativeInt("eitcQualifyingChildren", credits.eitcQualifyingChildren);
|
|
2793
|
+
checkNonNegative("eitcInvestmentIncome", credits.eitcInvestmentIncome);
|
|
2794
|
+
checkNonNegativeInt("qualifyingIndividualsForCare", credits.qualifyingIndividualsForCare);
|
|
2795
|
+
checkNonNegative("childAndDependentCareExpenses", credits.childAndDependentCareExpenses);
|
|
2796
|
+
checkNonNegative("foreignTaxCredit", credits.foreignTaxCredit);
|
|
2797
|
+
checkNonNegative("customNonRefundableCredits", credits.customNonRefundableCredits);
|
|
2798
|
+
checkNonNegative("customRefundableCredits", credits.customRefundableCredits);
|
|
2799
|
+
for (const student of credits.educationStudents ?? []) {
|
|
2800
|
+
if (!student) throw new require_clamp.TaxValidationError("educationStudents", student, "Invalid student entry");
|
|
2801
|
+
checkNonNegative("educationStudent.qualifiedExpenses", student.qualifiedExpenses);
|
|
2802
|
+
}
|
|
2803
|
+
}
|
|
2804
|
+
/**
|
|
2805
|
+
* Validates statutory US tax input parameters against bounds and types.
|
|
2806
|
+
*/
|
|
2807
|
+
function validateUsInput(input) {
|
|
2808
|
+
if (input.taxYear !== void 0 && input.taxYear !== 2026) throw new require_clamp.TaxValidationError("taxYear", input.taxYear, "Unsupported tax year; currently only 2026 is supported");
|
|
2809
|
+
if (!VALID_STATUSES.includes(input.filingStatus)) throw new require_clamp.TaxValidationError("filingStatus", input.filingStatus, "Invalid filing status");
|
|
2810
|
+
checkNonNegative("withholding", input.withholding);
|
|
2811
|
+
checkNonNegative("amtPreferences", input.amtPreferences);
|
|
2812
|
+
checkNonNegative("income.w2Wages", input.income.w2Wages);
|
|
2813
|
+
checkFiniteNumber("income.selfEmploymentNetEarnings", input.income.selfEmploymentNetEarnings);
|
|
2814
|
+
if (input.state !== void 0 && !US_STATE_CODES.includes(input.state)) throw new require_clamp.TaxValidationError("state", input.state, "Unsupported US state code");
|
|
2815
|
+
if (input.state === void 0) validateNoOrphanStateInputs(input);
|
|
2816
|
+
checkNonNegativeInt("stateDependents", input.stateDependents);
|
|
2817
|
+
checkNonNegative("stateWithholding", input.stateWithholding);
|
|
2818
|
+
validateStateCreditsInput(input.stateCredits);
|
|
2819
|
+
validateCreditsInput(input.credits);
|
|
2820
|
+
}
|
|
2821
|
+
// src/us/calculate.ts
|
|
2822
|
+
/**
|
|
2823
|
+
* Executes the 2026 US federal, payroll, and optional state income tax pipeline.
|
|
2824
|
+
*
|
|
2825
|
+
* Purpose: Chains federal AGI, deductions, brackets, AMT, NIIT, payroll, credits, and the
|
|
2826
|
+
* state stage into one result.
|
|
2827
|
+
* Units: Inputs and outputs are major USD; internal arithmetic uses integer cents.
|
|
2828
|
+
* Throws: TaxValidationError if any input is invalid.
|
|
2829
|
+
*
|
|
2830
|
+
* @statute IRC § 1 et seq.; state individual income tax statutes.
|
|
2831
|
+
*/
|
|
2832
|
+
function executeUsTaxCalculation(input) {
|
|
2833
|
+
validateUsInput(input);
|
|
2834
|
+
const seRes = calculateUsScheduleSe(input.income, US_2026_PARAMETERS);
|
|
2835
|
+
const seTax = input.adjustments?.deductibleSelfEmploymentTax ?? seRes.deductiblePortionDollars;
|
|
2836
|
+
const adjustments = {
|
|
2837
|
+
...input.adjustments,
|
|
2838
|
+
deductibleSelfEmploymentTax: seTax
|
|
2839
|
+
};
|
|
2840
|
+
const agiRes = calculateUsAgi(input.income, adjustments, input.filingStatus, US_2026_PARAMETERS);
|
|
2841
|
+
const stateRes = calculateUsStateTax(input, agiRes.agiCents, input.filingStatus, US_2026_PARAMETERS.currency);
|
|
2842
|
+
const dedRes = calculateUsDeductions(input, agiRes.agiCents, agiRes.preferentialGrossCents, input.filingStatus, US_2026_PARAMETERS);
|
|
2843
|
+
const ordRes = require_clamp.evaluateBrackets(dedRes.ordinaryTaxableCents, US_2026_PARAMETERS.ordinaryBrackets[input.filingStatus], Math.max(0, agiRes.grossIncomeCents), "ordinaryTaxableIncome");
|
|
2844
|
+
const prefRes = calculateUsPreferentialStacking(dedRes.ordinaryTaxableCents, dedRes.taxableIncomeCents, US_2026_PARAMETERS.preferentialBrackets[input.filingStatus]);
|
|
2845
|
+
const regularTaxCents = ordRes.totalTax + prefRes.preferentialTaxCents;
|
|
2846
|
+
const saltCents = resolveAmtSaltCents(dedRes, US_2026_PARAMETERS.currency);
|
|
2847
|
+
const amtRes = calculateUsAmt(dedRes.taxableIncomeCents, saltCents, input.amtPreferences, regularTaxCents, input.filingStatus, US_2026_PARAMETERS);
|
|
2848
|
+
const niitRes = calculateUsNiit(input, agiRes.agiCents, input.filingStatus, US_2026_PARAMETERS);
|
|
2849
|
+
const ficaRes = calculateUsFica(input.income, input.filingStatus, input.includeFica ?? true, US_2026_PARAMETERS);
|
|
2850
|
+
const creditsRes = calculateUsCredits(input, agiRes.agiCents, regularTaxCents + amtRes.amtTaxCents, US_2026_PARAMETERS);
|
|
2851
|
+
const federalTaxCents = regularTaxCents + amtRes.amtTaxCents - creditsRes.allowedNonRefundableCents + niitRes.taxCents + ficaRes.totalFicaCents + seRes.totalSeTaxCents;
|
|
2852
|
+
const totalTaxCents = federalTaxCents + stateRes.totalTaxCents;
|
|
2853
|
+
const withhCents = require_clamp.toMinorUnits(input.withholding ?? 0, US_2026_PARAMETERS.currency, "withholding");
|
|
2854
|
+
const netTaxCents = federalTaxCents - creditsRes.totalRefundableCents - withhCents + stateRes.netTaxCents;
|
|
2855
|
+
return buildUsTaxResult({
|
|
2856
|
+
agiRes,
|
|
2857
|
+
dedRes,
|
|
2858
|
+
ordTaxCents: ordRes.totalTax,
|
|
2859
|
+
ordMarginalRate: ordRes.marginalRate,
|
|
2860
|
+
ordSlices: ordRes.slices,
|
|
2861
|
+
prefRes,
|
|
2862
|
+
regularTaxCents,
|
|
2863
|
+
amtRes,
|
|
2864
|
+
niitRes,
|
|
2865
|
+
ficaRes,
|
|
2866
|
+
seRes,
|
|
2867
|
+
creditsRes,
|
|
2868
|
+
stateRes,
|
|
2869
|
+
totalTaxCents,
|
|
2870
|
+
withhCents,
|
|
2871
|
+
netTaxCents
|
|
2872
|
+
});
|
|
2873
|
+
}
|
|
2874
|
+
// src/us/system.ts
|
|
2875
|
+
/**
|
|
2876
|
+
* US Federal and state Individual Income Tax System implementation for 2026.
|
|
2877
|
+
*
|
|
2878
|
+
* @statute IRC § 1 et seq.; state individual income tax statutes for Tax Year 2026.
|
|
2879
|
+
*/
|
|
2880
|
+
const us = {
|
|
2881
|
+
jurisdiction: "US",
|
|
2882
|
+
taxYear: 2026,
|
|
2883
|
+
currency: "USD",
|
|
2884
|
+
calculate(input) {
|
|
2885
|
+
return executeUsTaxCalculation(input);
|
|
2886
|
+
}
|
|
2887
|
+
};
|
|
2888
|
+
/**
|
|
2889
|
+
* Calculates 2026 US federal and optional state Individual Income Tax for the specified input.
|
|
2890
|
+
*
|
|
2891
|
+
* @statute IRC § 1 et seq.; state individual income tax statutes for Tax Year 2026.
|
|
2892
|
+
*/
|
|
2893
|
+
function calculateUsTax(input) {
|
|
2894
|
+
return us.calculate(input);
|
|
2895
|
+
}
|
|
2896
|
+
exports.US_2026_ABOVE_THE_LINE_CAPS = US_2026_ABOVE_THE_LINE_CAPS;
|
|
2897
|
+
exports.US_2026_ADDITIONAL_STANDARD_DEDUCTION = US_2026_ADDITIONAL_STANDARD_DEDUCTION;
|
|
2898
|
+
exports.US_2026_AMT = US_2026_AMT;
|
|
2899
|
+
exports.US_2026_CREDITS = US_2026_CREDITS;
|
|
2900
|
+
exports.US_2026_ITEMIZED = US_2026_ITEMIZED;
|
|
2901
|
+
exports.US_2026_NIIT = US_2026_NIIT;
|
|
2902
|
+
exports.US_2026_ORDINARY_BRACKETS = US_2026_ORDINARY_BRACKETS;
|
|
2903
|
+
exports.US_2026_PARAMETERS = US_2026_PARAMETERS;
|
|
2904
|
+
exports.US_2026_PAYROLL = US_2026_PAYROLL;
|
|
2905
|
+
exports.US_2026_PREFERENTIAL_BRACKETS = US_2026_PREFERENTIAL_BRACKETS;
|
|
2906
|
+
exports.US_2026_STANDARD_DEDUCTION = US_2026_STANDARD_DEDUCTION;
|
|
2907
|
+
exports.US_2026_STATE_PARAMETERS = US_2026_STATE_PARAMETERS;
|
|
2908
|
+
exports.US_STATE_CODES = US_STATE_CODES;
|
|
2909
|
+
exports.UsAdjustmentField = UsAdjustmentField;
|
|
2910
|
+
exports.UsAmtField = UsAmtField;
|
|
2911
|
+
exports.UsCreditField = UsCreditField;
|
|
2912
|
+
exports.UsDeductionField = UsDeductionField;
|
|
2913
|
+
exports.UsFicaField = UsPayrollField;
|
|
2914
|
+
exports.UsIncomeField = UsIncomeField;
|
|
2915
|
+
exports.UsPayrollField = UsPayrollField;
|
|
2916
|
+
exports.UsStateField = UsStateField;
|
|
2917
|
+
exports.UsTaxField = UsTaxField;
|
|
2918
|
+
exports.calculateUsTax = calculateUsTax;
|
|
2919
|
+
exports.us = us;
|
|
2920
|
+
|
|
2921
|
+
//# sourceMappingURL=index.cjs.map
|