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