@invaro/opentax 0.8.2 → 0.9.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bundle/http.js +1282 -852
- package/bundle/index.js +1267 -837
- package/bundle/main.js +1598 -1104
- package/package.json +4 -4
package/bundle/http.js
CHANGED
|
@@ -1139,10 +1139,10 @@ var require_codegen = __commonJS({
|
|
|
1139
1139
|
}
|
|
1140
1140
|
exports.not = not8;
|
|
1141
1141
|
var andCode = mappend(exports.operators.AND);
|
|
1142
|
-
function
|
|
1142
|
+
function and12(...args) {
|
|
1143
1143
|
return args.reduce(andCode);
|
|
1144
1144
|
}
|
|
1145
|
-
exports.and =
|
|
1145
|
+
exports.and = and12;
|
|
1146
1146
|
var orCode = mappend(exports.operators.OR);
|
|
1147
1147
|
function or11(...args) {
|
|
1148
1148
|
return args.reduce(orCode);
|
|
@@ -1579,12 +1579,12 @@ var require_applicability = __commonJS({
|
|
|
1579
1579
|
}
|
|
1580
1580
|
exports.schemaHasRulesForType = schemaHasRulesForType;
|
|
1581
1581
|
function shouldUseGroup(schema, group) {
|
|
1582
|
-
return group.rules.some((
|
|
1582
|
+
return group.rules.some((rule2) => shouldUseRule(schema, rule2));
|
|
1583
1583
|
}
|
|
1584
1584
|
exports.shouldUseGroup = shouldUseGroup;
|
|
1585
|
-
function shouldUseRule(schema,
|
|
1585
|
+
function shouldUseRule(schema, rule2) {
|
|
1586
1586
|
var _a3;
|
|
1587
|
-
return schema[
|
|
1587
|
+
return schema[rule2.keyword] !== void 0 || ((_a3 = rule2.definition.implements) === null || _a3 === void 0 ? void 0 : _a3.some((kwd) => schema[kwd] !== void 0));
|
|
1588
1588
|
}
|
|
1589
1589
|
exports.shouldUseRule = shouldUseRule;
|
|
1590
1590
|
}
|
|
@@ -2340,10 +2340,10 @@ var require_resolve = __commonJS({
|
|
|
2340
2340
|
}
|
|
2341
2341
|
return count;
|
|
2342
2342
|
}
|
|
2343
|
-
function getFullPath(resolver,
|
|
2343
|
+
function getFullPath(resolver, id2 = "", normalize) {
|
|
2344
2344
|
if (normalize !== false)
|
|
2345
|
-
|
|
2346
|
-
const p = resolver.parse(
|
|
2345
|
+
id2 = normalizeId(id2);
|
|
2346
|
+
const p = resolver.parse(id2);
|
|
2347
2347
|
return _getFullPath(resolver, p);
|
|
2348
2348
|
}
|
|
2349
2349
|
exports.getFullPath = getFullPath;
|
|
@@ -2353,13 +2353,13 @@ var require_resolve = __commonJS({
|
|
|
2353
2353
|
}
|
|
2354
2354
|
exports._getFullPath = _getFullPath;
|
|
2355
2355
|
var TRAILING_SLASH_HASH = /#\/?$/;
|
|
2356
|
-
function normalizeId(
|
|
2357
|
-
return
|
|
2356
|
+
function normalizeId(id2) {
|
|
2357
|
+
return id2 ? id2.replace(TRAILING_SLASH_HASH, "") : "";
|
|
2358
2358
|
}
|
|
2359
2359
|
exports.normalizeId = normalizeId;
|
|
2360
|
-
function resolveUrl(resolver, baseId,
|
|
2361
|
-
|
|
2362
|
-
return resolver.resolve(baseId,
|
|
2360
|
+
function resolveUrl(resolver, baseId, id2) {
|
|
2361
|
+
id2 = normalizeId(id2);
|
|
2362
|
+
return resolver.resolve(baseId, id2);
|
|
2363
2363
|
}
|
|
2364
2364
|
exports.resolveUrl = resolveUrl;
|
|
2365
2365
|
var ANCHOR = /^[a-z_][-a-z0-9._]*$/i;
|
|
@@ -2636,9 +2636,9 @@ var require_validate = __commonJS({
|
|
|
2636
2636
|
if (useDefaults)
|
|
2637
2637
|
(0, defaults_1.assignDefaults)(it, group.type);
|
|
2638
2638
|
gen.block(() => {
|
|
2639
|
-
for (const
|
|
2640
|
-
if ((0, applicability_1.shouldUseRule)(schema,
|
|
2641
|
-
keywordCode(it,
|
|
2639
|
+
for (const rule2 of group.rules) {
|
|
2640
|
+
if ((0, applicability_1.shouldUseRule)(schema, rule2)) {
|
|
2641
|
+
keywordCode(it, rule2.keyword, rule2.definition, group.type);
|
|
2642
2642
|
}
|
|
2643
2643
|
}
|
|
2644
2644
|
});
|
|
@@ -2673,9 +2673,9 @@ var require_validate = __commonJS({
|
|
|
2673
2673
|
function checkKeywordTypes(it, ts) {
|
|
2674
2674
|
const rules = it.self.RULES.all;
|
|
2675
2675
|
for (const keyword in rules) {
|
|
2676
|
-
const
|
|
2677
|
-
if (typeof
|
|
2678
|
-
const { type } =
|
|
2676
|
+
const rule2 = rules[keyword];
|
|
2677
|
+
if (typeof rule2 == "object" && (0, applicability_1.shouldUseRule)(it.schema, rule2)) {
|
|
2678
|
+
const { type } = rule2.definition;
|
|
2679
2679
|
if (type.length && !type.some((t) => hasApplicableType(ts, t))) {
|
|
2680
2680
|
strictTypesError(it, `missing type "${type.join(",")}" for keyword "${keyword}"`);
|
|
2681
2681
|
}
|
|
@@ -3129,8 +3129,8 @@ var require_compile = __commonJS({
|
|
|
3129
3129
|
if (Object.keys(root.schema).length > 0 && refPath === baseId) {
|
|
3130
3130
|
return getJsonPointer.call(this, p, root);
|
|
3131
3131
|
}
|
|
3132
|
-
const
|
|
3133
|
-
const schOrRef = this.refs[
|
|
3132
|
+
const id2 = (0, resolve_1.normalizeId)(refPath);
|
|
3133
|
+
const schOrRef = this.refs[id2] || this.schemas[id2];
|
|
3134
3134
|
if (typeof schOrRef == "string") {
|
|
3135
3135
|
const sch = resolveSchema.call(this, root, schOrRef);
|
|
3136
3136
|
if (typeof (sch === null || sch === void 0 ? void 0 : sch.schema) !== "object")
|
|
@@ -3141,7 +3141,7 @@ var require_compile = __commonJS({
|
|
|
3141
3141
|
return;
|
|
3142
3142
|
if (!schOrRef.validate)
|
|
3143
3143
|
compileSchema.call(this, schOrRef);
|
|
3144
|
-
if (
|
|
3144
|
+
if (id2 === (0, resolve_1.normalizeId)(ref)) {
|
|
3145
3145
|
const { schema } = schOrRef;
|
|
3146
3146
|
const { schemaId } = this.opts;
|
|
3147
3147
|
const schId = schema[schemaId];
|
|
@@ -3713,10 +3713,10 @@ var require_utils = __commonJS({
|
|
|
3713
3713
|
}
|
|
3714
3714
|
return output2;
|
|
3715
3715
|
}
|
|
3716
|
-
function recomposeZonedIPv6Host(
|
|
3717
|
-
const zone =
|
|
3716
|
+
function recomposeZonedIPv6Host(component2) {
|
|
3717
|
+
const zone = component2.ipv6Zone;
|
|
3718
3718
|
if (zone === void 0) return void 0;
|
|
3719
|
-
const host =
|
|
3719
|
+
const host = component2.host;
|
|
3720
3720
|
const separator = host.indexOf("%");
|
|
3721
3721
|
if (separator === -1) return void 0;
|
|
3722
3722
|
const address = host.slice(0, separator);
|
|
@@ -3727,16 +3727,16 @@ var require_utils = __commonJS({
|
|
|
3727
3727
|
}
|
|
3728
3728
|
return void 0;
|
|
3729
3729
|
}
|
|
3730
|
-
function recomposeAuthority(
|
|
3730
|
+
function recomposeAuthority(component2, allowNonAscii = false) {
|
|
3731
3731
|
const uriTokens = [];
|
|
3732
|
-
if (
|
|
3733
|
-
uriTokens.push(encodeUserinfo(
|
|
3732
|
+
if (component2.userinfo !== void 0) {
|
|
3733
|
+
uriTokens.push(encodeUserinfo(component2.userinfo));
|
|
3734
3734
|
uriTokens.push("@");
|
|
3735
3735
|
}
|
|
3736
|
-
if (
|
|
3737
|
-
let host =
|
|
3736
|
+
if (component2.host !== void 0) {
|
|
3737
|
+
let host = component2.host;
|
|
3738
3738
|
if (!isIPv4(host)) {
|
|
3739
|
-
const zonedHost = recomposeZonedIPv6Host(
|
|
3739
|
+
const zonedHost = recomposeZonedIPv6Host(component2);
|
|
3740
3740
|
if (zonedHost !== void 0) {
|
|
3741
3741
|
host = zonedHost;
|
|
3742
3742
|
} else {
|
|
@@ -3754,8 +3754,8 @@ var require_utils = __commonJS({
|
|
|
3754
3754
|
}
|
|
3755
3755
|
uriTokens.push(host);
|
|
3756
3756
|
}
|
|
3757
|
-
if (typeof
|
|
3758
|
-
const port = String(
|
|
3757
|
+
if (typeof component2.port === "number" || typeof component2.port === "string") {
|
|
3758
|
+
const port = String(component2.port);
|
|
3759
3759
|
if (!isPort(port)) {
|
|
3760
3760
|
throw new TypeError("URI port is malformed.");
|
|
3761
3761
|
}
|
|
@@ -3824,21 +3824,21 @@ var require_schemes = __commonJS({
|
|
|
3824
3824
|
return false;
|
|
3825
3825
|
}
|
|
3826
3826
|
}
|
|
3827
|
-
function httpParse(
|
|
3828
|
-
if (!
|
|
3829
|
-
|
|
3827
|
+
function httpParse(component2) {
|
|
3828
|
+
if (!component2.host) {
|
|
3829
|
+
component2.error = component2.error || "HTTP URIs must have a host.";
|
|
3830
3830
|
}
|
|
3831
|
-
return
|
|
3831
|
+
return component2;
|
|
3832
3832
|
}
|
|
3833
|
-
function httpSerialize(
|
|
3834
|
-
const secure = String(
|
|
3835
|
-
if (
|
|
3836
|
-
|
|
3833
|
+
function httpSerialize(component2) {
|
|
3834
|
+
const secure = String(component2.scheme).toLowerCase() === "https";
|
|
3835
|
+
if (component2.port === (secure ? 443 : 80) || component2.port === "") {
|
|
3836
|
+
component2.port = void 0;
|
|
3837
3837
|
}
|
|
3838
|
-
if (!
|
|
3839
|
-
|
|
3838
|
+
if (!component2.path) {
|
|
3839
|
+
component2.path = "/";
|
|
3840
3840
|
}
|
|
3841
|
-
return
|
|
3841
|
+
return component2;
|
|
3842
3842
|
}
|
|
3843
3843
|
function wsParse(wsComponent) {
|
|
3844
3844
|
wsComponent.secure = wsIsSecure(wsComponent);
|
|
@@ -4056,7 +4056,7 @@ var require_schemes = __commonJS({
|
|
|
4056
4056
|
}
|
|
4057
4057
|
return result;
|
|
4058
4058
|
}
|
|
4059
|
-
function mailtoNormalizeDomain(domain2, options,
|
|
4059
|
+
function mailtoNormalizeDomain(domain2, options, component2) {
|
|
4060
4060
|
const normalizedDomain = String(domain2).toLowerCase();
|
|
4061
4061
|
if (MAILTO_DOMAIN_LITERAL.test(normalizedDomain)) {
|
|
4062
4062
|
return normalizedDomain;
|
|
@@ -4071,8 +4071,8 @@ var require_schemes = __commonJS({
|
|
|
4071
4071
|
}
|
|
4072
4072
|
return options && options.unicodeSupport ? normalizedDomain : parsedDomain.hostname;
|
|
4073
4073
|
} catch {
|
|
4074
|
-
if (
|
|
4075
|
-
|
|
4074
|
+
if (component2) {
|
|
4075
|
+
component2.error = component2.error || MAILTO_DOMAIN_ERROR;
|
|
4076
4076
|
}
|
|
4077
4077
|
return normalizedDomain;
|
|
4078
4078
|
}
|
|
@@ -4084,8 +4084,8 @@ var require_schemes = __commonJS({
|
|
|
4084
4084
|
}
|
|
4085
4085
|
return encodeWithAllow(domain2, set2);
|
|
4086
4086
|
}
|
|
4087
|
-
function mailtoParse(
|
|
4088
|
-
const mailtoComponent =
|
|
4087
|
+
function mailtoParse(component2, options) {
|
|
4088
|
+
const mailtoComponent = component2;
|
|
4089
4089
|
let rawPath = mailtoComponent.path;
|
|
4090
4090
|
let rawQuery = mailtoComponent.query;
|
|
4091
4091
|
if (rawPath && HAS_SURROGATE.test(rawPath)) rawPath = replaceLoneSurrogates(rawPath);
|
|
@@ -4152,8 +4152,8 @@ var require_schemes = __commonJS({
|
|
|
4152
4152
|
function mailtoEncodeHeaderName(name) {
|
|
4153
4153
|
return encodeWithAllow(name.replace(/%/gu, "%25"), HFNAME);
|
|
4154
4154
|
}
|
|
4155
|
-
function mailtoSerialize(
|
|
4156
|
-
const mailtoComponent =
|
|
4155
|
+
function mailtoSerialize(component2, options) {
|
|
4156
|
+
const mailtoComponent = component2;
|
|
4157
4157
|
const to = Array.isArray(mailtoComponent.to) ? mailtoComponent.to.slice() : [];
|
|
4158
4158
|
const sourceHeaders = mailtoComponent.headers && typeof mailtoComponent.headers === "object" ? Object.assign(/* @__PURE__ */ Object.create(null), mailtoComponent.headers) : /* @__PURE__ */ Object.create(null);
|
|
4159
4159
|
const headers = /* @__PURE__ */ Object.create(null);
|
|
@@ -4389,7 +4389,7 @@ var require_fast_uri = __commonJS({
|
|
|
4389
4389
|
return normalizedA !== void 0 && normalizedB !== void 0 && normalizedA === normalizedB;
|
|
4390
4390
|
}
|
|
4391
4391
|
function serialize2(cmpts, opts) {
|
|
4392
|
-
const
|
|
4392
|
+
const component2 = {
|
|
4393
4393
|
host: cmpts.host,
|
|
4394
4394
|
ipv6Zone: cmpts.ipv6Zone,
|
|
4395
4395
|
scheme: cmpts.scheme,
|
|
@@ -4412,38 +4412,38 @@ var require_fast_uri = __commonJS({
|
|
|
4412
4412
|
};
|
|
4413
4413
|
const options = Object.assign({}, opts);
|
|
4414
4414
|
const uriTokens = [];
|
|
4415
|
-
if (
|
|
4416
|
-
|
|
4415
|
+
if (component2.scheme) {
|
|
4416
|
+
component2.scheme = validateScheme(component2.scheme);
|
|
4417
4417
|
}
|
|
4418
|
-
const schemeHandler = getSchemeHandler(options.scheme ||
|
|
4419
|
-
if (schemeHandler && schemeHandler.serialize) schemeHandler.serialize(
|
|
4420
|
-
const hasAuthority =
|
|
4421
|
-
const schemelessReference = (
|
|
4418
|
+
const schemeHandler = getSchemeHandler(options.scheme || component2.scheme);
|
|
4419
|
+
if (schemeHandler && schemeHandler.serialize) schemeHandler.serialize(component2, options);
|
|
4420
|
+
const hasAuthority = component2.userinfo !== void 0 || component2.host !== void 0 || component2.port !== void 0;
|
|
4421
|
+
const schemelessReference = (component2.scheme === void 0 || options.reference === "suffix") && !hasAuthority;
|
|
4422
4422
|
const pathNoScheme = !options.skipEscape && schemelessReference;
|
|
4423
|
-
if (
|
|
4423
|
+
if (component2.path !== void 0) {
|
|
4424
4424
|
if (!options.skipEscape) {
|
|
4425
|
-
|
|
4425
|
+
component2.path = serializePathEncoding(component2.path, pathNoScheme);
|
|
4426
4426
|
} else {
|
|
4427
|
-
|
|
4427
|
+
component2.path = normalizePercentEncoding(component2.path);
|
|
4428
4428
|
}
|
|
4429
4429
|
}
|
|
4430
|
-
if (options.reference !== "suffix" &&
|
|
4431
|
-
|
|
4432
|
-
uriTokens.push(
|
|
4430
|
+
if (options.reference !== "suffix" && component2.scheme) {
|
|
4431
|
+
component2.scheme = validateScheme(component2.scheme);
|
|
4432
|
+
uriTokens.push(component2.scheme, ":");
|
|
4433
4433
|
}
|
|
4434
4434
|
const allowNonAsciiHost = options.unicodeSupport === true || Boolean(schemeHandler && schemeHandler.unicodeSupport);
|
|
4435
|
-
const authority = recomposeAuthority(
|
|
4435
|
+
const authority = recomposeAuthority(component2, allowNonAsciiHost);
|
|
4436
4436
|
if (authority !== void 0) {
|
|
4437
4437
|
if (options.reference !== "suffix") {
|
|
4438
4438
|
uriTokens.push("//");
|
|
4439
4439
|
}
|
|
4440
4440
|
uriTokens.push(authority);
|
|
4441
|
-
if (
|
|
4441
|
+
if (component2.path && component2.path[0] !== "/") {
|
|
4442
4442
|
uriTokens.push("/");
|
|
4443
4443
|
}
|
|
4444
4444
|
}
|
|
4445
|
-
if (
|
|
4446
|
-
let s =
|
|
4445
|
+
if (component2.path !== void 0) {
|
|
4446
|
+
let s = component2.path;
|
|
4447
4447
|
if (!options.absolutePath && (!schemeHandler || !schemeHandler.absolutePath)) {
|
|
4448
4448
|
s = schemelessReference && s[0] !== "/" ? removeDotSegmentsRelative(s) : removeDotSegments(s);
|
|
4449
4449
|
}
|
|
@@ -4455,11 +4455,11 @@ var require_fast_uri = __commonJS({
|
|
|
4455
4455
|
}
|
|
4456
4456
|
uriTokens.push(s);
|
|
4457
4457
|
}
|
|
4458
|
-
if (
|
|
4459
|
-
uriTokens.push("?", encodeQuery(
|
|
4458
|
+
if (component2.query !== void 0) {
|
|
4459
|
+
uriTokens.push("?", encodeQuery(component2.query));
|
|
4460
4460
|
}
|
|
4461
|
-
if (
|
|
4462
|
-
uriTokens.push("#", encodeFragment(
|
|
4461
|
+
if (component2.fragment !== void 0) {
|
|
4462
|
+
uriTokens.push("#", encodeFragment(component2.fragment));
|
|
4463
4463
|
}
|
|
4464
4464
|
return uriTokens.join("");
|
|
4465
4465
|
}
|
|
@@ -4475,14 +4475,14 @@ var require_fast_uri = __commonJS({
|
|
|
4475
4475
|
}
|
|
4476
4476
|
return void 0;
|
|
4477
4477
|
}
|
|
4478
|
-
function hasMalformedPercentEncoding(
|
|
4479
|
-
if (
|
|
4480
|
-
let percent =
|
|
4478
|
+
function hasMalformedPercentEncoding(component2) {
|
|
4479
|
+
if (component2 === void 0) return false;
|
|
4480
|
+
let percent = component2.indexOf("%");
|
|
4481
4481
|
while (percent !== -1) {
|
|
4482
|
-
if (percent + 2 >=
|
|
4482
|
+
if (percent + 2 >= component2.length || !/^[\da-f]{2}$/iu.test(component2.slice(percent + 1, percent + 3))) {
|
|
4483
4483
|
return true;
|
|
4484
4484
|
}
|
|
4485
|
-
percent =
|
|
4485
|
+
percent = component2.indexOf("%", percent + 3);
|
|
4486
4486
|
}
|
|
4487
4487
|
return false;
|
|
4488
4488
|
}
|
|
@@ -4958,15 +4958,15 @@ var require_core = __commonJS({
|
|
|
4958
4958
|
this.addSchema(sch, void 0, _meta, _validateSchema);
|
|
4959
4959
|
return this;
|
|
4960
4960
|
}
|
|
4961
|
-
let
|
|
4961
|
+
let id2;
|
|
4962
4962
|
if (typeof schema === "object") {
|
|
4963
4963
|
const { schemaId } = this.opts;
|
|
4964
|
-
|
|
4965
|
-
if (
|
|
4964
|
+
id2 = schema[schemaId];
|
|
4965
|
+
if (id2 !== void 0 && typeof id2 != "string") {
|
|
4966
4966
|
throw new Error(`schema ${schemaId} must be string`);
|
|
4967
4967
|
}
|
|
4968
4968
|
}
|
|
4969
|
-
key = (0, resolve_1.normalizeId)(key ||
|
|
4969
|
+
key = (0, resolve_1.normalizeId)(key || id2);
|
|
4970
4970
|
this._checkUnique(key);
|
|
4971
4971
|
this.schemas[key] = this._addSchema(schema, _meta, key, _validateSchema, true);
|
|
4972
4972
|
return this;
|
|
@@ -5045,11 +5045,11 @@ var require_core = __commonJS({
|
|
|
5045
5045
|
case "object": {
|
|
5046
5046
|
const cacheKey2 = schemaKeyRef;
|
|
5047
5047
|
this._cache.delete(cacheKey2);
|
|
5048
|
-
let
|
|
5049
|
-
if (
|
|
5050
|
-
|
|
5051
|
-
delete this.schemas[
|
|
5052
|
-
delete this.refs[
|
|
5048
|
+
let id2 = schemaKeyRef[this.opts.schemaId];
|
|
5049
|
+
if (id2) {
|
|
5050
|
+
id2 = (0, resolve_1.normalizeId)(id2);
|
|
5051
|
+
delete this.schemas[id2];
|
|
5052
|
+
delete this.refs[id2];
|
|
5053
5053
|
}
|
|
5054
5054
|
return this;
|
|
5055
5055
|
}
|
|
@@ -5095,8 +5095,8 @@ var require_core = __commonJS({
|
|
|
5095
5095
|
return this;
|
|
5096
5096
|
}
|
|
5097
5097
|
getKeyword(keyword) {
|
|
5098
|
-
const
|
|
5099
|
-
return typeof
|
|
5098
|
+
const rule2 = this.RULES.all[keyword];
|
|
5099
|
+
return typeof rule2 == "object" ? rule2.definition : !!rule2;
|
|
5100
5100
|
}
|
|
5101
5101
|
// Remove keyword
|
|
5102
5102
|
removeKeyword(keyword) {
|
|
@@ -5104,7 +5104,7 @@ var require_core = __commonJS({
|
|
|
5104
5104
|
delete RULES.keywords[keyword];
|
|
5105
5105
|
delete RULES.all[keyword];
|
|
5106
5106
|
for (const group of RULES.rules) {
|
|
5107
|
-
const i = group.rules.findIndex((
|
|
5107
|
+
const i = group.rules.findIndex((rule2) => rule2.keyword === keyword);
|
|
5108
5108
|
if (i >= 0)
|
|
5109
5109
|
group.rules.splice(i, 1);
|
|
5110
5110
|
}
|
|
@@ -5131,10 +5131,10 @@ var require_core = __commonJS({
|
|
|
5131
5131
|
for (const seg of segments)
|
|
5132
5132
|
keywords = keywords[seg];
|
|
5133
5133
|
for (const key in rules) {
|
|
5134
|
-
const
|
|
5135
|
-
if (typeof
|
|
5134
|
+
const rule2 = rules[key];
|
|
5135
|
+
if (typeof rule2 != "object")
|
|
5136
5136
|
continue;
|
|
5137
|
-
const { $data } =
|
|
5137
|
+
const { $data } = rule2.definition;
|
|
5138
5138
|
const schema = keywords[key];
|
|
5139
5139
|
if ($data && schema)
|
|
5140
5140
|
keywords[key] = schemaOrData(schema);
|
|
@@ -5156,10 +5156,10 @@ var require_core = __commonJS({
|
|
|
5156
5156
|
}
|
|
5157
5157
|
}
|
|
5158
5158
|
_addSchema(schema, meta3, baseId, validateSchema = this.opts.validateSchema, addSchema = this.opts.addUsedSchema) {
|
|
5159
|
-
let
|
|
5159
|
+
let id2;
|
|
5160
5160
|
const { schemaId } = this.opts;
|
|
5161
5161
|
if (typeof schema == "object") {
|
|
5162
|
-
|
|
5162
|
+
id2 = schema[schemaId];
|
|
5163
5163
|
} else {
|
|
5164
5164
|
if (this.opts.jtd)
|
|
5165
5165
|
throw new Error("schema must be object");
|
|
@@ -5169,7 +5169,7 @@ var require_core = __commonJS({
|
|
|
5169
5169
|
let sch = this._cache.get(schema);
|
|
5170
5170
|
if (sch !== void 0)
|
|
5171
5171
|
return sch;
|
|
5172
|
-
baseId = (0, resolve_1.normalizeId)(
|
|
5172
|
+
baseId = (0, resolve_1.normalizeId)(id2 || baseId);
|
|
5173
5173
|
const localRefs = resolve_1.getSchemaRefs.call(this, schema, baseId);
|
|
5174
5174
|
sch = new compile_1.SchemaEnv({ schema, schemaId, meta: meta3, baseId, localRefs });
|
|
5175
5175
|
this._cache.set(sch.schema, sch);
|
|
@@ -5182,9 +5182,9 @@ var require_core = __commonJS({
|
|
|
5182
5182
|
this.validateSchema(schema, true);
|
|
5183
5183
|
return sch;
|
|
5184
5184
|
}
|
|
5185
|
-
_checkUnique(
|
|
5186
|
-
if (this.schemas[
|
|
5187
|
-
throw new Error(`schema with key or id "${
|
|
5185
|
+
_checkUnique(id2) {
|
|
5186
|
+
if (this.schemas[id2] || this.refs[id2]) {
|
|
5187
|
+
throw new Error(`schema with key or id "${id2}" already exists`);
|
|
5188
5188
|
}
|
|
5189
5189
|
}
|
|
5190
5190
|
_compileSchemaEnv(sch) {
|
|
@@ -5298,7 +5298,7 @@ var require_core = __commonJS({
|
|
|
5298
5298
|
RULES.keywords[keyword] = true;
|
|
5299
5299
|
if (!definition)
|
|
5300
5300
|
return;
|
|
5301
|
-
const
|
|
5301
|
+
const rule2 = {
|
|
5302
5302
|
keyword,
|
|
5303
5303
|
definition: {
|
|
5304
5304
|
...definition,
|
|
@@ -5307,18 +5307,18 @@ var require_core = __commonJS({
|
|
|
5307
5307
|
}
|
|
5308
5308
|
};
|
|
5309
5309
|
if (definition.before)
|
|
5310
|
-
addBeforeRule.call(this, ruleGroup,
|
|
5310
|
+
addBeforeRule.call(this, ruleGroup, rule2, definition.before);
|
|
5311
5311
|
else
|
|
5312
|
-
ruleGroup.rules.push(
|
|
5313
|
-
RULES.all[keyword] =
|
|
5312
|
+
ruleGroup.rules.push(rule2);
|
|
5313
|
+
RULES.all[keyword] = rule2;
|
|
5314
5314
|
(_a3 = definition.implements) === null || _a3 === void 0 ? void 0 : _a3.forEach((kwd) => this.addKeyword(kwd));
|
|
5315
5315
|
}
|
|
5316
|
-
function addBeforeRule(ruleGroup,
|
|
5316
|
+
function addBeforeRule(ruleGroup, rule2, before) {
|
|
5317
5317
|
const i = ruleGroup.rules.findIndex((_rule) => _rule.keyword === before);
|
|
5318
5318
|
if (i >= 0) {
|
|
5319
|
-
ruleGroup.rules.splice(i, 0,
|
|
5319
|
+
ruleGroup.rules.splice(i, 0, rule2);
|
|
5320
5320
|
} else {
|
|
5321
|
-
ruleGroup.rules.push(
|
|
5321
|
+
ruleGroup.rules.push(rule2);
|
|
5322
5322
|
this.logger.warn(`rule ${before} is not defined`);
|
|
5323
5323
|
}
|
|
5324
5324
|
}
|
|
@@ -6156,8 +6156,8 @@ var require_contains = __commonJS({
|
|
|
6156
6156
|
var codegen_1 = require_codegen();
|
|
6157
6157
|
var util_1 = require_util();
|
|
6158
6158
|
var error62 = {
|
|
6159
|
-
message: ({ params: { min:
|
|
6160
|
-
params: ({ params: { min:
|
|
6159
|
+
message: ({ params: { min: min7, max: max2 } }) => max2 === void 0 ? (0, codegen_1.str)`must contain at least ${min7} valid item(s)` : (0, codegen_1.str)`must contain at least ${min7} and no more than ${max2} valid item(s)`,
|
|
6160
|
+
params: ({ params: { min: min7, max: max2 } }) => max2 === void 0 ? (0, codegen_1._)`{minContains: ${min7}}` : (0, codegen_1._)`{minContains: ${min7}, maxContains: ${max2}}`
|
|
6161
6161
|
};
|
|
6162
6162
|
var def = {
|
|
6163
6163
|
keyword: "contains",
|
|
@@ -6168,28 +6168,28 @@ var require_contains = __commonJS({
|
|
|
6168
6168
|
error: error62,
|
|
6169
6169
|
code(cxt) {
|
|
6170
6170
|
const { gen, schema, parentSchema, data, it } = cxt;
|
|
6171
|
-
let
|
|
6171
|
+
let min7;
|
|
6172
6172
|
let max2;
|
|
6173
6173
|
const { minContains, maxContains } = parentSchema;
|
|
6174
6174
|
if (it.opts.next) {
|
|
6175
|
-
|
|
6175
|
+
min7 = minContains === void 0 ? 1 : minContains;
|
|
6176
6176
|
max2 = maxContains;
|
|
6177
6177
|
} else {
|
|
6178
|
-
|
|
6178
|
+
min7 = 1;
|
|
6179
6179
|
}
|
|
6180
6180
|
const len = gen.const("len", (0, codegen_1._)`${data}.length`);
|
|
6181
|
-
cxt.setParams({ min:
|
|
6182
|
-
if (max2 === void 0 &&
|
|
6181
|
+
cxt.setParams({ min: min7, max: max2 });
|
|
6182
|
+
if (max2 === void 0 && min7 === 0) {
|
|
6183
6183
|
(0, util_1.checkStrictMode)(it, `"minContains" == 0 without "maxContains": "contains" keyword ignored`);
|
|
6184
6184
|
return;
|
|
6185
6185
|
}
|
|
6186
|
-
if (max2 !== void 0 &&
|
|
6186
|
+
if (max2 !== void 0 && min7 > max2) {
|
|
6187
6187
|
(0, util_1.checkStrictMode)(it, `"minContains" > "maxContains" is always invalid`);
|
|
6188
6188
|
cxt.fail();
|
|
6189
6189
|
return;
|
|
6190
6190
|
}
|
|
6191
6191
|
if ((0, util_1.alwaysValidSchema)(it, schema)) {
|
|
6192
|
-
let cond = (0, codegen_1._)`${len} >= ${
|
|
6192
|
+
let cond = (0, codegen_1._)`${len} >= ${min7}`;
|
|
6193
6193
|
if (max2 !== void 0)
|
|
6194
6194
|
cond = (0, codegen_1._)`${cond} && ${len} <= ${max2}`;
|
|
6195
6195
|
cxt.pass(cond);
|
|
@@ -6197,9 +6197,9 @@ var require_contains = __commonJS({
|
|
|
6197
6197
|
}
|
|
6198
6198
|
it.items = true;
|
|
6199
6199
|
const valid = gen.name("valid");
|
|
6200
|
-
if (max2 === void 0 &&
|
|
6200
|
+
if (max2 === void 0 && min7 === 1) {
|
|
6201
6201
|
validateItems(valid, () => gen.if(valid, () => gen.break()));
|
|
6202
|
-
} else if (
|
|
6202
|
+
} else if (min7 === 0) {
|
|
6203
6203
|
gen.let(valid, true);
|
|
6204
6204
|
if (max2 !== void 0)
|
|
6205
6205
|
gen.if((0, codegen_1._)`${data}.length > 0`, validateItemsWithCount);
|
|
@@ -6227,13 +6227,13 @@ var require_contains = __commonJS({
|
|
|
6227
6227
|
function checkLimits(count) {
|
|
6228
6228
|
gen.code((0, codegen_1._)`${count}++`);
|
|
6229
6229
|
if (max2 === void 0) {
|
|
6230
|
-
gen.if((0, codegen_1._)`${count} >= ${
|
|
6230
|
+
gen.if((0, codegen_1._)`${count} >= ${min7}`, () => gen.assign(valid, true).break());
|
|
6231
6231
|
} else {
|
|
6232
6232
|
gen.if((0, codegen_1._)`${count} > ${max2}`, () => gen.assign(valid, false).break());
|
|
6233
|
-
if (
|
|
6233
|
+
if (min7 === 1)
|
|
6234
6234
|
gen.assign(valid, true);
|
|
6235
6235
|
else
|
|
6236
|
-
gen.if((0, codegen_1._)`${count} >= ${
|
|
6236
|
+
gen.if((0, codegen_1._)`${count} >= ${min7}`, () => gen.assign(valid, true));
|
|
6237
6237
|
}
|
|
6238
6238
|
}
|
|
6239
6239
|
}
|
|
@@ -7479,7 +7479,7 @@ var require_formats = __commonJS({
|
|
|
7479
7479
|
if (!matches)
|
|
7480
7480
|
return false;
|
|
7481
7481
|
const hr = +matches[1];
|
|
7482
|
-
const
|
|
7482
|
+
const min7 = +matches[2];
|
|
7483
7483
|
const sec = +matches[3];
|
|
7484
7484
|
const tz = matches[4];
|
|
7485
7485
|
const tzSign = matches[5] === "-" ? -1 : 1;
|
|
@@ -7487,9 +7487,9 @@ var require_formats = __commonJS({
|
|
|
7487
7487
|
const tzM = +(matches[7] || 0);
|
|
7488
7488
|
if (tzH > 23 || tzM > 59 || strictTimeZone && !tz)
|
|
7489
7489
|
return false;
|
|
7490
|
-
if (hr <= 23 &&
|
|
7490
|
+
if (hr <= 23 && min7 <= 59 && sec < 60)
|
|
7491
7491
|
return true;
|
|
7492
|
-
const utcMin =
|
|
7492
|
+
const utcMin = min7 - tzM * tzSign;
|
|
7493
7493
|
const utcHr = hr - tzH * tzSign - (utcMin < 0 ? 1 : 0);
|
|
7494
7494
|
return (utcHr === 23 || utcHr === -1) && (utcMin === 59 || utcMin === -1) && sec < 61;
|
|
7495
7495
|
};
|
|
@@ -10423,11 +10423,11 @@ function node(obj, key, make) {
|
|
|
10423
10423
|
function flattenError(error62, mapper = (issue2) => issue2.message) {
|
|
10424
10424
|
const fieldErrors = {};
|
|
10425
10425
|
const formErrors = [];
|
|
10426
|
-
for (const
|
|
10427
|
-
if (
|
|
10428
|
-
node(fieldErrors,
|
|
10426
|
+
for (const sub28 of error62.issues) {
|
|
10427
|
+
if (sub28.path.length > 0) {
|
|
10428
|
+
node(fieldErrors, sub28.path[0], () => []).push(mapper(sub28));
|
|
10429
10429
|
} else {
|
|
10430
|
-
formErrors.push(mapper(
|
|
10430
|
+
formErrors.push(mapper(sub28));
|
|
10431
10431
|
}
|
|
10432
10432
|
}
|
|
10433
10433
|
return { formErrors, fieldErrors };
|
|
@@ -12426,15 +12426,15 @@ var $ZodObjectJIT = /* @__PURE__ */ $constructor("$ZodObjectJIT", (inst, def) =>
|
|
|
12426
12426
|
const syms = normalized.symbolKeys;
|
|
12427
12427
|
const doc = new Doc(["payload", "ctx"], { shape, inst, memo: memo2, syms });
|
|
12428
12428
|
const parseStr = (k) => `shape[${k}]._zod.run({ value: input[${k}], issues: [] }, ctx)`;
|
|
12429
|
-
const prefixStr = (
|
|
12430
|
-
let ${
|
|
12431
|
-
for (let i = 0; i < ${
|
|
12432
|
-
const iss = ${
|
|
12429
|
+
const prefixStr = (id2, k) => `
|
|
12430
|
+
let ${id2}_ab = false;
|
|
12431
|
+
for (let i = 0; i < ${id2}.issues.length; i++) {
|
|
12432
|
+
const iss = ${id2}.issues[i];
|
|
12433
12433
|
iss.path = iss.path ? [${k}, ...iss.path] : [${k}];
|
|
12434
12434
|
payload.issues.push(iss);
|
|
12435
|
-
if (iss.continue !== true) ${
|
|
12435
|
+
if (iss.continue !== true) ${id2}_ab = true;
|
|
12436
12436
|
}
|
|
12437
|
-
if (${
|
|
12437
|
+
if (${id2}_ab && ctx && ctx.abortEarly) {
|
|
12438
12438
|
payload.value = newResult;
|
|
12439
12439
|
return payload;
|
|
12440
12440
|
}`;
|
|
@@ -12448,34 +12448,34 @@ var $ZodObjectJIT = /* @__PURE__ */ $constructor("$ZodObjectJIT", (inst, def) =>
|
|
|
12448
12448
|
for (const key of normalized.allKeys) {
|
|
12449
12449
|
if (key === "__proto__")
|
|
12450
12450
|
continue;
|
|
12451
|
-
const
|
|
12451
|
+
const id2 = ids[key];
|
|
12452
12452
|
const k = typeof key === "symbol" ? `syms[${syms.indexOf(key)}]` : esc(key);
|
|
12453
12453
|
const isPresent = `${k} in input`;
|
|
12454
12454
|
const schema = shape[key];
|
|
12455
12455
|
const optin = schema?._zod?.optin;
|
|
12456
12456
|
const isOptionalIn = optin !== void 0;
|
|
12457
12457
|
const isOptionalOut = schema?._zod?.optout === "optional";
|
|
12458
|
-
doc.write(`const ${
|
|
12458
|
+
doc.write(`const ${id2} = ${parseStr(k)};`);
|
|
12459
12459
|
if (isOptionalIn && isOptionalOut) {
|
|
12460
|
-
const assign = optin === "optional" ? `${
|
|
12460
|
+
const assign = optin === "optional" ? `${id2}_present` : `${id2}.value !== undefined || ${id2}_present`;
|
|
12461
12461
|
doc.write(`
|
|
12462
|
-
const ${
|
|
12463
|
-
if (!${
|
|
12464
|
-
if (${
|
|
12462
|
+
const ${id2}_present = ${isPresent};
|
|
12463
|
+
if (!${id2}.issues.length || ${id2}_present) {
|
|
12464
|
+
if (${id2}.issues.length) {${prefixStr(id2, k)}
|
|
12465
12465
|
}
|
|
12466
12466
|
|
|
12467
12467
|
if (${assign}) {
|
|
12468
|
-
newResult[${k}] = ${
|
|
12468
|
+
newResult[${k}] = ${id2}.value;
|
|
12469
12469
|
}
|
|
12470
12470
|
}
|
|
12471
12471
|
|
|
12472
12472
|
`);
|
|
12473
12473
|
} else if (!isOptionalIn) {
|
|
12474
12474
|
doc.write(`
|
|
12475
|
-
const ${
|
|
12476
|
-
if (${
|
|
12475
|
+
const ${id2}_present = ${isPresent};
|
|
12476
|
+
if (${id2}.issues.length) {${prefixStr(id2, k)}
|
|
12477
12477
|
}
|
|
12478
|
-
if (!${
|
|
12478
|
+
if (!${id2}_present && !${id2}.issues.length) {
|
|
12479
12479
|
payload.issues.push({
|
|
12480
12480
|
code: "invalid_type",
|
|
12481
12481
|
expected: "nonoptional",
|
|
@@ -12488,22 +12488,22 @@ var $ZodObjectJIT = /* @__PURE__ */ $constructor("$ZodObjectJIT", (inst, def) =>
|
|
|
12488
12488
|
}
|
|
12489
12489
|
}
|
|
12490
12490
|
|
|
12491
|
-
if (${
|
|
12492
|
-
newResult[${k}] = ${
|
|
12491
|
+
if (${id2}_present) {
|
|
12492
|
+
newResult[${k}] = ${id2}.value;
|
|
12493
12493
|
}
|
|
12494
12494
|
|
|
12495
12495
|
`);
|
|
12496
12496
|
} else {
|
|
12497
12497
|
doc.write(`
|
|
12498
|
-
if (${
|
|
12498
|
+
if (${id2}.issues.length) {${prefixStr(id2, k)}
|
|
12499
12499
|
}
|
|
12500
12500
|
`);
|
|
12501
12501
|
if (optin === "defaulted") {
|
|
12502
|
-
doc.write(`newResult[${k}] = ${
|
|
12502
|
+
doc.write(`newResult[${k}] = ${id2}.value;`);
|
|
12503
12503
|
} else {
|
|
12504
12504
|
doc.write(`
|
|
12505
|
-
if (${
|
|
12506
|
-
newResult[${k}] = ${
|
|
12505
|
+
if (${id2}.value !== undefined || ${isPresent}) {
|
|
12506
|
+
newResult[${k}] = ${id2}.value;
|
|
12507
12507
|
}
|
|
12508
12508
|
`);
|
|
12509
12509
|
}
|
|
@@ -12858,11 +12858,11 @@ function handleIntersectionResults(result, left, right) {
|
|
|
12858
12858
|
}
|
|
12859
12859
|
const bothKeys = [...unrecKeys].filter(([, f]) => f.l && f.r).map(([k]) => k);
|
|
12860
12860
|
if (bothKeys.length) {
|
|
12861
|
-
const
|
|
12862
|
-
if (
|
|
12863
|
-
result.issues.push({ ...unrecIssue, keys:
|
|
12861
|
+
const aggregated2 = unrecIssue ? bothKeys.filter((k) => unrecIssue.keys.includes(k)) : [];
|
|
12862
|
+
if (aggregated2.length)
|
|
12863
|
+
result.issues.push({ ...unrecIssue, keys: aggregated2 });
|
|
12864
12864
|
for (const k of bothKeys) {
|
|
12865
|
-
if (!
|
|
12865
|
+
if (!aggregated2.includes(k) && keyIssues.has(k))
|
|
12866
12866
|
result.issues.push(keyIssues.get(k));
|
|
12867
12867
|
}
|
|
12868
12868
|
}
|
|
@@ -21965,9 +21965,9 @@ function generateChecks(doc, ctx, schema, accessor) {
|
|
|
21965
21965
|
generateNumberFormatCheck(doc, def, currentAccessor);
|
|
21966
21966
|
break;
|
|
21967
21967
|
case "min_length": {
|
|
21968
|
-
const
|
|
21969
|
-
const len = codePointLengthVar(doc, ctx, currentAccessor, `${currentAccessor}.length >= ${
|
|
21970
|
-
doc.write(`if (${len} < ${
|
|
21968
|
+
const min7 = numericOperand(def.minimum, "min_length");
|
|
21969
|
+
const len = codePointLengthVar(doc, ctx, currentAccessor, `${currentAccessor}.length >= ${min7} && ${currentAccessor}.length < ${def.minimum * 2}`);
|
|
21970
|
+
doc.write(`if (${len} < ${min7}) return INVALID;`);
|
|
21971
21971
|
break;
|
|
21972
21972
|
}
|
|
21973
21973
|
case "max_length": {
|
|
@@ -24531,26 +24531,26 @@ function extractDefs(ctx, schema) {
|
|
|
24531
24531
|
return;
|
|
24532
24532
|
const idToSchema = /* @__PURE__ */ new Map();
|
|
24533
24533
|
for (const entry of ctx.seen.entries()) {
|
|
24534
|
-
const
|
|
24535
|
-
if (
|
|
24536
|
-
const existing = idToSchema.get(
|
|
24534
|
+
const id2 = ctx.metadataRegistry.get(entry[0])?.id;
|
|
24535
|
+
if (id2) {
|
|
24536
|
+
const existing = idToSchema.get(id2);
|
|
24537
24537
|
if (existing && existing !== entry[0]) {
|
|
24538
|
-
throw new Error(`Duplicate schema id "${
|
|
24538
|
+
throw new Error(`Duplicate schema id "${id2}" detected during JSON Schema conversion. Two different schemas cannot share the same id when converted together.`);
|
|
24539
24539
|
}
|
|
24540
|
-
idToSchema.set(
|
|
24540
|
+
idToSchema.set(id2, entry[0]);
|
|
24541
24541
|
}
|
|
24542
24542
|
}
|
|
24543
24543
|
const makeURI = (entry) => {
|
|
24544
24544
|
const defsSegment = ctx.target === "draft-2020-12" ? "$defs" : "definitions";
|
|
24545
24545
|
if (ctx.external) {
|
|
24546
24546
|
const externalId = ctx.external.registry.get(entry[0])?.id;
|
|
24547
|
-
const uriGenerator = ctx.external.uri ?? ((
|
|
24547
|
+
const uriGenerator = ctx.external.uri ?? ((id3) => id3);
|
|
24548
24548
|
if (externalId) {
|
|
24549
24549
|
return { ref: uriGenerator(externalId) };
|
|
24550
24550
|
}
|
|
24551
|
-
const
|
|
24552
|
-
entry[1].defId =
|
|
24553
|
-
return { defId:
|
|
24551
|
+
const id2 = entry[1].defId ?? entry[1].schema.id ?? `schema${ctx.counter++}`;
|
|
24552
|
+
entry[1].defId = id2;
|
|
24553
|
+
return { defId: id2, ref: `${uriGenerator("__shared")}#/${defsSegment}/${encodeJSONPointerSegment(id2)}` };
|
|
24554
24554
|
}
|
|
24555
24555
|
const uriPrefix = `#`;
|
|
24556
24556
|
const defUriPrefix = `${uriPrefix}/${defsSegment}/`;
|
|
@@ -24598,8 +24598,8 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
24598
24598
|
continue;
|
|
24599
24599
|
}
|
|
24600
24600
|
}
|
|
24601
|
-
const
|
|
24602
|
-
if (
|
|
24601
|
+
const id2 = ctx.metadataRegistry.get(entry[0])?.id;
|
|
24602
|
+
if (id2) {
|
|
24603
24603
|
extractToDef(entry);
|
|
24604
24604
|
continue;
|
|
24605
24605
|
}
|
|
@@ -24832,10 +24832,10 @@ function finalize(ctx, schema) {
|
|
|
24832
24832
|
} else {
|
|
24833
24833
|
}
|
|
24834
24834
|
if (ctx.external?.uri) {
|
|
24835
|
-
const
|
|
24836
|
-
if (!
|
|
24835
|
+
const id2 = ctx.external.registry.get(schema)?.id;
|
|
24836
|
+
if (!id2)
|
|
24837
24837
|
throw new Error("Schema is missing an `id` property");
|
|
24838
|
-
result.$id = ctx.external.uri(
|
|
24838
|
+
result.$id = ctx.external.uri(id2);
|
|
24839
24839
|
}
|
|
24840
24840
|
assignProps(result, root.defId ? root.schema : root.def ?? root.schema);
|
|
24841
24841
|
const rootMetaId = ctx.metadataRegistry.get(schema)?.id;
|
|
@@ -25441,7 +25441,7 @@ function stringifyKeyNames(bySchema, json3, visited) {
|
|
|
25441
25441
|
const values = json3.enum ?? (json3.const !== void 0 ? [json3.const] : void 0);
|
|
25442
25442
|
if (!numericType && !values?.some((v) => typeof v === "number"))
|
|
25443
25443
|
return json3;
|
|
25444
|
-
const { minimum, maximum, exclusiveMinimum, exclusiveMaximum, multipleOf, format, id, ...rest } = json3;
|
|
25444
|
+
const { minimum, maximum, exclusiveMinimum, exclusiveMaximum, multipleOf, format, id: id2, ...rest } = json3;
|
|
25445
25445
|
if (rest.enum)
|
|
25446
25446
|
rest.enum = rest.enum.map((v) => typeof v === "number" ? String(v) : v);
|
|
25447
25447
|
else if (typeof rest.const === "number")
|
|
@@ -27802,12 +27802,12 @@ function containsRef(value) {
|
|
|
27802
27802
|
return value.some(containsRef);
|
|
27803
27803
|
if (typeof value.$ref === "string")
|
|
27804
27804
|
return true;
|
|
27805
|
-
return Object.entries(value).some(([key,
|
|
27805
|
+
return Object.entries(value).some(([key, sub28]) => {
|
|
27806
27806
|
if (SCHEMA_KEYWORDS.has(key))
|
|
27807
|
-
return containsRef(
|
|
27808
|
-
if (!SCHEMA_MAP_KEYWORDS.has(key) || typeof
|
|
27807
|
+
return containsRef(sub28);
|
|
27808
|
+
if (!SCHEMA_MAP_KEYWORDS.has(key) || typeof sub28 !== "object" || sub28 === null)
|
|
27809
27809
|
return false;
|
|
27810
|
-
return Object.values(
|
|
27810
|
+
return Object.values(sub28).some(containsRef);
|
|
27811
27811
|
});
|
|
27812
27812
|
}
|
|
27813
27813
|
function plural(n) {
|
|
@@ -30750,28 +30750,28 @@ data:
|
|
|
30750
30750
|
}
|
|
30751
30751
|
if (isJSONRPCResultResponse(message) || isJSONRPCErrorResponse(message)) {
|
|
30752
30752
|
this._requestResponseMap.set(requestId, message);
|
|
30753
|
-
const relatedIds = Array.from(this._requestToStreamMapping.entries()).filter(([_, sid]) => sid === streamId).map(([
|
|
30754
|
-
const allResponsesReady = relatedIds.every((
|
|
30753
|
+
const relatedIds = Array.from(this._requestToStreamMapping.entries()).filter(([_, sid]) => sid === streamId).map(([id2]) => id2);
|
|
30754
|
+
const allResponsesReady = relatedIds.every((id2) => this._requestResponseMap.has(id2));
|
|
30755
30755
|
if (allResponsesReady) {
|
|
30756
30756
|
if (!stream) {
|
|
30757
30757
|
if (this._closed) {
|
|
30758
|
-
for (const
|
|
30759
|
-
this._requestResponseMap.delete(
|
|
30760
|
-
this._requestToStreamMapping.delete(
|
|
30758
|
+
for (const id2 of relatedIds) {
|
|
30759
|
+
this._requestResponseMap.delete(id2);
|
|
30760
|
+
this._requestToStreamMapping.delete(id2);
|
|
30761
30761
|
}
|
|
30762
30762
|
return;
|
|
30763
30763
|
}
|
|
30764
30764
|
if (!this._enableJsonResponse && this._eventStore && this._resumableStreams.has(streamId)) {
|
|
30765
|
-
for (const
|
|
30766
|
-
this._requestResponseMap.delete(
|
|
30767
|
-
this._requestToStreamMapping.delete(
|
|
30765
|
+
for (const id2 of relatedIds) {
|
|
30766
|
+
this._requestResponseMap.delete(id2);
|
|
30767
|
+
this._requestToStreamMapping.delete(id2);
|
|
30768
30768
|
}
|
|
30769
30769
|
this._resumableStreams.delete(streamId);
|
|
30770
30770
|
return;
|
|
30771
30771
|
}
|
|
30772
|
-
for (const
|
|
30773
|
-
this._requestResponseMap.delete(
|
|
30774
|
-
this._requestToStreamMapping.delete(
|
|
30772
|
+
for (const id2 of relatedIds) {
|
|
30773
|
+
this._requestResponseMap.delete(id2);
|
|
30774
|
+
this._requestToStreamMapping.delete(id2);
|
|
30775
30775
|
}
|
|
30776
30776
|
throw new Error(`No connection established for request ID: ${String(requestId)}`);
|
|
30777
30777
|
}
|
|
@@ -30782,7 +30782,7 @@ data:
|
|
|
30782
30782
|
if (this.sessionId !== void 0) {
|
|
30783
30783
|
headers["mcp-session-id"] = this.sessionId;
|
|
30784
30784
|
}
|
|
30785
|
-
const responses = relatedIds.map((
|
|
30785
|
+
const responses = relatedIds.map((id2) => this._requestResponseMap.get(id2));
|
|
30786
30786
|
if (responses.length === 1) {
|
|
30787
30787
|
stream.resolveJson(new Response(JSON.stringify(responses[0]), { status: 200, headers }));
|
|
30788
30788
|
} else {
|
|
@@ -30791,9 +30791,9 @@ data:
|
|
|
30791
30791
|
} else {
|
|
30792
30792
|
stream.cleanup();
|
|
30793
30793
|
}
|
|
30794
|
-
for (const
|
|
30795
|
-
this._requestResponseMap.delete(
|
|
30796
|
-
this._requestToStreamMapping.delete(
|
|
30794
|
+
for (const id2 of relatedIds) {
|
|
30795
|
+
this._requestResponseMap.delete(id2);
|
|
30796
|
+
this._requestToStreamMapping.delete(id2);
|
|
30797
30797
|
}
|
|
30798
30798
|
this._resumableStreams.delete(streamId);
|
|
30799
30799
|
}
|
|
@@ -31063,8 +31063,8 @@ var ZodError2 = class _ZodError extends Error {
|
|
|
31063
31063
|
constructor(issues) {
|
|
31064
31064
|
super();
|
|
31065
31065
|
this.issues = [];
|
|
31066
|
-
this.addIssue = (
|
|
31067
|
-
this.issues = [...this.issues,
|
|
31066
|
+
this.addIssue = (sub28) => {
|
|
31067
|
+
this.issues = [...this.issues, sub28];
|
|
31068
31068
|
};
|
|
31069
31069
|
this.addIssues = (subs = []) => {
|
|
31070
31070
|
this.issues = [...this.issues, ...subs];
|
|
@@ -31146,13 +31146,13 @@ var ZodError2 = class _ZodError extends Error {
|
|
|
31146
31146
|
flatten(mapper = (issue2) => issue2.message) {
|
|
31147
31147
|
const fieldErrors = /* @__PURE__ */ Object.create(null);
|
|
31148
31148
|
const formErrors = [];
|
|
31149
|
-
for (const
|
|
31150
|
-
if (
|
|
31151
|
-
const firstEl =
|
|
31149
|
+
for (const sub28 of this.issues) {
|
|
31150
|
+
if (sub28.path.length > 0) {
|
|
31151
|
+
const firstEl = sub28.path[0];
|
|
31152
31152
|
fieldErrors[firstEl] = fieldErrors[firstEl] || [];
|
|
31153
|
-
fieldErrors[firstEl].push(mapper(
|
|
31153
|
+
fieldErrors[firstEl].push(mapper(sub28));
|
|
31154
31154
|
} else {
|
|
31155
|
-
formErrors.push(mapper(
|
|
31155
|
+
formErrors.push(mapper(sub28));
|
|
31156
31156
|
}
|
|
31157
31157
|
}
|
|
31158
31158
|
return { formErrors, fieldErrors };
|
|
@@ -32334,14 +32334,14 @@ var ZodString2 = class _ZodString2 extends ZodType2 {
|
|
|
32334
32334
|
return !!this._def.checks.find((ch) => ch.kind === "base64url");
|
|
32335
32335
|
}
|
|
32336
32336
|
get minLength() {
|
|
32337
|
-
let
|
|
32337
|
+
let min7 = null;
|
|
32338
32338
|
for (const ch of this._def.checks) {
|
|
32339
32339
|
if (ch.kind === "min") {
|
|
32340
|
-
if (
|
|
32341
|
-
|
|
32340
|
+
if (min7 === null || ch.value > min7)
|
|
32341
|
+
min7 = ch.value;
|
|
32342
32342
|
}
|
|
32343
32343
|
}
|
|
32344
|
-
return
|
|
32344
|
+
return min7;
|
|
32345
32345
|
}
|
|
32346
32346
|
get maxLength() {
|
|
32347
32347
|
let max2 = null;
|
|
@@ -32555,14 +32555,14 @@ var ZodNumber2 = class _ZodNumber extends ZodType2 {
|
|
|
32555
32555
|
});
|
|
32556
32556
|
}
|
|
32557
32557
|
get minValue() {
|
|
32558
|
-
let
|
|
32558
|
+
let min7 = null;
|
|
32559
32559
|
for (const ch of this._def.checks) {
|
|
32560
32560
|
if (ch.kind === "min") {
|
|
32561
|
-
if (
|
|
32562
|
-
|
|
32561
|
+
if (min7 === null || ch.value > min7)
|
|
32562
|
+
min7 = ch.value;
|
|
32563
32563
|
}
|
|
32564
32564
|
}
|
|
32565
|
-
return
|
|
32565
|
+
return min7;
|
|
32566
32566
|
}
|
|
32567
32567
|
get maxValue() {
|
|
32568
32568
|
let max2 = null;
|
|
@@ -32579,19 +32579,19 @@ var ZodNumber2 = class _ZodNumber extends ZodType2 {
|
|
|
32579
32579
|
}
|
|
32580
32580
|
get isFinite() {
|
|
32581
32581
|
let max2 = null;
|
|
32582
|
-
let
|
|
32582
|
+
let min7 = null;
|
|
32583
32583
|
for (const ch of this._def.checks) {
|
|
32584
32584
|
if (ch.kind === "finite" || ch.kind === "int" || ch.kind === "multipleOf") {
|
|
32585
32585
|
return true;
|
|
32586
32586
|
} else if (ch.kind === "min") {
|
|
32587
|
-
if (
|
|
32588
|
-
|
|
32587
|
+
if (min7 === null || ch.value > min7)
|
|
32588
|
+
min7 = ch.value;
|
|
32589
32589
|
} else if (ch.kind === "max") {
|
|
32590
32590
|
if (max2 === null || ch.value < max2)
|
|
32591
32591
|
max2 = ch.value;
|
|
32592
32592
|
}
|
|
32593
32593
|
}
|
|
32594
|
-
return Number.isFinite(
|
|
32594
|
+
return Number.isFinite(min7) && Number.isFinite(max2);
|
|
32595
32595
|
}
|
|
32596
32596
|
};
|
|
32597
32597
|
ZodNumber2.create = (params) => {
|
|
@@ -32746,14 +32746,14 @@ var ZodBigInt2 = class _ZodBigInt extends ZodType2 {
|
|
|
32746
32746
|
});
|
|
32747
32747
|
}
|
|
32748
32748
|
get minValue() {
|
|
32749
|
-
let
|
|
32749
|
+
let min7 = null;
|
|
32750
32750
|
for (const ch of this._def.checks) {
|
|
32751
32751
|
if (ch.kind === "min") {
|
|
32752
|
-
if (
|
|
32753
|
-
|
|
32752
|
+
if (min7 === null || ch.value > min7)
|
|
32753
|
+
min7 = ch.value;
|
|
32754
32754
|
}
|
|
32755
32755
|
}
|
|
32756
|
-
return
|
|
32756
|
+
return min7;
|
|
32757
32757
|
}
|
|
32758
32758
|
get maxValue() {
|
|
32759
32759
|
let max2 = null;
|
|
@@ -32880,14 +32880,14 @@ var ZodDate2 = class _ZodDate extends ZodType2 {
|
|
|
32880
32880
|
});
|
|
32881
32881
|
}
|
|
32882
32882
|
get minDate() {
|
|
32883
|
-
let
|
|
32883
|
+
let min7 = null;
|
|
32884
32884
|
for (const ch of this._def.checks) {
|
|
32885
32885
|
if (ch.kind === "min") {
|
|
32886
|
-
if (
|
|
32887
|
-
|
|
32886
|
+
if (min7 === null || ch.value > min7)
|
|
32887
|
+
min7 = ch.value;
|
|
32888
32888
|
}
|
|
32889
32889
|
}
|
|
32890
|
-
return
|
|
32890
|
+
return min7 != null ? new Date(min7) : null;
|
|
32891
32891
|
}
|
|
32892
32892
|
get maxDate() {
|
|
32893
32893
|
let max2 = null;
|
|
@@ -37488,7 +37488,7 @@ var ExperimentalServerTasks = class {
|
|
|
37488
37488
|
if (hasPreviousToolUse) {
|
|
37489
37489
|
const toolUseIds = new Set(previousContent.filter((c2) => c2.type === "tool_use").map((c2) => c2.id));
|
|
37490
37490
|
const toolResultIds = new Set(lastContent.filter((c2) => c2.type === "tool_result").map((c2) => c2.toolUseId));
|
|
37491
|
-
if (toolUseIds.size !== toolResultIds.size || ![...toolUseIds].every((
|
|
37491
|
+
if (toolUseIds.size !== toolResultIds.size || ![...toolUseIds].every((id2) => toolResultIds.has(id2))) {
|
|
37492
37492
|
throw new Error("ids of tool_result blocks and tool_use blocks from previous message do not match");
|
|
37493
37493
|
}
|
|
37494
37494
|
}
|
|
@@ -37913,7 +37913,7 @@ var Server = class extends Protocol {
|
|
|
37913
37913
|
if (hasPreviousToolUse) {
|
|
37914
37914
|
const toolUseIds = new Set(previousContent.filter((c2) => c2.type === "tool_use").map((c2) => c2.id));
|
|
37915
37915
|
const toolResultIds = new Set(lastContent.filter((c2) => c2.type === "tool_result").map((c2) => c2.toolUseId));
|
|
37916
|
-
if (toolUseIds.size !== toolResultIds.size || ![...toolUseIds].every((
|
|
37916
|
+
if (toolUseIds.size !== toolResultIds.size || ![...toolUseIds].every((id2) => toolResultIds.has(id2))) {
|
|
37917
37917
|
throw new Error("ids of tool_result blocks and tool_use blocks from previous message do not match");
|
|
37918
37918
|
}
|
|
37919
37919
|
}
|
|
@@ -39175,23 +39175,23 @@ function divRound(n, d3, mode) {
|
|
|
39175
39175
|
const r = n % d3;
|
|
39176
39176
|
if (r === 0n)
|
|
39177
39177
|
return q;
|
|
39178
|
-
const
|
|
39178
|
+
const neg3 = n < 0n;
|
|
39179
39179
|
const twiceAbsRem = (r < 0n ? -r : r) * 2n;
|
|
39180
39180
|
switch (mode) {
|
|
39181
39181
|
case "floor":
|
|
39182
|
-
return
|
|
39182
|
+
return neg3 ? q - 1n : q;
|
|
39183
39183
|
case "ceil":
|
|
39184
|
-
return
|
|
39184
|
+
return neg3 ? q : q + 1n;
|
|
39185
39185
|
case "half-up":
|
|
39186
39186
|
if (twiceAbsRem >= d3)
|
|
39187
|
-
return
|
|
39187
|
+
return neg3 ? q - 1n : q + 1n;
|
|
39188
39188
|
return q;
|
|
39189
39189
|
case "half-even":
|
|
39190
39190
|
if (twiceAbsRem > d3)
|
|
39191
|
-
return
|
|
39191
|
+
return neg3 ? q - 1n : q + 1n;
|
|
39192
39192
|
if (twiceAbsRem < d3)
|
|
39193
39193
|
return q;
|
|
39194
|
-
return q % 2n === 0n ? q :
|
|
39194
|
+
return q % 2n === 0n ? q : neg3 ? q - 1n : q + 1n;
|
|
39195
39195
|
}
|
|
39196
39196
|
}
|
|
39197
39197
|
function mulRate(cents, rate2, mode) {
|
|
@@ -39418,8 +39418,8 @@ function sha256Hex(input2) {
|
|
|
39418
39418
|
function hashOf(value) {
|
|
39419
39419
|
return `sha256:${sha256Hex(canonical(value))}`;
|
|
39420
39420
|
}
|
|
39421
|
-
function ruleHash(
|
|
39422
|
-
return hashOf(
|
|
39421
|
+
function ruleHash(rule2) {
|
|
39422
|
+
return hashOf(rule2);
|
|
39423
39423
|
}
|
|
39424
39424
|
function merkleRoot(rules, facts2 = []) {
|
|
39425
39425
|
const ordered = [...rules].sort((a, b) => a.id.localeCompare(b.id) || a.version - b.version);
|
|
@@ -39551,60 +39551,60 @@ function loadCorpus(input2) {
|
|
|
39551
39551
|
const factById2 = /* @__PURE__ */ new Map();
|
|
39552
39552
|
const overriders = /* @__PURE__ */ new Map();
|
|
39553
39553
|
const contributors2 = /* @__PURE__ */ new Map();
|
|
39554
|
-
for (const
|
|
39555
|
-
if (factById2.has(
|
|
39556
|
-
issues.push(`duplicate fact id "${
|
|
39557
|
-
factById2.set(
|
|
39558
|
-
if (
|
|
39559
|
-
issues.push(`enum fact "${
|
|
39554
|
+
for (const fact47 of input2.facts) {
|
|
39555
|
+
if (factById2.has(fact47.id))
|
|
39556
|
+
issues.push(`duplicate fact id "${fact47.id}"`);
|
|
39557
|
+
factById2.set(fact47.id, fact47);
|
|
39558
|
+
if (fact47.type === "enum" && !fact47.enumValues?.length) {
|
|
39559
|
+
issues.push(`enum fact "${fact47.id}" must declare enumValues`);
|
|
39560
39560
|
}
|
|
39561
39561
|
}
|
|
39562
39562
|
const knownRuleIds = byIdRefChecker(input2);
|
|
39563
39563
|
const contributorIds = new Set(input2.rules.filter((r) => r.contributesTo !== void 0).map((r) => r.id));
|
|
39564
39564
|
const seenVersions = /* @__PURE__ */ new Set();
|
|
39565
|
-
for (const
|
|
39566
|
-
const key = `${
|
|
39565
|
+
for (const rule2 of input2.rules) {
|
|
39566
|
+
const key = `${rule2.id}@${rule2.version}`;
|
|
39567
39567
|
if (seenVersions.has(key))
|
|
39568
39568
|
issues.push(`duplicate rule version "${key}"`);
|
|
39569
39569
|
seenVersions.add(key);
|
|
39570
|
-
if (!ISO_DATE.test(
|
|
39571
|
-
issues.push(`rule "${key}": invalid effectiveFrom "${
|
|
39570
|
+
if (!ISO_DATE.test(rule2.effectiveFrom)) {
|
|
39571
|
+
issues.push(`rule "${key}": invalid effectiveFrom "${rule2.effectiveFrom}"`);
|
|
39572
39572
|
}
|
|
39573
|
-
if (
|
|
39574
|
-
if (!ISO_DATE.test(
|
|
39575
|
-
issues.push(`rule "${key}": invalid effectiveTo "${
|
|
39576
|
-
} else if (
|
|
39573
|
+
if (rule2.effectiveTo !== void 0) {
|
|
39574
|
+
if (!ISO_DATE.test(rule2.effectiveTo)) {
|
|
39575
|
+
issues.push(`rule "${key}": invalid effectiveTo "${rule2.effectiveTo}"`);
|
|
39576
|
+
} else if (rule2.effectiveTo <= rule2.effectiveFrom) {
|
|
39577
39577
|
issues.push(`rule "${key}": empty validity window`);
|
|
39578
39578
|
}
|
|
39579
39579
|
}
|
|
39580
|
-
const list = byId.get(
|
|
39581
|
-
list.push(
|
|
39582
|
-
byId.set(
|
|
39583
|
-
if (
|
|
39584
|
-
const list2 = overriders.get(
|
|
39585
|
-
list2.push(
|
|
39586
|
-
overriders.set(
|
|
39587
|
-
if (
|
|
39580
|
+
const list = byId.get(rule2.id) ?? [];
|
|
39581
|
+
list.push(rule2);
|
|
39582
|
+
byId.set(rule2.id, list);
|
|
39583
|
+
if (rule2.overrides) {
|
|
39584
|
+
const list2 = overriders.get(rule2.overrides.ruleId) ?? [];
|
|
39585
|
+
list2.push(rule2);
|
|
39586
|
+
overriders.set(rule2.overrides.ruleId, list2);
|
|
39587
|
+
if (rule2.overrides.priority <= 0) {
|
|
39588
39588
|
issues.push(`rule "${key}": override priority must be > 0 (base rule has implicit priority 0)`);
|
|
39589
39589
|
}
|
|
39590
|
-
if (!
|
|
39590
|
+
if (!rule2.applicability) {
|
|
39591
39591
|
issues.push(`rule "${key}": an override must declare an applicability guard`);
|
|
39592
39592
|
}
|
|
39593
39593
|
}
|
|
39594
|
-
if (
|
|
39595
|
-
const list2 = contributors2.get(
|
|
39596
|
-
list2.push(
|
|
39597
|
-
contributors2.set(
|
|
39598
|
-
if (
|
|
39594
|
+
if (rule2.contributesTo !== void 0) {
|
|
39595
|
+
const list2 = contributors2.get(rule2.contributesTo) ?? [];
|
|
39596
|
+
list2.push(rule2);
|
|
39597
|
+
contributors2.set(rule2.contributesTo, list2);
|
|
39598
|
+
if (rule2.output.type !== "money")
|
|
39599
39599
|
issues.push(`rule "${key}": a contribution must output money`);
|
|
39600
|
-
if (
|
|
39600
|
+
if (rule2.applicability)
|
|
39601
39601
|
issues.push(`rule "${key}": a contribution cannot declare an applicability guard`);
|
|
39602
|
-
if (
|
|
39602
|
+
if (rule2.overrides)
|
|
39603
39603
|
issues.push(`rule "${key}": a rule cannot both override and contribute`);
|
|
39604
|
-
if (
|
|
39604
|
+
if (rule2.contributesTo === rule2.id)
|
|
39605
39605
|
issues.push(`rule "${key}" contributes to itself`);
|
|
39606
39606
|
}
|
|
39607
|
-
validateExpressions(
|
|
39607
|
+
validateExpressions(rule2, knownRuleIds, contributorIds, factById2, issues);
|
|
39608
39608
|
}
|
|
39609
39609
|
for (const [targetId] of contributors2) {
|
|
39610
39610
|
const targets = byId.get(targetId);
|
|
@@ -39613,13 +39613,13 @@ function loadCorpus(input2) {
|
|
|
39613
39613
|
else if (targets[0].output.type !== "money")
|
|
39614
39614
|
issues.push(`contribution target "${targetId}" is not a money rule`);
|
|
39615
39615
|
}
|
|
39616
|
-
for (const [
|
|
39616
|
+
for (const [id2, versions2] of byId) {
|
|
39617
39617
|
const sorted = [...versions2].sort((a, b) => a.effectiveFrom.localeCompare(b.effectiveFrom));
|
|
39618
39618
|
for (let i = 0; i + 1 < sorted.length; i++) {
|
|
39619
39619
|
const cur = sorted[i];
|
|
39620
39620
|
const next = sorted[i + 1];
|
|
39621
39621
|
if (cur.effectiveTo === void 0 || next.effectiveFrom < cur.effectiveTo) {
|
|
39622
|
-
issues.push(`rule "${
|
|
39622
|
+
issues.push(`rule "${id2}": overlapping validity windows (v${cur.version} and v${next.version})`);
|
|
39623
39623
|
}
|
|
39624
39624
|
}
|
|
39625
39625
|
}
|
|
@@ -39631,23 +39631,23 @@ function loadCorpus(input2) {
|
|
|
39631
39631
|
}
|
|
39632
39632
|
const targetType = targets[0].output.type;
|
|
39633
39633
|
const prios = /* @__PURE__ */ new Map();
|
|
39634
|
-
for (const
|
|
39635
|
-
if (
|
|
39636
|
-
issues.push(`rule "${
|
|
39634
|
+
for (const rule2 of list) {
|
|
39635
|
+
if (rule2.output.type !== targetType) {
|
|
39636
|
+
issues.push(`rule "${rule2.id}" overrides "${targetId}" but output type ${rule2.output.type} != ${targetType}`);
|
|
39637
39637
|
}
|
|
39638
|
-
const p =
|
|
39638
|
+
const p = rule2.overrides.priority;
|
|
39639
39639
|
const existing = prios.get(p);
|
|
39640
|
-
if (existing !== void 0 && existing !==
|
|
39641
|
-
issues.push(`rules "${existing}" and "${
|
|
39640
|
+
if (existing !== void 0 && existing !== rule2.id) {
|
|
39641
|
+
issues.push(`rules "${existing}" and "${rule2.id}" both override "${targetId}" at priority ${p}`);
|
|
39642
39642
|
}
|
|
39643
|
-
prios.set(p,
|
|
39643
|
+
prios.set(p, rule2.id);
|
|
39644
39644
|
}
|
|
39645
39645
|
}
|
|
39646
39646
|
if (issues.length > 0)
|
|
39647
39647
|
throw new CorpusValidationError(issues);
|
|
39648
39648
|
const ruleHashes = /* @__PURE__ */ new Map();
|
|
39649
|
-
for (const
|
|
39650
|
-
ruleHashes.set(`${
|
|
39649
|
+
for (const rule2 of input2.rules) {
|
|
39650
|
+
ruleHashes.set(`${rule2.id}@${rule2.version}`, ruleHash(rule2));
|
|
39651
39651
|
}
|
|
39652
39652
|
return {
|
|
39653
39653
|
name: input2.name,
|
|
@@ -39665,11 +39665,11 @@ function loadCorpus(input2) {
|
|
|
39665
39665
|
function byIdRefChecker(input2) {
|
|
39666
39666
|
return new Set(input2.rules.map((r) => r.id));
|
|
39667
39667
|
}
|
|
39668
|
-
function validateExpressions(
|
|
39669
|
-
const key = `${
|
|
39670
|
-
const exprs = [
|
|
39671
|
-
if (
|
|
39672
|
-
exprs.push(
|
|
39668
|
+
function validateExpressions(rule2, knownRuleIds, contributorIds, factById2, issues) {
|
|
39669
|
+
const key = `${rule2.id}@${rule2.version}`;
|
|
39670
|
+
const exprs = [rule2.formula];
|
|
39671
|
+
if (rule2.applicability)
|
|
39672
|
+
exprs.push(rule2.applicability);
|
|
39673
39673
|
for (const root of exprs) {
|
|
39674
39674
|
walkExpr(root, (e) => {
|
|
39675
39675
|
switch (e.kind) {
|
|
@@ -39686,9 +39686,9 @@ function validateExpressions(rule, knownRuleIds, contributorIds, factById2, issu
|
|
|
39686
39686
|
if (!knownRuleIds.has(e.ruleId)) {
|
|
39687
39687
|
issues.push(`rule "${key}" references unknown rule "${e.ruleId}"`);
|
|
39688
39688
|
}
|
|
39689
|
-
for (const
|
|
39690
|
-
if (!contributorIds.has(
|
|
39691
|
-
issues.push(`rule "${key}" excludes "${
|
|
39689
|
+
for (const id2 of e.excluding ?? []) {
|
|
39690
|
+
if (!contributorIds.has(id2)) {
|
|
39691
|
+
issues.push(`rule "${key}" excludes "${id2}", which is not a contributing rule`);
|
|
39692
39692
|
}
|
|
39693
39693
|
}
|
|
39694
39694
|
break;
|
|
@@ -39698,7 +39698,7 @@ function validateExpressions(rule, knownRuleIds, contributorIds, factById2, issu
|
|
|
39698
39698
|
}
|
|
39699
39699
|
break;
|
|
39700
39700
|
case "param":
|
|
39701
|
-
if (!
|
|
39701
|
+
if (!rule2.parameters || !(e.name in rule2.parameters)) {
|
|
39702
39702
|
issues.push(`rule "${key}" references unknown parameter "${e.name}"`);
|
|
39703
39703
|
}
|
|
39704
39704
|
break;
|
|
@@ -39907,17 +39907,17 @@ function evalRule(ruleId, ctx) {
|
|
|
39907
39907
|
}
|
|
39908
39908
|
const contributions = [];
|
|
39909
39909
|
let contributed = 0n;
|
|
39910
|
-
for (const
|
|
39911
|
-
if (ctx.excluded.has(
|
|
39910
|
+
for (const id2 of selectContributors(ctx.corpus, ruleId, ctx.asOf)) {
|
|
39911
|
+
if (ctx.excluded.has(id2))
|
|
39912
39912
|
continue;
|
|
39913
|
-
const c2 = evalRule(
|
|
39913
|
+
const c2 = evalRule(id2, ctx);
|
|
39914
39914
|
if (c2.value === POISON || c2.node === null) {
|
|
39915
39915
|
poisoned = true;
|
|
39916
39916
|
continue;
|
|
39917
39917
|
}
|
|
39918
39918
|
if (!children.includes(c2.node))
|
|
39919
39919
|
children.push(c2.node);
|
|
39920
|
-
contributions.push({ ruleId:
|
|
39920
|
+
contributions.push({ ruleId: id2, value: valueToJSON(c2.value) });
|
|
39921
39921
|
contributed += c2.value.cents;
|
|
39922
39922
|
}
|
|
39923
39923
|
if (poisoned)
|
|
@@ -39976,15 +39976,15 @@ function passExcluding(ctx, ids) {
|
|
|
39976
39976
|
}
|
|
39977
39977
|
return pass;
|
|
39978
39978
|
}
|
|
39979
|
-
function candidateEntry(
|
|
39979
|
+
function candidateEntry(rule2, applicable) {
|
|
39980
39980
|
return {
|
|
39981
|
-
ruleId:
|
|
39982
|
-
version:
|
|
39983
|
-
priority:
|
|
39981
|
+
ruleId: rule2.id,
|
|
39982
|
+
version: rule2.version,
|
|
39983
|
+
priority: rule2.overrides?.priority ?? 0,
|
|
39984
39984
|
applicable
|
|
39985
39985
|
};
|
|
39986
39986
|
}
|
|
39987
|
-
function evalExpr(expr,
|
|
39987
|
+
function evalExpr(expr, rule2, ctx, children) {
|
|
39988
39988
|
switch (expr.kind) {
|
|
39989
39989
|
case "money":
|
|
39990
39990
|
return { type: "money", cents: parseCents(expr.cents) };
|
|
@@ -40004,29 +40004,29 @@ function evalExpr(expr, rule, ctx, children) {
|
|
|
40004
40004
|
return value;
|
|
40005
40005
|
}
|
|
40006
40006
|
case "param": {
|
|
40007
|
-
const param28 =
|
|
40007
|
+
const param28 = rule2.parameters?.[expr.name];
|
|
40008
40008
|
if (!param28) {
|
|
40009
|
-
throw new EngineError(`rule "${
|
|
40009
|
+
throw new EngineError(`rule "${rule2.id}" has no parameter "${expr.name}"`);
|
|
40010
40010
|
}
|
|
40011
40011
|
return valueFromJSON({ type: param28.type, value: param28.value });
|
|
40012
40012
|
}
|
|
40013
40013
|
case "add": {
|
|
40014
|
-
const vals = evalAll(expr.args,
|
|
40014
|
+
const vals = evalAll(expr.args, rule2, ctx, children);
|
|
40015
40015
|
if (vals === POISON)
|
|
40016
40016
|
return POISON;
|
|
40017
|
-
return numericFold(vals,
|
|
40017
|
+
return numericFold(vals, rule2, "add", (acc, v) => acc + v);
|
|
40018
40018
|
}
|
|
40019
40019
|
case "sub": {
|
|
40020
|
-
const vals = evalAll([expr.left, expr.right],
|
|
40020
|
+
const vals = evalAll([expr.left, expr.right], rule2, ctx, children);
|
|
40021
40021
|
if (vals === POISON)
|
|
40022
40022
|
return POISON;
|
|
40023
|
-
return numericFold(vals,
|
|
40023
|
+
return numericFold(vals, rule2, "sub", (acc, v) => acc - v);
|
|
40024
40024
|
}
|
|
40025
40025
|
case "mulRate": {
|
|
40026
|
-
const base = evalExpr(expr.base,
|
|
40026
|
+
const base = evalExpr(expr.base, rule2, ctx, children);
|
|
40027
40027
|
if (base === POISON)
|
|
40028
40028
|
return POISON;
|
|
40029
|
-
expectType(base, "money",
|
|
40029
|
+
expectType(base, "money", rule2, "mulRate.base");
|
|
40030
40030
|
const rate2 = {
|
|
40031
40031
|
num: parseInt_(expr.rate.num),
|
|
40032
40032
|
den: parseInt_(expr.rate.den)
|
|
@@ -40037,12 +40037,12 @@ function evalExpr(expr, rule, ctx, children) {
|
|
|
40037
40037
|
};
|
|
40038
40038
|
}
|
|
40039
40039
|
case "mulInt": {
|
|
40040
|
-
const vals = evalAll([expr.base, expr.count],
|
|
40040
|
+
const vals = evalAll([expr.base, expr.count], rule2, ctx, children);
|
|
40041
40041
|
if (vals === POISON)
|
|
40042
40042
|
return POISON;
|
|
40043
40043
|
const [base, count] = vals;
|
|
40044
|
-
expectType(base, "money",
|
|
40045
|
-
expectType(count, "int",
|
|
40044
|
+
expectType(base, "money", rule2, "mulInt.base");
|
|
40045
|
+
expectType(count, "int", rule2, "mulInt.count");
|
|
40046
40046
|
return {
|
|
40047
40047
|
type: "money",
|
|
40048
40048
|
cents: base.cents * count.value
|
|
@@ -40050,79 +40050,79 @@ function evalExpr(expr, rule, ctx, children) {
|
|
|
40050
40050
|
}
|
|
40051
40051
|
case "min":
|
|
40052
40052
|
case "max": {
|
|
40053
|
-
const vals = evalAll(expr.args,
|
|
40053
|
+
const vals = evalAll(expr.args, rule2, ctx, children);
|
|
40054
40054
|
if (vals === POISON)
|
|
40055
40055
|
return POISON;
|
|
40056
40056
|
const pick2 = expr.kind === "min" ? (a, b) => b < a ? b : a : (a, b) => b > a ? b : a;
|
|
40057
|
-
return numericFold(vals,
|
|
40057
|
+
return numericFold(vals, rule2, expr.kind, pick2);
|
|
40058
40058
|
}
|
|
40059
40059
|
case "max0": {
|
|
40060
|
-
const v = evalExpr(expr.arg,
|
|
40060
|
+
const v = evalExpr(expr.arg, rule2, ctx, children);
|
|
40061
40061
|
if (v === POISON)
|
|
40062
40062
|
return POISON;
|
|
40063
|
-
expectType(v, "money",
|
|
40063
|
+
expectType(v, "money", rule2, "max0");
|
|
40064
40064
|
return { type: "money", cents: max0(v.cents) };
|
|
40065
40065
|
}
|
|
40066
40066
|
case "clamp": {
|
|
40067
|
-
const vals = evalAll([expr.value, expr.lo, expr.hi],
|
|
40067
|
+
const vals = evalAll([expr.value, expr.lo, expr.hi], rule2, ctx, children);
|
|
40068
40068
|
if (vals === POISON)
|
|
40069
40069
|
return POISON;
|
|
40070
40070
|
const [v, lo, hi] = vals.map((x) => {
|
|
40071
|
-
expectType(x, "money",
|
|
40071
|
+
expectType(x, "money", rule2, "clamp");
|
|
40072
40072
|
return x.cents;
|
|
40073
40073
|
});
|
|
40074
40074
|
const clamped = v < lo ? lo : v > hi ? hi : v;
|
|
40075
40075
|
return { type: "money", cents: clamped };
|
|
40076
40076
|
}
|
|
40077
40077
|
case "roundToDollar": {
|
|
40078
|
-
const v = evalExpr(expr.value,
|
|
40078
|
+
const v = evalExpr(expr.value, rule2, ctx, children);
|
|
40079
40079
|
if (v === POISON)
|
|
40080
40080
|
return POISON;
|
|
40081
|
-
expectType(v, "money",
|
|
40081
|
+
expectType(v, "money", rule2, "roundToDollar");
|
|
40082
40082
|
return {
|
|
40083
40083
|
type: "money",
|
|
40084
40084
|
cents: roundToDollar(v.cents, expr.mode)
|
|
40085
40085
|
};
|
|
40086
40086
|
}
|
|
40087
40087
|
case "mulDiv": {
|
|
40088
|
-
const vals = evalAll([expr.a, expr.b, expr.c],
|
|
40088
|
+
const vals = evalAll([expr.a, expr.b, expr.c], rule2, ctx, children);
|
|
40089
40089
|
if (vals === POISON)
|
|
40090
40090
|
return POISON;
|
|
40091
40091
|
const [a, b, c2] = vals.map((x) => {
|
|
40092
|
-
expectType(x, "money",
|
|
40092
|
+
expectType(x, "money", rule2, "mulDiv");
|
|
40093
40093
|
return x.cents;
|
|
40094
40094
|
});
|
|
40095
40095
|
if (c2 === 0n) {
|
|
40096
|
-
throw new EngineError(`rule "${
|
|
40096
|
+
throw new EngineError(`rule "${rule2.id}": mulDiv division by zero`);
|
|
40097
40097
|
}
|
|
40098
40098
|
return { type: "money", cents: divRound(a * b, c2, expr.round) };
|
|
40099
40099
|
}
|
|
40100
40100
|
case "unsupported":
|
|
40101
|
-
throw new NotModeledError(
|
|
40101
|
+
throw new NotModeledError(rule2.id, expr.reason);
|
|
40102
40102
|
case "stepUnits": {
|
|
40103
|
-
const v = evalExpr(expr.value,
|
|
40103
|
+
const v = evalExpr(expr.value, rule2, ctx, children);
|
|
40104
40104
|
if (v === POISON)
|
|
40105
40105
|
return POISON;
|
|
40106
|
-
expectType(v, "money",
|
|
40106
|
+
expectType(v, "money", rule2, "stepUnits");
|
|
40107
40107
|
return {
|
|
40108
40108
|
type: "int",
|
|
40109
40109
|
value: stepUnits(v.cents, parseCents(expr.unitCents), expr.mode)
|
|
40110
40110
|
};
|
|
40111
40111
|
}
|
|
40112
40112
|
case "cmp": {
|
|
40113
|
-
const vals = evalAll([expr.left, expr.right],
|
|
40113
|
+
const vals = evalAll([expr.left, expr.right], rule2, ctx, children);
|
|
40114
40114
|
if (vals === POISON)
|
|
40115
40115
|
return POISON;
|
|
40116
40116
|
const [l, r] = vals;
|
|
40117
40117
|
if (l.type !== r.type) {
|
|
40118
|
-
throw new EngineError(`rule "${
|
|
40118
|
+
throw new EngineError(`rule "${rule2.id}": cmp between ${l.type} and ${r.type}`);
|
|
40119
40119
|
}
|
|
40120
40120
|
if (expr.op === "eq" || expr.op === "ne") {
|
|
40121
40121
|
const eq3 = canonicalScalar(l) === canonicalScalar(r);
|
|
40122
40122
|
return { type: "bool", value: expr.op === "eq" ? eq3 : !eq3 };
|
|
40123
40123
|
}
|
|
40124
|
-
const ln = numericOf(l,
|
|
40125
|
-
const rn = numericOf(r,
|
|
40124
|
+
const ln = numericOf(l, rule2, "cmp");
|
|
40125
|
+
const rn = numericOf(r, rule2, "cmp");
|
|
40126
40126
|
const result = expr.op === "lt" ? ln < rn : expr.op === "le" ? ln <= rn : expr.op === "gt" ? ln > rn : ln >= rn;
|
|
40127
40127
|
return { type: "bool", value: result };
|
|
40128
40128
|
}
|
|
@@ -40131,12 +40131,12 @@ function evalExpr(expr, rule, ctx, children) {
|
|
|
40131
40131
|
const decider = expr.kind === "and" ? false : true;
|
|
40132
40132
|
let sawPoison = false;
|
|
40133
40133
|
for (const arg of expr.args) {
|
|
40134
|
-
const v = evalExpr(arg,
|
|
40134
|
+
const v = evalExpr(arg, rule2, ctx, children);
|
|
40135
40135
|
if (v === POISON) {
|
|
40136
40136
|
sawPoison = true;
|
|
40137
40137
|
continue;
|
|
40138
40138
|
}
|
|
40139
|
-
expectType(v, "bool",
|
|
40139
|
+
expectType(v, "bool", rule2, expr.kind);
|
|
40140
40140
|
if (v.value === decider) {
|
|
40141
40141
|
return { type: "bool", value: decider };
|
|
40142
40142
|
}
|
|
@@ -40146,24 +40146,24 @@ function evalExpr(expr, rule, ctx, children) {
|
|
|
40146
40146
|
return { type: "bool", value: !decider };
|
|
40147
40147
|
}
|
|
40148
40148
|
case "not": {
|
|
40149
|
-
const v = evalExpr(expr.arg,
|
|
40149
|
+
const v = evalExpr(expr.arg, rule2, ctx, children);
|
|
40150
40150
|
if (v === POISON)
|
|
40151
40151
|
return POISON;
|
|
40152
|
-
expectType(v, "bool",
|
|
40152
|
+
expectType(v, "bool", rule2, "not");
|
|
40153
40153
|
return { type: "bool", value: !v.value };
|
|
40154
40154
|
}
|
|
40155
40155
|
case "if": {
|
|
40156
|
-
const cond = evalExpr(expr.cond,
|
|
40156
|
+
const cond = evalExpr(expr.cond, rule2, ctx, children);
|
|
40157
40157
|
if (cond === POISON)
|
|
40158
40158
|
return POISON;
|
|
40159
|
-
expectType(cond, "bool",
|
|
40160
|
-
return evalExpr(cond.value ? expr.then : expr.else,
|
|
40159
|
+
expectType(cond, "bool", rule2, "if.cond");
|
|
40160
|
+
return evalExpr(cond.value ? expr.then : expr.else, rule2, ctx, children);
|
|
40161
40161
|
}
|
|
40162
40162
|
case "brackets": {
|
|
40163
|
-
const base = evalExpr(expr.base,
|
|
40163
|
+
const base = evalExpr(expr.base, rule2, ctx, children);
|
|
40164
40164
|
if (base === POISON)
|
|
40165
40165
|
return POISON;
|
|
40166
|
-
expectType(base, "money",
|
|
40166
|
+
expectType(base, "money", rule2, "brackets.base");
|
|
40167
40167
|
const amount = base.cents;
|
|
40168
40168
|
let tax = 0n;
|
|
40169
40169
|
for (let i = 0; i < expr.table.length; i++) {
|
|
@@ -40181,17 +40181,17 @@ function evalExpr(expr, rule, ctx, children) {
|
|
|
40181
40181
|
return { type: "money", cents: tax };
|
|
40182
40182
|
}
|
|
40183
40183
|
case "match": {
|
|
40184
|
-
const on = evalExpr(expr.on,
|
|
40184
|
+
const on = evalExpr(expr.on, rule2, ctx, children);
|
|
40185
40185
|
if (on === POISON)
|
|
40186
40186
|
return POISON;
|
|
40187
|
-
expectType(on, "enum",
|
|
40187
|
+
expectType(on, "enum", rule2, "match.on");
|
|
40188
40188
|
const tag = on.value;
|
|
40189
40189
|
const found = expr.cases.find((c2) => c2.when === tag);
|
|
40190
40190
|
if (found)
|
|
40191
|
-
return evalExpr(found.value,
|
|
40191
|
+
return evalExpr(found.value, rule2, ctx, children);
|
|
40192
40192
|
if (expr.else)
|
|
40193
|
-
return evalExpr(expr.else,
|
|
40194
|
-
throw new UnhandledEnumCaseError(
|
|
40193
|
+
return evalExpr(expr.else, rule2, ctx, children);
|
|
40194
|
+
throw new UnhandledEnumCaseError(rule2.id, tag);
|
|
40195
40195
|
}
|
|
40196
40196
|
}
|
|
40197
40197
|
}
|
|
@@ -40235,11 +40235,11 @@ function resolveFact(factId, ctx, children) {
|
|
|
40235
40235
|
children.push(node2);
|
|
40236
40236
|
return ctx.facts.get(factId);
|
|
40237
40237
|
}
|
|
40238
|
-
function evalAll(exprs,
|
|
40238
|
+
function evalAll(exprs, rule2, ctx, children) {
|
|
40239
40239
|
const out = [];
|
|
40240
40240
|
let poisoned = false;
|
|
40241
40241
|
for (const e of exprs) {
|
|
40242
|
-
const v = evalExpr(e,
|
|
40242
|
+
const v = evalExpr(e, rule2, ctx, children);
|
|
40243
40243
|
if (v === POISON)
|
|
40244
40244
|
poisoned = true;
|
|
40245
40245
|
else
|
|
@@ -40247,28 +40247,28 @@ function evalAll(exprs, rule, ctx, children) {
|
|
|
40247
40247
|
}
|
|
40248
40248
|
return poisoned ? POISON : out;
|
|
40249
40249
|
}
|
|
40250
|
-
function numericFold(vals,
|
|
40250
|
+
function numericFold(vals, rule2, op, fold) {
|
|
40251
40251
|
if (vals.length === 0)
|
|
40252
|
-
throw new EngineError(`rule "${
|
|
40252
|
+
throw new EngineError(`rule "${rule2.id}": empty ${op}`);
|
|
40253
40253
|
const type = vals[0].type;
|
|
40254
40254
|
if (type !== "money" && type !== "int") {
|
|
40255
|
-
throw new EngineError(`rule "${
|
|
40255
|
+
throw new EngineError(`rule "${rule2.id}": ${op} over ${type}`);
|
|
40256
40256
|
}
|
|
40257
|
-
let acc = numericOf(vals[0],
|
|
40257
|
+
let acc = numericOf(vals[0], rule2, op);
|
|
40258
40258
|
for (const v of vals.slice(1)) {
|
|
40259
40259
|
if (v.type !== type) {
|
|
40260
|
-
throw new EngineError(`rule "${
|
|
40260
|
+
throw new EngineError(`rule "${rule2.id}": ${op} mixes ${type} and ${v.type}`);
|
|
40261
40261
|
}
|
|
40262
|
-
acc = fold(acc, numericOf(v,
|
|
40262
|
+
acc = fold(acc, numericOf(v, rule2, op));
|
|
40263
40263
|
}
|
|
40264
40264
|
return type === "money" ? { type: "money", cents: acc } : { type: "int", value: acc };
|
|
40265
40265
|
}
|
|
40266
|
-
function numericOf(v,
|
|
40266
|
+
function numericOf(v, rule2, op) {
|
|
40267
40267
|
if (v.type === "money")
|
|
40268
40268
|
return v.cents;
|
|
40269
40269
|
if (v.type === "int")
|
|
40270
40270
|
return v.value;
|
|
40271
|
-
throw new EngineError(`rule "${
|
|
40271
|
+
throw new EngineError(`rule "${rule2.id}": ${op} expects money|int, got ${v.type}`);
|
|
40272
40272
|
}
|
|
40273
40273
|
function canonicalScalar(v) {
|
|
40274
40274
|
switch (v.type) {
|
|
@@ -40282,9 +40282,9 @@ function canonicalScalar(v) {
|
|
|
40282
40282
|
return `e:${v.value}`;
|
|
40283
40283
|
}
|
|
40284
40284
|
}
|
|
40285
|
-
function expectType(v, type,
|
|
40285
|
+
function expectType(v, type, rule2, where) {
|
|
40286
40286
|
if (v.type !== type) {
|
|
40287
|
-
throw new EngineError(`rule "${
|
|
40287
|
+
throw new EngineError(`rule "${rule2.id}": ${where} expects ${type}, got ${v.type}`);
|
|
40288
40288
|
}
|
|
40289
40289
|
}
|
|
40290
40290
|
function coerceFacts(corpus2, plain) {
|
|
@@ -40352,7 +40352,7 @@ var IncompleteReturnError = class extends OpenTaxError {
|
|
|
40352
40352
|
};
|
|
40353
40353
|
|
|
40354
40354
|
// dist/version.js
|
|
40355
|
-
var COMPOSER_VERSION = "0.
|
|
40355
|
+
var COMPOSER_VERSION = "0.9.1";
|
|
40356
40356
|
|
|
40357
40357
|
// ../solve/dist/sweep.js
|
|
40358
40358
|
function evaluateAt(corpus2, baseFacts, options, atCents) {
|
|
@@ -40473,9 +40473,9 @@ function compareAcross(corpus2, baseFacts, options) {
|
|
|
40473
40473
|
|
|
40474
40474
|
// ../solve/dist/lookup.js
|
|
40475
40475
|
var tokenize = (s) => s.toLowerCase().replace(/[^a-z0-9]+/g, " ").split(" ").filter((t) => t.length > 2);
|
|
40476
|
-
function extractByStatus(
|
|
40476
|
+
function extractByStatus(rule2) {
|
|
40477
40477
|
const out = {};
|
|
40478
|
-
walkExpr(
|
|
40478
|
+
walkExpr(rule2.formula, (e) => {
|
|
40479
40479
|
if (e.kind === "match" && e.on.kind === "fact" && e.on.factId === "filingStatus") {
|
|
40480
40480
|
for (const c2 of e.cases) {
|
|
40481
40481
|
if (c2.value.kind === "money")
|
|
@@ -40518,13 +40518,13 @@ function lookupParameters(corpus2, query, asOf) {
|
|
|
40518
40518
|
if (tokens.length === 0)
|
|
40519
40519
|
return [];
|
|
40520
40520
|
const hits = [];
|
|
40521
|
-
for (const
|
|
40522
|
-
if (asOf && !(
|
|
40521
|
+
for (const rule2 of corpus2.rules) {
|
|
40522
|
+
if (asOf && !(rule2.effectiveFrom <= asOf && (rule2.effectiveTo === void 0 || asOf < rule2.effectiveTo))) {
|
|
40523
40523
|
continue;
|
|
40524
40524
|
}
|
|
40525
|
-
const paramWords = Object.keys(
|
|
40526
|
-
const haystackStrong = `${
|
|
40527
|
-
const haystackWeak = `${
|
|
40525
|
+
const paramWords = Object.keys(rule2.parameters ?? {}).map((n) => n.replace(/([A-Z])/g, " $1").toLowerCase()).join(" ");
|
|
40526
|
+
const haystackStrong = `${rule2.id} ${rule2.title} ${paramWords} ${JURISDICTION_NAMES[rule2.jurisdiction] ?? ""}`.toLowerCase();
|
|
40527
|
+
const haystackWeak = `${rule2.citation.source} ${rule2.citation.section} ${rule2.citation.excerpt}`.toLowerCase();
|
|
40528
40528
|
let score = 0;
|
|
40529
40529
|
for (const t of tokens) {
|
|
40530
40530
|
if (haystackStrong.includes(t))
|
|
@@ -40535,23 +40535,23 @@ function lookupParameters(corpus2, query, asOf) {
|
|
|
40535
40535
|
if (score === 0)
|
|
40536
40536
|
continue;
|
|
40537
40537
|
const parameters = {};
|
|
40538
|
-
for (const [name, p] of Object.entries(
|
|
40538
|
+
for (const [name, p] of Object.entries(rule2.parameters ?? {})) {
|
|
40539
40539
|
if (p.type === "money")
|
|
40540
40540
|
parameters[name] = String(p.value);
|
|
40541
40541
|
}
|
|
40542
|
-
const byFilingStatus = extractByStatus(
|
|
40542
|
+
const byFilingStatus = extractByStatus(rule2);
|
|
40543
40543
|
if (Object.keys(parameters).length === 0 && Object.keys(byFilingStatus).length === 0) {
|
|
40544
40544
|
score -= 1;
|
|
40545
40545
|
if (score <= 0)
|
|
40546
40546
|
continue;
|
|
40547
40547
|
}
|
|
40548
40548
|
hits.push({
|
|
40549
|
-
ruleId:
|
|
40550
|
-
version:
|
|
40551
|
-
title:
|
|
40552
|
-
citation:
|
|
40553
|
-
effectiveFrom:
|
|
40554
|
-
effectiveTo:
|
|
40549
|
+
ruleId: rule2.id,
|
|
40550
|
+
version: rule2.version,
|
|
40551
|
+
title: rule2.title,
|
|
40552
|
+
citation: rule2.citation,
|
|
40553
|
+
effectiveFrom: rule2.effectiveFrom,
|
|
40554
|
+
effectiveTo: rule2.effectiveTo,
|
|
40555
40555
|
parameters,
|
|
40556
40556
|
byFilingStatus,
|
|
40557
40557
|
score
|
|
@@ -40579,16 +40579,16 @@ function searchRules(corpus2, query, asOf, limit = 8) {
|
|
|
40579
40579
|
const allTokens = [...new Set(tokenize(query.slice(0, 500)))].slice(0, 12);
|
|
40580
40580
|
if (allTokens.length === 0)
|
|
40581
40581
|
return [];
|
|
40582
|
-
const haystacks = corpus2.rules.map((
|
|
40583
|
-
const paramWords = Object.keys(
|
|
40582
|
+
const haystacks = corpus2.rules.map((rule2) => {
|
|
40583
|
+
const paramWords = Object.keys(rule2.parameters ?? {}).map((n) => n.replace(/([A-Z])/g, " $1").toLowerCase()).join(" ");
|
|
40584
40584
|
return {
|
|
40585
|
-
rule,
|
|
40585
|
+
rule: rule2,
|
|
40586
40586
|
// "_" is a regex word character — split snake_case so \b-anchored
|
|
40587
40587
|
// tokens ("tax") still reach id segments ("kiddie_tax").
|
|
40588
|
-
id:
|
|
40589
|
-
title:
|
|
40590
|
-
meta: `${paramWords} ${JURISDICTION_NAMES[
|
|
40591
|
-
weak: `${
|
|
40588
|
+
id: rule2.id.toLowerCase().replace(/[._]/g, " "),
|
|
40589
|
+
title: rule2.title.toLowerCase(),
|
|
40590
|
+
meta: `${paramWords} ${JURISDICTION_NAMES[rule2.jurisdiction] ?? ""}`.toLowerCase(),
|
|
40591
|
+
weak: `${rule2.citation.source} ${rule2.citation.section} ${rule2.citation.excerpt ?? ""}`.toLowerCase()
|
|
40592
40592
|
};
|
|
40593
40593
|
});
|
|
40594
40594
|
const matchers = new Map(allTokens.map((t) => [t, new RegExp(`\\b${t}`)]));
|
|
@@ -40600,8 +40600,8 @@ function searchRules(corpus2, query, asOf, limit = 8) {
|
|
|
40600
40600
|
const boost = new Map(tokens.map((t) => [t, dfCache.get(t) <= haystacks.length * 0.05 ? 2 : 1]));
|
|
40601
40601
|
const minScore = tokens.length >= 2 ? 2 : 1;
|
|
40602
40602
|
const hits = [];
|
|
40603
|
-
for (const { rule, id, title, meta: meta3, weak } of haystacks) {
|
|
40604
|
-
if (asOf && !(
|
|
40603
|
+
for (const { rule: rule2, id: id2, title, meta: meta3, weak } of haystacks) {
|
|
40604
|
+
if (asOf && !(rule2.effectiveFrom <= asOf && (rule2.effectiveTo === void 0 || asOf < rule2.effectiveTo))) {
|
|
40605
40605
|
continue;
|
|
40606
40606
|
}
|
|
40607
40607
|
let raw = 0;
|
|
@@ -40610,7 +40610,7 @@ function searchRules(corpus2, query, asOf, limit = 8) {
|
|
|
40610
40610
|
let sawStrong = false;
|
|
40611
40611
|
for (const t of tokens) {
|
|
40612
40612
|
let s = 0;
|
|
40613
|
-
if (has(
|
|
40613
|
+
if (has(id2, t))
|
|
40614
40614
|
s += 2;
|
|
40615
40615
|
if (has(title, t))
|
|
40616
40616
|
s += 2;
|
|
@@ -40630,15 +40630,15 @@ function searchRules(corpus2, query, asOf, limit = 8) {
|
|
|
40630
40630
|
if (tokens.length >= 2 && !sawStrong)
|
|
40631
40631
|
continue;
|
|
40632
40632
|
hits.push({
|
|
40633
|
-
ruleId:
|
|
40634
|
-
version:
|
|
40635
|
-
title:
|
|
40636
|
-
jurisdiction:
|
|
40637
|
-
citation:
|
|
40638
|
-
effectiveFrom:
|
|
40639
|
-
effectiveTo:
|
|
40640
|
-
snippet: makeSnippet(
|
|
40641
|
-
hasParameters: Object.keys(
|
|
40633
|
+
ruleId: rule2.id,
|
|
40634
|
+
version: rule2.version,
|
|
40635
|
+
title: rule2.title,
|
|
40636
|
+
jurisdiction: rule2.jurisdiction,
|
|
40637
|
+
citation: rule2.citation,
|
|
40638
|
+
effectiveFrom: rule2.effectiveFrom,
|
|
40639
|
+
effectiveTo: rule2.effectiveTo,
|
|
40640
|
+
snippet: makeSnippet(rule2.citation.excerpt ?? "", tokens),
|
|
40641
|
+
hasParameters: Object.keys(rule2.parameters ?? {}).length > 0,
|
|
40642
40642
|
score
|
|
40643
40643
|
});
|
|
40644
40644
|
}
|
|
@@ -40738,17 +40738,17 @@ var isIncompleteReturnRefusal = (err) => err instanceof Error && err.code === "I
|
|
|
40738
40738
|
// ../compose/dist/money.js
|
|
40739
40739
|
var c = (d3) => BigInt(Math.round((d3 ?? 0) * 100));
|
|
40740
40740
|
var rd = (x) => {
|
|
40741
|
-
const
|
|
40742
|
-
const a =
|
|
40741
|
+
const neg3 = x < 0n;
|
|
40742
|
+
const a = neg3 ? -x : x;
|
|
40743
40743
|
const r = (a + 50n) / 100n * 100n;
|
|
40744
|
-
return
|
|
40744
|
+
return neg3 ? -r : r;
|
|
40745
40745
|
};
|
|
40746
40746
|
var max02 = (x) => x > 0n ? x : 0n;
|
|
40747
40747
|
var min2 = (a, b) => a < b ? a : b;
|
|
40748
40748
|
var fmtD = (x) => {
|
|
40749
|
-
const
|
|
40750
|
-
const a =
|
|
40751
|
-
return `${
|
|
40749
|
+
const neg3 = x < 0n;
|
|
40750
|
+
const a = neg3 ? -x : x;
|
|
40751
|
+
return `${neg3 ? "-" : ""}$${(a / 100n).toLocaleString()}`;
|
|
40752
40752
|
};
|
|
40753
40753
|
|
|
40754
40754
|
// ../compose/dist/types.js
|
|
@@ -41347,8 +41347,8 @@ function composeMO(input2, evalStateTax, notes) {
|
|
|
41347
41347
|
const privRaw = min2(rd(c(input2.moPrivatePensionYou)), PRIVATE_PENSION_CAP) + min2(rd(c(input2.moPrivatePensionSpouse)), PRIVATE_PENSION_CAP);
|
|
41348
41348
|
let secB = 0n;
|
|
41349
41349
|
if (privRaw > 0n) {
|
|
41350
|
-
const
|
|
41351
|
-
secB = max02(privRaw -
|
|
41350
|
+
const excess2 = max02(l6 - rd(c(input2.taxableSocialSecurity)) - privateLimit);
|
|
41351
|
+
secB = max02(privRaw - excess2);
|
|
41352
41352
|
notes.push(`MO-A Section B private pension exemption ${fmtD(secB)} ($6,000/spouse cap, reduced by the excess of MO AGI less taxable SS over ${fmtD(privateLimit)})`);
|
|
41353
41353
|
}
|
|
41354
41354
|
const l8 = secAY + secAS + secB + secC;
|
|
@@ -41389,7 +41389,7 @@ function composeMO(input2, evalStateTax, notes) {
|
|
|
41389
41389
|
const l2124 = rd(c(input2.moOtherDeductions));
|
|
41390
41390
|
const l25 = l8 + l13 + l14 + l15 + l16 + l17 + l18 + l19 + l2124;
|
|
41391
41391
|
const l26 = l6 - l25;
|
|
41392
|
-
const alloc = (
|
|
41392
|
+
const alloc = (pct13) => rd((l26 * pct13 + 50n) / 100n);
|
|
41393
41393
|
const l27Y = pctY === 100n ? rd(l26) : alloc(pctY);
|
|
41394
41394
|
const l27S = pctS === 0n ? 0n : pctS === 100n ? rd(l26) : alloc(pctS);
|
|
41395
41395
|
const l28Y = rd(c(input2.moEnterpriseZoneYou));
|
|
@@ -43455,10 +43455,10 @@ function composeAR(input2, evalStateTax, notes) {
|
|
|
43455
43455
|
if (itemize) {
|
|
43456
43456
|
method = "itemized";
|
|
43457
43457
|
if (status4) {
|
|
43458
|
-
const
|
|
43459
|
-
a27 = (itemized *
|
|
43458
|
+
const pct13 = agiAll > 0n ? (a25 * 200n + agiAll) / (2n * agiAll) : 100n;
|
|
43459
|
+
a27 = (itemized * pct13 + 50n) / 100n;
|
|
43460
43460
|
b27 = itemized - a27;
|
|
43461
|
-
n.push(`AR3 lines 31-35: itemized deductions ${fmtD(itemized)} prorated ${
|
|
43461
|
+
n.push(`AR3 lines 31-35: itemized deductions ${fmtD(itemized)} prorated ${pct13}% to the primary (${fmtD(a27)}) and ${fmtD(b27)} to the spouse by AGI share (whole percent)`);
|
|
43462
43462
|
} else
|
|
43463
43463
|
a27 = itemized;
|
|
43464
43464
|
if (fs === "mfs")
|
|
@@ -48794,7 +48794,7 @@ var facts = [
|
|
|
48794
48794
|
id: "qbiW2Wages",
|
|
48795
48795
|
type: "money",
|
|
48796
48796
|
min: "0",
|
|
48797
|
-
description: "W-2 wages PAID BY the qualified trade or business, allocable to QBI (\xA7 199A(b)(4)) \u2014 drives the above-threshold wage limit. Intake forms often label this 'W-2 Wages Paid' under the business section: it is a \xA7 199A LIMIT input, NOT a Schedule C expense \u2014 never subtract it from selfEmploymentNetProfit. Defaults to $0, which can only understate the deduction (conservative). In dollars.",
|
|
48797
|
+
description: "W-2 wages PAID BY the qualified trade or business, allocable to QBI (\xA7 199A(b)(4)) \u2014 drives the above-threshold wage limit. Intake forms often label this 'W-2 Wages Paid' under the business section: it is a \xA7 199A LIMIT input, NOT a Schedule C expense \u2014 never subtract it from selfEmploymentNetProfit. With businesses listed separately (qbiAdditionalBusinesses) these are the main business's wages \u2014 the business holding whatever QBI is not listed. Defaults to $0, which can only understate the deduction (conservative). In dollars.",
|
|
48798
48798
|
default: {
|
|
48799
48799
|
value: "0",
|
|
48800
48800
|
rationale: "Assumed the business paid no W-2 wages absent contrary input (conservative above the threshold)"
|
|
@@ -48804,7 +48804,7 @@ var facts = [
|
|
|
48804
48804
|
id: "qbiUBIA",
|
|
48805
48805
|
type: "money",
|
|
48806
48806
|
min: "0",
|
|
48807
|
-
description: "Unadjusted basis immediately after acquisition of the business's qualified property (\xA7 199A(b)(6)) \u2014 the 2.5% prong of the wage limit. Defaults to $0 (conservative). In dollars.",
|
|
48807
|
+
description: "Unadjusted basis immediately after acquisition of the business's qualified property (\xA7 199A(b)(6)) \u2014 the 2.5% prong of the wage limit. With businesses listed separately, the main business's UBIA. Defaults to $0 (conservative). In dollars.",
|
|
48808
48808
|
default: {
|
|
48809
48809
|
value: "0",
|
|
48810
48810
|
rationale: "Assumed no qualified-property UBIA absent contrary input (conservative)"
|
|
@@ -48813,10 +48813,294 @@ var facts = [
|
|
|
48813
48813
|
{
|
|
48814
48814
|
id: "businessIsSSTB",
|
|
48815
48815
|
type: "bool",
|
|
48816
|
-
description: "The trade or business is a specified service trade or business (\xA7 199A(d)(2): health, law, accounting, consulting, financial services, athletics, performing arts, \u2026) \u2014 above the threshold an SSTB's deduction phases to zero."
|
|
48816
|
+
description: "The trade or business is a specified service trade or business (\xA7 199A(d)(2): health, law, accounting, consulting, financial services, athletics, performing arts, \u2026) \u2014 above the threshold an SSTB's deduction phases to zero. With businesses listed separately, this is the main business \u2014 the one holding whatever QBI is not listed."
|
|
48817
48817
|
// no default — only demanded above the § 199A threshold, where it
|
|
48818
48818
|
// decides everything; the engine must never guess it
|
|
48819
48819
|
},
|
|
48820
|
+
{
|
|
48821
|
+
id: "qbiAggregationGroup",
|
|
48822
|
+
type: "int",
|
|
48823
|
+
min: "0",
|
|
48824
|
+
max: "9",
|
|
48825
|
+
description: "\xA7 199A aggregation group (Reg. \xA7 1.199A-4) of the main business (QBI not listed separately): businesses given the same number from 1 to 9 are one business for the W-2 wage and UBIA limits (Form 8995-A Schedule B), adding their QBI, W-2 wages and UBIA; 0 = not aggregated. Aggregation requires 50% common ownership for the majority of the year, the same tax year, and two of the three Reg. \xA7 1.199A-4(b)(1)(v) factors; once chosen it must be kept in later years. A specified service trade or business may not be aggregated (refused). Read only above the \xA7 199A threshold when the return has two or more businesses.",
|
|
48826
|
+
default: {
|
|
48827
|
+
value: "0",
|
|
48828
|
+
rationale: "Assumed the business is not aggregated with another"
|
|
48829
|
+
}
|
|
48830
|
+
},
|
|
48831
|
+
{
|
|
48832
|
+
id: "spouseQbiW2Wages",
|
|
48833
|
+
type: "money",
|
|
48834
|
+
min: "0",
|
|
48835
|
+
description: "JOINT RETURN: W-2 wages PAID BY the second spouse's own Schedule C business (\xA7 199A(b)(4)) \u2014 its above-threshold wage limit; that business is its own \xA7 199A trade or business. Never subtract it from spouseSelfEmploymentNetProfit. Defaults to $0, which can only understate the deduction. In dollars.",
|
|
48836
|
+
default: {
|
|
48837
|
+
value: "0",
|
|
48838
|
+
rationale: "Assumed the second spouse's business paid no W-2 wages (conservative above the threshold)"
|
|
48839
|
+
}
|
|
48840
|
+
},
|
|
48841
|
+
{
|
|
48842
|
+
id: "spouseQbiUBIA",
|
|
48843
|
+
type: "money",
|
|
48844
|
+
min: "0",
|
|
48845
|
+
description: "JOINT RETURN: UBIA of the second spouse's own Schedule C business's qualified property (\xA7 199A(b)(6)) \u2014 the 2.5% prong of its wage limit. Defaults to $0 (conservative). In dollars.",
|
|
48846
|
+
default: {
|
|
48847
|
+
value: "0",
|
|
48848
|
+
rationale: "Assumed no qualified-property UBIA in the second spouse's business (conservative)"
|
|
48849
|
+
}
|
|
48850
|
+
},
|
|
48851
|
+
{
|
|
48852
|
+
id: "spouseBusinessIsSSTB",
|
|
48853
|
+
type: "bool",
|
|
48854
|
+
description: "JOINT RETURN: the second spouse's own Schedule C business is a specified service trade or business (\xA7 199A(d)(2)). Asked only above the \xA7 199A threshold when that spouse has QBI."
|
|
48855
|
+
// no default — decides the deduction above the threshold; never guessed
|
|
48856
|
+
},
|
|
48857
|
+
{
|
|
48858
|
+
id: "spouseQbiAggregationGroup",
|
|
48859
|
+
type: "int",
|
|
48860
|
+
min: "0",
|
|
48861
|
+
max: "9",
|
|
48862
|
+
description: "\xA7 199A aggregation group (Reg. \xA7 1.199A-4) of the second spouse's Schedule C business: businesses given the same number from 1 to 9 are one business for the W-2 wage and UBIA limits (Form 8995-A Schedule B), adding their QBI, W-2 wages and UBIA; 0 = not aggregated. Aggregation requires 50% common ownership for the majority of the year, the same tax year, and two of the three Reg. \xA7 1.199A-4(b)(1)(v) factors; once chosen it must be kept in later years. A specified service trade or business may not be aggregated (refused). Read only above the \xA7 199A threshold when the return has two or more businesses.",
|
|
48863
|
+
default: {
|
|
48864
|
+
value: "0",
|
|
48865
|
+
rationale: "Assumed the business is not aggregated with another"
|
|
48866
|
+
}
|
|
48867
|
+
},
|
|
48868
|
+
{
|
|
48869
|
+
id: "qbiAdditionalBusinesses",
|
|
48870
|
+
type: "int",
|
|
48871
|
+
min: "0",
|
|
48872
|
+
max: "5",
|
|
48873
|
+
description: "How many trades or businesses to list separately for \xA7 199A (0\u20135), each in qbiBusiness2\u2026 through qbiBusiness6\u2026: each listed business gets its own W-2 wage and UBIA limit, SSTB status and aggregation group (Form 8995-A Part II, one column each). A listed business STAYS in the return's totals \u2014 its profit is part of selfEmploymentNetProfit or k1OrdinaryBusinessIncome, a QBI loss part of qbiLossOffset \u2014 and listing it only takes it out of the main business, which keeps whatever QBI is not listed (with qbiW2Wages, qbiUBIA and businessIsSSTB). The second spouse's Schedule C on a joint return is already its own business: do not list it. List each S corporation or partnership K-1 with its Statement A amounts.",
|
|
48874
|
+
default: {
|
|
48875
|
+
value: "0",
|
|
48876
|
+
rationale: "Assumed one trade or business (plus the second spouse's Schedule C on a joint return)"
|
|
48877
|
+
}
|
|
48878
|
+
},
|
|
48879
|
+
{
|
|
48880
|
+
id: "qbiBusiness2Income",
|
|
48881
|
+
type: "money",
|
|
48882
|
+
description: "Listed business 2 (when qbiAdditionalBusinesses \u2265 1): its qualified business income, or a QBI LOSS as a NEGATIVE number (\xA7 199A(c); Form 8995-A Schedule C line 1(a)) \u2014 for a K-1, Statement A's QBI; for a Schedule C, net profit less its share of the \xBD-SE, SEP and SE-health deductions. Its income or loss must already be in the return's totals (a profit within selfEmploymentNetProfit or k1OrdinaryBusinessIncome, a loss within qbiLossOffset). In dollars."
|
|
48883
|
+
// no default — a listed business's QBI is never guessed
|
|
48884
|
+
},
|
|
48885
|
+
{
|
|
48886
|
+
id: "qbiBusiness2W2Wages",
|
|
48887
|
+
type: "money",
|
|
48888
|
+
min: "0",
|
|
48889
|
+
description: "Listed business 2: W-2 wages paid by the business allocable to QBI (\xA7 199A(b)(4); K-1 Statement A) \u2014 its above-threshold wage limit. Defaults to $0, which can only understate the deduction. In dollars.",
|
|
48890
|
+
default: {
|
|
48891
|
+
value: "0",
|
|
48892
|
+
rationale: "Assumed listed business 2 paid no W-2 wages (conservative above the threshold)"
|
|
48893
|
+
}
|
|
48894
|
+
},
|
|
48895
|
+
{
|
|
48896
|
+
id: "qbiBusiness2UBIA",
|
|
48897
|
+
type: "money",
|
|
48898
|
+
min: "0",
|
|
48899
|
+
description: "Listed business 2: UBIA of its qualified property (\xA7 199A(b)(6); K-1 Statement A) \u2014 the 2.5% prong of its wage limit. Defaults to $0 (conservative). In dollars.",
|
|
48900
|
+
default: {
|
|
48901
|
+
value: "0",
|
|
48902
|
+
rationale: "Assumed no qualified-property UBIA in listed business 2 (conservative)"
|
|
48903
|
+
}
|
|
48904
|
+
},
|
|
48905
|
+
{
|
|
48906
|
+
id: "qbiBusiness2IsSSTB",
|
|
48907
|
+
type: "bool",
|
|
48908
|
+
description: "Listed business 2 is a specified service trade or business (\xA7 199A(d)(2); K-1 Statement A). Asked only above the \xA7 199A threshold."
|
|
48909
|
+
// no default — never guessed
|
|
48910
|
+
},
|
|
48911
|
+
{
|
|
48912
|
+
id: "qbiBusiness2AggregationGroup",
|
|
48913
|
+
type: "int",
|
|
48914
|
+
min: "0",
|
|
48915
|
+
max: "9",
|
|
48916
|
+
description: "\xA7 199A aggregation group (Reg. \xA7 1.199A-4) of listed business 2: businesses given the same number from 1 to 9 are one business for the W-2 wage and UBIA limits (Form 8995-A Schedule B), adding their QBI, W-2 wages and UBIA; 0 = not aggregated. Aggregation requires 50% common ownership for the majority of the year, the same tax year, and two of the three Reg. \xA7 1.199A-4(b)(1)(v) factors; once chosen it must be kept in later years. A specified service trade or business may not be aggregated (refused). Read only above the \xA7 199A threshold when the return has two or more businesses.",
|
|
48917
|
+
default: {
|
|
48918
|
+
value: "0",
|
|
48919
|
+
rationale: "Assumed the business is not aggregated with another"
|
|
48920
|
+
}
|
|
48921
|
+
},
|
|
48922
|
+
{
|
|
48923
|
+
id: "qbiBusiness3Income",
|
|
48924
|
+
type: "money",
|
|
48925
|
+
description: "Listed business 3 (when qbiAdditionalBusinesses \u2265 2): its qualified business income, or a QBI LOSS as a NEGATIVE number (\xA7 199A(c); Form 8995-A Schedule C line 1(a)) \u2014 for a K-1, Statement A's QBI; for a Schedule C, net profit less its share of the \xBD-SE, SEP and SE-health deductions. Its income or loss must already be in the return's totals (a profit within selfEmploymentNetProfit or k1OrdinaryBusinessIncome, a loss within qbiLossOffset). In dollars."
|
|
48926
|
+
// no default — a listed business's QBI is never guessed
|
|
48927
|
+
},
|
|
48928
|
+
{
|
|
48929
|
+
id: "qbiBusiness3W2Wages",
|
|
48930
|
+
type: "money",
|
|
48931
|
+
min: "0",
|
|
48932
|
+
description: "Listed business 3: W-2 wages paid by the business allocable to QBI (\xA7 199A(b)(4); K-1 Statement A) \u2014 its above-threshold wage limit. Defaults to $0, which can only understate the deduction. In dollars.",
|
|
48933
|
+
default: {
|
|
48934
|
+
value: "0",
|
|
48935
|
+
rationale: "Assumed listed business 3 paid no W-2 wages (conservative above the threshold)"
|
|
48936
|
+
}
|
|
48937
|
+
},
|
|
48938
|
+
{
|
|
48939
|
+
id: "qbiBusiness3UBIA",
|
|
48940
|
+
type: "money",
|
|
48941
|
+
min: "0",
|
|
48942
|
+
description: "Listed business 3: UBIA of its qualified property (\xA7 199A(b)(6); K-1 Statement A) \u2014 the 2.5% prong of its wage limit. Defaults to $0 (conservative). In dollars.",
|
|
48943
|
+
default: {
|
|
48944
|
+
value: "0",
|
|
48945
|
+
rationale: "Assumed no qualified-property UBIA in listed business 3 (conservative)"
|
|
48946
|
+
}
|
|
48947
|
+
},
|
|
48948
|
+
{
|
|
48949
|
+
id: "qbiBusiness3IsSSTB",
|
|
48950
|
+
type: "bool",
|
|
48951
|
+
description: "Listed business 3 is a specified service trade or business (\xA7 199A(d)(2); K-1 Statement A). Asked only above the \xA7 199A threshold."
|
|
48952
|
+
// no default — never guessed
|
|
48953
|
+
},
|
|
48954
|
+
{
|
|
48955
|
+
id: "qbiBusiness3AggregationGroup",
|
|
48956
|
+
type: "int",
|
|
48957
|
+
min: "0",
|
|
48958
|
+
max: "9",
|
|
48959
|
+
description: "\xA7 199A aggregation group (Reg. \xA7 1.199A-4) of listed business 3: businesses given the same number from 1 to 9 are one business for the W-2 wage and UBIA limits (Form 8995-A Schedule B), adding their QBI, W-2 wages and UBIA; 0 = not aggregated. Aggregation requires 50% common ownership for the majority of the year, the same tax year, and two of the three Reg. \xA7 1.199A-4(b)(1)(v) factors; once chosen it must be kept in later years. A specified service trade or business may not be aggregated (refused). Read only above the \xA7 199A threshold when the return has two or more businesses.",
|
|
48960
|
+
default: {
|
|
48961
|
+
value: "0",
|
|
48962
|
+
rationale: "Assumed the business is not aggregated with another"
|
|
48963
|
+
}
|
|
48964
|
+
},
|
|
48965
|
+
{
|
|
48966
|
+
id: "qbiBusiness4Income",
|
|
48967
|
+
type: "money",
|
|
48968
|
+
description: "Listed business 4 (when qbiAdditionalBusinesses \u2265 3): its qualified business income, or a QBI LOSS as a NEGATIVE number (\xA7 199A(c); Form 8995-A Schedule C line 1(a)) \u2014 for a K-1, Statement A's QBI; for a Schedule C, net profit less its share of the \xBD-SE, SEP and SE-health deductions. Its income or loss must already be in the return's totals (a profit within selfEmploymentNetProfit or k1OrdinaryBusinessIncome, a loss within qbiLossOffset). In dollars."
|
|
48969
|
+
// no default — a listed business's QBI is never guessed
|
|
48970
|
+
},
|
|
48971
|
+
{
|
|
48972
|
+
id: "qbiBusiness4W2Wages",
|
|
48973
|
+
type: "money",
|
|
48974
|
+
min: "0",
|
|
48975
|
+
description: "Listed business 4: W-2 wages paid by the business allocable to QBI (\xA7 199A(b)(4); K-1 Statement A) \u2014 its above-threshold wage limit. Defaults to $0, which can only understate the deduction. In dollars.",
|
|
48976
|
+
default: {
|
|
48977
|
+
value: "0",
|
|
48978
|
+
rationale: "Assumed listed business 4 paid no W-2 wages (conservative above the threshold)"
|
|
48979
|
+
}
|
|
48980
|
+
},
|
|
48981
|
+
{
|
|
48982
|
+
id: "qbiBusiness4UBIA",
|
|
48983
|
+
type: "money",
|
|
48984
|
+
min: "0",
|
|
48985
|
+
description: "Listed business 4: UBIA of its qualified property (\xA7 199A(b)(6); K-1 Statement A) \u2014 the 2.5% prong of its wage limit. Defaults to $0 (conservative). In dollars.",
|
|
48986
|
+
default: {
|
|
48987
|
+
value: "0",
|
|
48988
|
+
rationale: "Assumed no qualified-property UBIA in listed business 4 (conservative)"
|
|
48989
|
+
}
|
|
48990
|
+
},
|
|
48991
|
+
{
|
|
48992
|
+
id: "qbiBusiness4IsSSTB",
|
|
48993
|
+
type: "bool",
|
|
48994
|
+
description: "Listed business 4 is a specified service trade or business (\xA7 199A(d)(2); K-1 Statement A). Asked only above the \xA7 199A threshold."
|
|
48995
|
+
// no default — never guessed
|
|
48996
|
+
},
|
|
48997
|
+
{
|
|
48998
|
+
id: "qbiBusiness4AggregationGroup",
|
|
48999
|
+
type: "int",
|
|
49000
|
+
min: "0",
|
|
49001
|
+
max: "9",
|
|
49002
|
+
description: "\xA7 199A aggregation group (Reg. \xA7 1.199A-4) of listed business 4: businesses given the same number from 1 to 9 are one business for the W-2 wage and UBIA limits (Form 8995-A Schedule B), adding their QBI, W-2 wages and UBIA; 0 = not aggregated. Aggregation requires 50% common ownership for the majority of the year, the same tax year, and two of the three Reg. \xA7 1.199A-4(b)(1)(v) factors; once chosen it must be kept in later years. A specified service trade or business may not be aggregated (refused). Read only above the \xA7 199A threshold when the return has two or more businesses.",
|
|
49003
|
+
default: {
|
|
49004
|
+
value: "0",
|
|
49005
|
+
rationale: "Assumed the business is not aggregated with another"
|
|
49006
|
+
}
|
|
49007
|
+
},
|
|
49008
|
+
{
|
|
49009
|
+
id: "qbiBusiness5Income",
|
|
49010
|
+
type: "money",
|
|
49011
|
+
description: "Listed business 5 (when qbiAdditionalBusinesses \u2265 4): its qualified business income, or a QBI LOSS as a NEGATIVE number (\xA7 199A(c); Form 8995-A Schedule C line 1(a)) \u2014 for a K-1, Statement A's QBI; for a Schedule C, net profit less its share of the \xBD-SE, SEP and SE-health deductions. Its income or loss must already be in the return's totals (a profit within selfEmploymentNetProfit or k1OrdinaryBusinessIncome, a loss within qbiLossOffset). In dollars."
|
|
49012
|
+
// no default — a listed business's QBI is never guessed
|
|
49013
|
+
},
|
|
49014
|
+
{
|
|
49015
|
+
id: "qbiBusiness5W2Wages",
|
|
49016
|
+
type: "money",
|
|
49017
|
+
min: "0",
|
|
49018
|
+
description: "Listed business 5: W-2 wages paid by the business allocable to QBI (\xA7 199A(b)(4); K-1 Statement A) \u2014 its above-threshold wage limit. Defaults to $0, which can only understate the deduction. In dollars.",
|
|
49019
|
+
default: {
|
|
49020
|
+
value: "0",
|
|
49021
|
+
rationale: "Assumed listed business 5 paid no W-2 wages (conservative above the threshold)"
|
|
49022
|
+
}
|
|
49023
|
+
},
|
|
49024
|
+
{
|
|
49025
|
+
id: "qbiBusiness5UBIA",
|
|
49026
|
+
type: "money",
|
|
49027
|
+
min: "0",
|
|
49028
|
+
description: "Listed business 5: UBIA of its qualified property (\xA7 199A(b)(6); K-1 Statement A) \u2014 the 2.5% prong of its wage limit. Defaults to $0 (conservative). In dollars.",
|
|
49029
|
+
default: {
|
|
49030
|
+
value: "0",
|
|
49031
|
+
rationale: "Assumed no qualified-property UBIA in listed business 5 (conservative)"
|
|
49032
|
+
}
|
|
49033
|
+
},
|
|
49034
|
+
{
|
|
49035
|
+
id: "qbiBusiness5IsSSTB",
|
|
49036
|
+
type: "bool",
|
|
49037
|
+
description: "Listed business 5 is a specified service trade or business (\xA7 199A(d)(2); K-1 Statement A). Asked only above the \xA7 199A threshold."
|
|
49038
|
+
// no default — never guessed
|
|
49039
|
+
},
|
|
49040
|
+
{
|
|
49041
|
+
id: "qbiBusiness5AggregationGroup",
|
|
49042
|
+
type: "int",
|
|
49043
|
+
min: "0",
|
|
49044
|
+
max: "9",
|
|
49045
|
+
description: "\xA7 199A aggregation group (Reg. \xA7 1.199A-4) of listed business 5: businesses given the same number from 1 to 9 are one business for the W-2 wage and UBIA limits (Form 8995-A Schedule B), adding their QBI, W-2 wages and UBIA; 0 = not aggregated. Aggregation requires 50% common ownership for the majority of the year, the same tax year, and two of the three Reg. \xA7 1.199A-4(b)(1)(v) factors; once chosen it must be kept in later years. A specified service trade or business may not be aggregated (refused). Read only above the \xA7 199A threshold when the return has two or more businesses.",
|
|
49046
|
+
default: {
|
|
49047
|
+
value: "0",
|
|
49048
|
+
rationale: "Assumed the business is not aggregated with another"
|
|
49049
|
+
}
|
|
49050
|
+
},
|
|
49051
|
+
{
|
|
49052
|
+
id: "qbiBusiness6Income",
|
|
49053
|
+
type: "money",
|
|
49054
|
+
description: "Listed business 6 (when qbiAdditionalBusinesses \u2265 5): its qualified business income, or a QBI LOSS as a NEGATIVE number (\xA7 199A(c); Form 8995-A Schedule C line 1(a)) \u2014 for a K-1, Statement A's QBI; for a Schedule C, net profit less its share of the \xBD-SE, SEP and SE-health deductions. Its income or loss must already be in the return's totals (a profit within selfEmploymentNetProfit or k1OrdinaryBusinessIncome, a loss within qbiLossOffset). In dollars."
|
|
49055
|
+
// no default — a listed business's QBI is never guessed
|
|
49056
|
+
},
|
|
49057
|
+
{
|
|
49058
|
+
id: "qbiBusiness6W2Wages",
|
|
49059
|
+
type: "money",
|
|
49060
|
+
min: "0",
|
|
49061
|
+
description: "Listed business 6: W-2 wages paid by the business allocable to QBI (\xA7 199A(b)(4); K-1 Statement A) \u2014 its above-threshold wage limit. Defaults to $0, which can only understate the deduction. In dollars.",
|
|
49062
|
+
default: {
|
|
49063
|
+
value: "0",
|
|
49064
|
+
rationale: "Assumed listed business 6 paid no W-2 wages (conservative above the threshold)"
|
|
49065
|
+
}
|
|
49066
|
+
},
|
|
49067
|
+
{
|
|
49068
|
+
id: "qbiBusiness6UBIA",
|
|
49069
|
+
type: "money",
|
|
49070
|
+
min: "0",
|
|
49071
|
+
description: "Listed business 6: UBIA of its qualified property (\xA7 199A(b)(6); K-1 Statement A) \u2014 the 2.5% prong of its wage limit. Defaults to $0 (conservative). In dollars.",
|
|
49072
|
+
default: {
|
|
49073
|
+
value: "0",
|
|
49074
|
+
rationale: "Assumed no qualified-property UBIA in listed business 6 (conservative)"
|
|
49075
|
+
}
|
|
49076
|
+
},
|
|
49077
|
+
{
|
|
49078
|
+
id: "qbiBusiness6IsSSTB",
|
|
49079
|
+
type: "bool",
|
|
49080
|
+
description: "Listed business 6 is a specified service trade or business (\xA7 199A(d)(2); K-1 Statement A). Asked only above the \xA7 199A threshold."
|
|
49081
|
+
// no default — never guessed
|
|
49082
|
+
},
|
|
49083
|
+
{
|
|
49084
|
+
id: "qbiBusiness6AggregationGroup",
|
|
49085
|
+
type: "int",
|
|
49086
|
+
min: "0",
|
|
49087
|
+
max: "9",
|
|
49088
|
+
description: "\xA7 199A aggregation group (Reg. \xA7 1.199A-4) of listed business 6: businesses given the same number from 1 to 9 are one business for the W-2 wage and UBIA limits (Form 8995-A Schedule B), adding their QBI, W-2 wages and UBIA; 0 = not aggregated. Aggregation requires 50% common ownership for the majority of the year, the same tax year, and two of the three Reg. \xA7 1.199A-4(b)(1)(v) factors; once chosen it must be kept in later years. A specified service trade or business may not be aggregated (refused). Read only above the \xA7 199A threshold when the return has two or more businesses.",
|
|
49089
|
+
default: {
|
|
49090
|
+
value: "0",
|
|
49091
|
+
rationale: "Assumed the business is not aggregated with another"
|
|
49092
|
+
}
|
|
49093
|
+
},
|
|
49094
|
+
{
|
|
49095
|
+
id: "qbiLossCarryforward",
|
|
49096
|
+
type: "money",
|
|
49097
|
+
min: "0",
|
|
49098
|
+
description: "Qualified business net LOSS carried forward from prior years, as a POSITIVE number (\xA7 199A(c)(2); last year's Form 8995 line 16 or Schedule C (Form 8995-A) line 6) \u2014 it reduces this year's QBI for the deduction only, never taxable income. Next year's amount is the target us.federal.qbi.loss_carryforward. In dollars.",
|
|
49099
|
+
default: {
|
|
49100
|
+
value: "0",
|
|
49101
|
+
rationale: "Assumed no qualified business loss carryforward from prior years"
|
|
49102
|
+
}
|
|
49103
|
+
},
|
|
48820
49104
|
{
|
|
48821
49105
|
id: "sepContribution",
|
|
48822
49106
|
type: "money",
|
|
@@ -54074,7 +54358,7 @@ function studentLoanRule(version2, effectiveFrom, effectiveTo, jointThresholdCen
|
|
|
54074
54358
|
then: param("thresholdJoint"),
|
|
54075
54359
|
else: param("threshold")
|
|
54076
54360
|
};
|
|
54077
|
-
const
|
|
54361
|
+
const range2 = {
|
|
54078
54362
|
kind: "if",
|
|
54079
54363
|
cond: isStatus("mfj"),
|
|
54080
54364
|
then: param("rangeJoint"),
|
|
@@ -54128,10 +54412,10 @@ function studentLoanRule(version2, effectiveFrom, effectiveTo, jointThresholdCen
|
|
|
54128
54412
|
kind: "min",
|
|
54129
54413
|
args: [
|
|
54130
54414
|
{ kind: "max0", arg: { kind: "sub", left: magi2, right: threshold2 } },
|
|
54131
|
-
|
|
54415
|
+
range2
|
|
54132
54416
|
]
|
|
54133
54417
|
},
|
|
54134
|
-
c:
|
|
54418
|
+
c: range2,
|
|
54135
54419
|
round: "half-up"
|
|
54136
54420
|
}
|
|
54137
54421
|
}
|
|
@@ -54911,14 +55195,14 @@ function quarterRule(q, year, from, to, proratedLimitCents, proratedLabel, withQ
|
|
|
54911
55195
|
{ kind: "mulRate", base: tiBeforeQbi, rate: { num: "20", den: "100" }, round: "half-up" }
|
|
54912
55196
|
]
|
|
54913
55197
|
};
|
|
54914
|
-
const
|
|
55198
|
+
const qbi = withQbiMinimum ? {
|
|
54915
55199
|
kind: "if",
|
|
54916
55200
|
cond: { kind: "cmp", op: "ge", left: qbiBase, right: money4("100000") },
|
|
54917
55201
|
then: { kind: "max", args: [qbiCore, money4("40000")] },
|
|
54918
55202
|
// OBBBA $400 min
|
|
54919
55203
|
else: qbiCore
|
|
54920
55204
|
} : qbiCore;
|
|
54921
|
-
const ti = { kind: "max0", arg: { kind: "sub", left: tiBeforeQbi, right:
|
|
55205
|
+
const ti = { kind: "max0", arg: { kind: "sub", left: tiBeforeQbi, right: qbi } };
|
|
54922
55206
|
const line17 = {
|
|
54923
55207
|
kind: "add",
|
|
54924
55208
|
args: [ordinaryRateTaxExpr(ti, "filingStatus", year), seTax]
|
|
@@ -57455,7 +57739,7 @@ function phased(tentative) {
|
|
|
57455
57739
|
then: param7("thresholdJoint"),
|
|
57456
57740
|
else: param7("threshold")
|
|
57457
57741
|
};
|
|
57458
|
-
const
|
|
57742
|
+
const range2 = {
|
|
57459
57743
|
kind: "if",
|
|
57460
57744
|
cond: isStatus4("mfj"),
|
|
57461
57745
|
then: param7("rangeJoint"),
|
|
@@ -57484,10 +57768,10 @@ function phased(tentative) {
|
|
|
57484
57768
|
right: threshold2
|
|
57485
57769
|
}
|
|
57486
57770
|
},
|
|
57487
|
-
|
|
57771
|
+
range2
|
|
57488
57772
|
]
|
|
57489
57773
|
},
|
|
57490
|
-
c:
|
|
57774
|
+
c: range2,
|
|
57491
57775
|
round: "half-up"
|
|
57492
57776
|
}
|
|
57493
57777
|
}
|
|
@@ -58365,7 +58649,7 @@ function repayment2025() {
|
|
|
58365
58649
|
else: capFor("162500", "325000")
|
|
58366
58650
|
}
|
|
58367
58651
|
};
|
|
58368
|
-
const
|
|
58652
|
+
const excess2 = {
|
|
58369
58653
|
kind: "max0",
|
|
58370
58654
|
arg: {
|
|
58371
58655
|
kind: "sub",
|
|
@@ -58401,8 +58685,8 @@ function repayment2025() {
|
|
|
58401
58685
|
then: {
|
|
58402
58686
|
kind: "if",
|
|
58403
58687
|
cond: { kind: "cmp", op: "lt", left: fplPercentCents, right: money19("40000") },
|
|
58404
|
-
then: { kind: "min", args: [
|
|
58405
|
-
else:
|
|
58688
|
+
then: { kind: "min", args: [excess2, cappedBand] },
|
|
58689
|
+
else: excess2
|
|
58406
58690
|
},
|
|
58407
58691
|
else: zero12
|
|
58408
58692
|
}
|
|
@@ -59947,8 +60231,8 @@ function iraRule(version2, effectiveFrom, effectiveTo, yearLabel, p, source, amo
|
|
|
59947
60231
|
{ kind: "if", cond: fact28("isAge50OrOlder"), then: param15("catchUp"), else: zero16 }
|
|
59948
60232
|
]
|
|
59949
60233
|
};
|
|
59950
|
-
const phasedLimit = (threshold2,
|
|
59951
|
-
const
|
|
60234
|
+
const phasedLimit = (threshold2, range2) => {
|
|
60235
|
+
const excess2 = {
|
|
59952
60236
|
kind: "max0",
|
|
59953
60237
|
arg: { kind: "sub", left: magi, right: threshold2 }
|
|
59954
60238
|
};
|
|
@@ -59959,14 +60243,14 @@ function iraRule(version2, effectiveFrom, effectiveTo, yearLabel, p, source, amo
|
|
|
59959
60243
|
// $10
|
|
59960
60244
|
count: {
|
|
59961
60245
|
kind: "stepUnits",
|
|
59962
|
-
value: { kind: "mulDiv", a: limit, b:
|
|
60246
|
+
value: { kind: "mulDiv", a: limit, b: excess2, c: range2, round: "floor" },
|
|
59963
60247
|
unitCents: "1000",
|
|
59964
60248
|
mode: "floor"
|
|
59965
60249
|
}
|
|
59966
60250
|
};
|
|
59967
60251
|
return {
|
|
59968
60252
|
kind: "if",
|
|
59969
|
-
cond: { kind: "cmp", op: "ge", left:
|
|
60253
|
+
cond: { kind: "cmp", op: "ge", left: excess2, right: range2 },
|
|
59970
60254
|
then: zero16,
|
|
59971
60255
|
// fully phased: the $200 floor does not apply
|
|
59972
60256
|
else: {
|
|
@@ -61225,8 +61509,8 @@ var F5695_2025 = "2025 Form 5695 (Cat. No. 13540P, created 3/20/25) and Instruct
|
|
|
61225
61509
|
var URL_25D = "https://www.law.cornell.edu/uscode/text/26/25D";
|
|
61226
61510
|
var URL_25C = "https://www.law.cornell.edu/uscode/text/26/25C";
|
|
61227
61511
|
var URL_I5695 = "https://www.irs.gov/pub/irs-pdf/i5695.pdf";
|
|
61228
|
-
var line = (
|
|
61229
|
-
id: `${J26}.energy.${
|
|
61512
|
+
var line = (id2, title, citation, formula, extra = {}) => ({
|
|
61513
|
+
id: `${J26}.energy.${id2}`,
|
|
61230
61514
|
version: 1,
|
|
61231
61515
|
jurisdiction: J26,
|
|
61232
61516
|
title,
|
|
@@ -62776,8 +63060,8 @@ var caRules = [
|
|
|
62776
63060
|
};
|
|
62777
63061
|
const param28 = (name) => ({ kind: "param", name });
|
|
62778
63062
|
const agi2 = ruleRef32("us.federal.agi");
|
|
62779
|
-
const
|
|
62780
|
-
const line26Hundredths = { kind: "stepUnits", value:
|
|
63063
|
+
const excess2 = { kind: "sub", left: earned2, right: param28("phaseOutStart") };
|
|
63064
|
+
const line26Hundredths = { kind: "stepUnits", value: excess2, unitCents: "100", mode: "floor" };
|
|
62781
63065
|
const line27Cents = {
|
|
62782
63066
|
kind: "mulInt",
|
|
62783
63067
|
base: money35("1"),
|
|
@@ -63994,7 +64278,7 @@ var njRules = [
|
|
|
63994
64278
|
},
|
|
63995
64279
|
formula: (() => {
|
|
63996
64280
|
const ti = max08(fact38("stateTaxableIncome"));
|
|
63997
|
-
const
|
|
64281
|
+
const pct13 = (num) => ({
|
|
63998
64282
|
kind: "mulRate",
|
|
63999
64283
|
base: fact38("njFederalCdcc"),
|
|
64000
64284
|
rate: { num, den: "100" },
|
|
@@ -64003,7 +64287,7 @@ var njRules = [
|
|
|
64003
64287
|
const tier = (max2, num, next) => ({
|
|
64004
64288
|
kind: "if",
|
|
64005
64289
|
cond: le(ti, param19(max2)),
|
|
64006
|
-
then:
|
|
64290
|
+
then: pct13(num),
|
|
64007
64291
|
else: next
|
|
64008
64292
|
});
|
|
64009
64293
|
return rd3(tier("tier1Max", "50", tier("tier2Max", "40", tier("tier3Max", "30", tier("tier4Max", "20", tier("tier5Max", "10", money35("0")))))));
|
|
@@ -64475,7 +64759,7 @@ var ohRules = [
|
|
|
64475
64759
|
// $75,000 → 10%; above → 5%
|
|
64476
64760
|
},
|
|
64477
64761
|
formula: (() => {
|
|
64478
|
-
const
|
|
64762
|
+
const pct13 = (num) => ({
|
|
64479
64763
|
kind: "mulRate",
|
|
64480
64764
|
base: max09(fact38("ohTaxLessCredits")),
|
|
64481
64765
|
rate: { num, den: "100" },
|
|
@@ -64484,16 +64768,16 @@ var ohRules = [
|
|
|
64484
64768
|
const tiered = {
|
|
64485
64769
|
kind: "if",
|
|
64486
64770
|
cond: le2(magiLessExemptions, param20("tier1Max")),
|
|
64487
|
-
then:
|
|
64771
|
+
then: pct13("20"),
|
|
64488
64772
|
else: {
|
|
64489
64773
|
kind: "if",
|
|
64490
64774
|
cond: le2(magiLessExemptions, param20("tier2Max")),
|
|
64491
|
-
then:
|
|
64775
|
+
then: pct13("15"),
|
|
64492
64776
|
else: {
|
|
64493
64777
|
kind: "if",
|
|
64494
64778
|
cond: le2(magiLessExemptions, param20("tier3Max")),
|
|
64495
|
-
then:
|
|
64496
|
-
else:
|
|
64779
|
+
then: pct13("10"),
|
|
64780
|
+
else: pct13("5")
|
|
64497
64781
|
}
|
|
64498
64782
|
}
|
|
64499
64783
|
};
|
|
@@ -65729,8 +66013,8 @@ var moRules = [
|
|
|
65729
66013
|
formula: (() => {
|
|
65730
66014
|
const magi2 = fact38("moMagi");
|
|
65731
66015
|
const total = { kind: "max0", arg: fact38("moFederalTaxTotal") };
|
|
65732
|
-
const
|
|
65733
|
-
const uncapped = iff2(le5(magi2, money35("2500000")),
|
|
66016
|
+
const pct13 = (num) => rd8({ kind: "mulRate", base: total, rate: { num, den: "100" }, round: "half-up" });
|
|
66017
|
+
const uncapped = iff2(le5(magi2, money35("2500000")), pct13("35"), iff2(le5(magi2, money35("5000000")), pct13("25"), iff2(le5(magi2, money35("10000000")), pct13("15"), iff2(le5(magi2, money35("12500000")), pct13("5"), money35("0")))));
|
|
65734
66018
|
const cap = iff2({ kind: "cmp", op: "eq", left: fact38("filingStatus"), right: { kind: "enum", value: "mfj" } }, money35("1000000"), money35("500000"));
|
|
65735
66019
|
return { kind: "min", args: [uncapped, cap] };
|
|
65736
66020
|
})()
|
|
@@ -66048,8 +66332,8 @@ var wiRules = [
|
|
|
66048
66332
|
formula: (() => {
|
|
66049
66333
|
const eic = { kind: "max0", arg: fact38("wiFederalEicForWi") };
|
|
66050
66334
|
const kids = fact38("wiQualifyingChildren");
|
|
66051
|
-
const
|
|
66052
|
-
return iff3({ kind: "cmp", op: "ge", left: kids, right: { kind: "int", value: "3" } },
|
|
66335
|
+
const pct13 = (num) => rd9({ kind: "mulRate", base: eic, rate: { num, den: "100" }, round: "half-up" });
|
|
66336
|
+
return iff3({ kind: "cmp", op: "ge", left: kids, right: { kind: "int", value: "3" } }, pct13("34"), iff3({ kind: "cmp", op: "eq", left: kids, right: { kind: "int", value: "2" } }, pct13("11"), iff3({ kind: "cmp", op: "eq", left: kids, right: { kind: "int", value: "1" } }, pct13("4"), money35("0"))));
|
|
66053
66337
|
})()
|
|
66054
66338
|
},
|
|
66055
66339
|
{
|
|
@@ -66387,12 +66671,12 @@ var mnRules = [
|
|
|
66387
66671
|
formula: (() => {
|
|
66388
66672
|
const total = mulInt3(money35("520000"), fact38("mnDependents"));
|
|
66389
66673
|
const threshold2 = iff4({ kind: "or", args: [isStatus12("mfj"), isStatus12("qss")] }, money35("35855000"), iff4(isStatus12("hoh"), money35("29880000"), iff4(isStatus12("mfs"), money35("17927500"), money35("23905000"))));
|
|
66390
|
-
const
|
|
66674
|
+
const excess2 = { kind: "max0", arg: sub8(fact38("mnAgi"), threshold2) };
|
|
66391
66675
|
const cutoff = iff4(isStatus12("mfs"), money35("6125000"), money35("12250000"));
|
|
66392
|
-
const stepsMfs = stepsCeil(
|
|
66393
|
-
const stepsOther = stepsCeil(
|
|
66676
|
+
const stepsMfs = stepsCeil(excess2, "125000");
|
|
66677
|
+
const stepsOther = stepsCeil(excess2, "250000");
|
|
66394
66678
|
const reduction = (steps) => mulInt3({ kind: "mulRate", base: total, rate: { num: "2", den: "100" }, round: "half-up" }, steps);
|
|
66395
|
-
return iff4(fact38("isClaimedAsDependent"), money35("0"), iff4({ kind: "cmp", op: "gt", left:
|
|
66679
|
+
return iff4(fact38("isClaimedAsDependent"), money35("0"), iff4({ kind: "cmp", op: "gt", left: excess2, right: cutoff }, money35("0"), rd10({
|
|
66396
66680
|
kind: "max0",
|
|
66397
66681
|
arg: sub8(total, iff4(isStatus12("mfs"), reduction(stepsMfs), reduction(stepsOther)))
|
|
66398
66682
|
})));
|
|
@@ -66431,8 +66715,8 @@ var mnRules = [
|
|
|
66431
66715
|
formula: (() => {
|
|
66432
66716
|
const ss2 = { kind: "max0", arg: fact38("mnTaxableSs") };
|
|
66433
66717
|
const threshold2 = iff4({ kind: "or", args: [isStatus12("mfj"), isStatus12("qss")] }, money35("10832000"), iff4(isStatus12("mfs"), money35("5416000"), money35("8449000")));
|
|
66434
|
-
const
|
|
66435
|
-
const steps = iff4(isStatus12("mfs"), stepsCeil(
|
|
66718
|
+
const excess2 = { kind: "max0", arg: sub8(fact38("mnAgi"), threshold2) };
|
|
66719
|
+
const steps = iff4(isStatus12("mfs"), stepsCeil(excess2, "200000"), stepsCeil(excess2, "400000"));
|
|
66436
66720
|
const cappedSteps = { kind: "min", args: [steps, { kind: "int", value: "10" }] };
|
|
66437
66721
|
const reduction = mulInt3({ kind: "mulRate", base: ss2, rate: { num: "10", den: "100" }, round: "half-up" }, cappedSteps);
|
|
66438
66722
|
return rd10({ kind: "max0", arg: sub8(ss2, reduction) });
|
|
@@ -66612,9 +66896,9 @@ var scRules = [
|
|
|
66612
66896
|
// $110,000
|
|
66613
66897
|
},
|
|
66614
66898
|
formula: (() => {
|
|
66615
|
-
const phased2 = (base, start,
|
|
66616
|
-
const
|
|
66617
|
-
const reductionRaw = { kind: "mulDiv", a: money35(base), b:
|
|
66899
|
+
const phased2 = (base, start, range2) => {
|
|
66900
|
+
const excess2 = { kind: "max0", arg: sub9(fact38("scAgi"), money35(start)) };
|
|
66901
|
+
const reductionRaw = { kind: "mulDiv", a: money35(base), b: excess2, c: money35(range2), round: "floor" };
|
|
66618
66902
|
const reduction10 = mulInt4(money35("1000"), { kind: "stepUnits", value: reductionRaw, unitCents: "1000", mode: "floor" });
|
|
66619
66903
|
return { kind: "max0", arg: sub9(money35(base), reduction10) };
|
|
66620
66904
|
};
|
|
@@ -66896,10 +67180,10 @@ var alRules = [
|
|
|
66896
67180
|
formula: (() => {
|
|
66897
67181
|
const agi2 = { kind: "max0", arg: fact38("alAgi") };
|
|
66898
67182
|
const chart = (max2, step, floor, start, width) => {
|
|
66899
|
-
const
|
|
67183
|
+
const excess2 = sub10(agi2, money35(start));
|
|
66900
67184
|
const steps = {
|
|
66901
67185
|
kind: "add",
|
|
66902
|
-
args: [{ kind: "stepUnits", value:
|
|
67186
|
+
args: [{ kind: "stepUnits", value: excess2, unitCents: width, mode: "floor" }, { kind: "int", value: "1" }]
|
|
66903
67187
|
};
|
|
66904
67188
|
const reduced = { kind: "max", args: [sub10(money35(max2), mulInt5(money35(step), steps)), money35(floor)] };
|
|
66905
67189
|
return iff6(lt8(agi2, money35(start)), money35(max2), reduced);
|
|
@@ -67271,8 +67555,8 @@ var orRules = [
|
|
|
67271
67555
|
formula: (() => {
|
|
67272
67556
|
const qi = fact38("orKidsQualifyingIncome");
|
|
67273
67557
|
const base = iff7({ kind: "cmp", op: "gt", left: fact38("orKidsUnder6"), right: { kind: "int", value: "5" } }, mulInt6(money35("105000"), { kind: "int", value: "5" }), mulInt6(money35("105000"), fact38("orKidsUnder6")));
|
|
67274
|
-
const
|
|
67275
|
-
const hundredths = { kind: "mulDiv", a:
|
|
67558
|
+
const excess2 = { kind: "max0", arg: sub11(qi, money35("2655000")) };
|
|
67559
|
+
const hundredths = { kind: "mulDiv", a: excess2, b: money35("100"), c: money35("500000"), round: "half-up" };
|
|
67276
67560
|
const reduction = { kind: "mulDiv", a: base, b: hundredths, c: money35("100"), round: "half-up" };
|
|
67277
67561
|
const credit = { kind: "max0", arg: sub11(base, reduction) };
|
|
67278
67562
|
return iff7({ kind: "cmp", op: "ge", left: qi, right: money35("3155000") }, money35("0"), iff7(isStatus15("mfs"), money35("0"), rd13(credit)));
|
|
@@ -67357,8 +67641,8 @@ var times = (base, num) => ({ kind: "mulRate", base, rate: { num, den: "1" }, ro
|
|
|
67357
67641
|
var scaled = (cents) => times(money35(cents), "10000");
|
|
67358
67642
|
var dollarsFromScaled = (n) => times({ kind: "mulDiv", a: n, b: money35("1"), c: money35("1000000"), round: "half-up" }, "100");
|
|
67359
67643
|
var scaledSchedule = (base, rows) => add8(...rows.map((r, i) => {
|
|
67360
|
-
const
|
|
67361
|
-
const portion = i + 1 < rows.length ? { kind: "clamp", value:
|
|
67644
|
+
const excess2 = sub12(base, money35(r.thresholdCents));
|
|
67645
|
+
const portion = i + 1 < rows.length ? { kind: "clamp", value: excess2, lo: money35("0"), hi: money35(String(BigInt(rows[i + 1].thresholdCents) - BigInt(r.thresholdCents))) } : max012(excess2);
|
|
67362
67646
|
return times(portion, r.rateNum);
|
|
67363
67647
|
}));
|
|
67364
67648
|
var SCHED_2025_S = [
|
|
@@ -67912,8 +68196,8 @@ var stepsOver = (agi2, startCents, unitCents, maxUnits) => {
|
|
|
67912
68196
|
var times2 = (base, num) => ({ kind: "mulRate", base, rate: { num, den: "1" }, round: "half-up" });
|
|
67913
68197
|
var dollarsFromScaled2 = (n, denCents) => times2({ kind: "mulDiv", a: n, b: money35("1"), c: money35(denCents), round: "half-up" }, "100");
|
|
67914
68198
|
var scaledSchedule2 = (base, rows) => add9(...rows.map((r, i) => {
|
|
67915
|
-
const
|
|
67916
|
-
const portion = i + 1 < rows.length ? { kind: "clamp", value:
|
|
68199
|
+
const excess2 = sub13(base, money35(r.thresholdCents));
|
|
68200
|
+
const portion = i + 1 < rows.length ? { kind: "clamp", value: excess2, lo: money35("0"), hi: money35(String(BigInt(rows[i + 1].thresholdCents) - BigInt(r.thresholdCents))) } : max013(excess2);
|
|
67917
68201
|
return times2(portion, r.rateNum);
|
|
67918
68202
|
}));
|
|
67919
68203
|
var bands = (agi2, rows, beyond, wrap) => {
|
|
@@ -68139,15 +68423,15 @@ var tcsFor = (agi2, s, method) => {
|
|
|
68139
68423
|
const taxable3 = max013(sub13(agi2, exemptionFor(agi2, s)));
|
|
68140
68424
|
const scaledTax = scaledSchedule2(taxable3, SCHED[s]);
|
|
68141
68425
|
const cAndD = add9(addbackFor(agi2, s), recaptureFor(agi2, s));
|
|
68142
|
-
const
|
|
68426
|
+
const pct13 = creditPctFor(agi2, s);
|
|
68143
68427
|
if (method === "schedule") {
|
|
68144
68428
|
const line4 = dollarsFromScaled2(scaledTax, "1000000");
|
|
68145
68429
|
const line72 = add9(line4, cAndD);
|
|
68146
|
-
const line92 = rd15({ kind: "mulDiv", a: line72, b: mulInt8(money35("1"),
|
|
68430
|
+
const line92 = rd15({ kind: "mulDiv", a: line72, b: mulInt8(money35("1"), pct13), c: money35("100"), round: "half-up" });
|
|
68147
68431
|
return sub13(line72, line92);
|
|
68148
68432
|
}
|
|
68149
68433
|
const totalScaled = add9(scaledTax, times2(cAndD, "10000"));
|
|
68150
|
-
const keep = sub13(int5("100"),
|
|
68434
|
+
const keep = sub13(int5("100"), pct13);
|
|
68151
68435
|
const scaledAfterCredit = mulInt8(totalScaled, keep);
|
|
68152
68436
|
return dollarsFromScaled2(scaledAfterCredit, "100000000");
|
|
68153
68437
|
};
|
|
@@ -68424,8 +68708,8 @@ var isKsHoh = { kind: "or", args: [isStatus18("hoh"), isStatus18("qss")] };
|
|
|
68424
68708
|
var times3 = (base, num) => ({ kind: "mulRate", base, rate: { num, den: "1" }, round: "half-up" });
|
|
68425
68709
|
var dollarsFromScaled3 = (n, denCents) => times3({ kind: "mulDiv", a: n, b: money35("1"), c: money35(denCents), round: "half-up" }, "100");
|
|
68426
68710
|
var scaledSchedule3 = (base, rows) => add10(...rows.map((r, i) => {
|
|
68427
|
-
const
|
|
68428
|
-
const portion = i + 1 < rows.length ? { kind: "clamp", value:
|
|
68711
|
+
const excess2 = sub14(base, money35(r.thresholdCents));
|
|
68712
|
+
const portion = i + 1 < rows.length ? { kind: "clamp", value: excess2, lo: money35("0"), hi: money35(String(BigInt(rows[i + 1].thresholdCents) - BigInt(r.thresholdCents))) } : max014(excess2);
|
|
68429
68713
|
return times3(portion, r.rateNum);
|
|
68430
68714
|
}));
|
|
68431
68715
|
var SCHED_MFJ2 = [
|
|
@@ -68897,8 +69181,8 @@ var isMfs3 = isStatus19("mfs");
|
|
|
68897
69181
|
var times4 = (base, num) => ({ kind: "mulRate", base, rate: { num, den: "1" }, round: "half-up" });
|
|
68898
69182
|
var dollarsFromScaled4 = (n, denCents) => times4({ kind: "mulDiv", a: n, b: money35("1"), c: money35(denCents), round: "half-up" }, "100");
|
|
68899
69183
|
var scaledSchedule4 = (base, rows) => add11(...rows.map((r, i) => {
|
|
68900
|
-
const
|
|
68901
|
-
const portion = i + 1 < rows.length ? { kind: "clamp", value:
|
|
69184
|
+
const excess2 = sub15(base, money35(r.thresholdCents));
|
|
69185
|
+
const portion = i + 1 < rows.length ? { kind: "clamp", value: excess2, lo: money35("0"), hi: money35(String(BigInt(rows[i + 1].thresholdCents) - BigInt(r.thresholdCents))) } : max015(excess2);
|
|
68902
69186
|
return times4(portion, r.rateNum);
|
|
68903
69187
|
}));
|
|
68904
69188
|
var dollars3 = (d3) => money35(String(d3) + "00");
|
|
@@ -69132,8 +69416,8 @@ var arRules = [
|
|
|
69132
69416
|
const earned2 = max015(fact38("arEarnedIncome"));
|
|
69133
69417
|
const l6 = iff11(isMfj2, minE(l3, earned2, max015(fact38("arSpouseEarnedIncome"))), minE(l3, earned2));
|
|
69134
69418
|
const steps = stepUnits2(max015(sub15(fact38("arFederalAgi"), money35("1500000"))), "200000", "ceil");
|
|
69135
|
-
const
|
|
69136
|
-
const l9 = rd17({ kind: "mulDiv", a: l6, b:
|
|
69419
|
+
const pct13 = maxE(sub15(money35("35"), mulInt10(money35("1"), steps)), money35("20"));
|
|
69420
|
+
const l9 = rd17({ kind: "mulDiv", a: l6, b: pct13, c: money35("100"), round: "half-up" });
|
|
69137
69421
|
return rd17({ kind: "mulRate", base: l9, rate: { num: "20", den: "100" }, round: "half-up" });
|
|
69138
69422
|
})()
|
|
69139
69423
|
},
|
|
@@ -69347,8 +69631,8 @@ var isMfs4 = isStatus20("mfs");
|
|
|
69347
69631
|
var times5 = (base, num) => ({ kind: "mulRate", base, rate: { num, den: "1" }, round: "half-up" });
|
|
69348
69632
|
var dollarsFromScaled5 = (n, denCents) => times5({ kind: "mulDiv", a: n, b: money35("1"), c: money35(denCents), round: "half-up" }, "100");
|
|
69349
69633
|
var scaledSchedule5 = (base, rows) => add12(...rows.map((r, i) => {
|
|
69350
|
-
const
|
|
69351
|
-
const portion = i + 1 < rows.length ? { kind: "clamp", value:
|
|
69634
|
+
const excess2 = sub16(base, money35(r.thresholdCents));
|
|
69635
|
+
const portion = i + 1 < rows.length ? { kind: "clamp", value: excess2, lo: money35("0"), hi: money35(String(BigInt(rows[i + 1].thresholdCents) - BigInt(r.thresholdCents))) } : max016(excess2);
|
|
69352
69636
|
return times5(portion, r.rateNum);
|
|
69353
69637
|
}));
|
|
69354
69638
|
var dollars4 = (d3) => money35(String(d3) + "00");
|
|
@@ -69863,8 +70147,8 @@ var times6 = (base, num) => ({ kind: "mulRate", base, rate: { num, den: "1" }, r
|
|
|
69863
70147
|
var pct4 = (base, num, den) => ({ kind: "mulRate", base, rate: { num, den }, round: "half-up" });
|
|
69864
70148
|
var dollarsFromScaled6 = (n, denCents) => times6({ kind: "mulDiv", a: n, b: money35("1"), c: money35(denCents), round: "half-up" }, "100");
|
|
69865
70149
|
var scaledSchedule6 = (base, rows) => add13(...rows.map((r, i) => {
|
|
69866
|
-
const
|
|
69867
|
-
const portion = i + 1 < rows.length ? { kind: "clamp", value:
|
|
70150
|
+
const excess2 = sub17(base, money35(r.thresholdCents));
|
|
70151
|
+
const portion = i + 1 < rows.length ? { kind: "clamp", value: excess2, lo: money35("0"), hi: money35(String(BigInt(rows[i + 1].thresholdCents) - BigInt(r.thresholdCents))) } : max017(excess2);
|
|
69868
70152
|
return times6(portion, r.rateNum);
|
|
69869
70153
|
}));
|
|
69870
70154
|
var calcSchedule = (base, rows) => {
|
|
@@ -70765,8 +71049,8 @@ var times7 = (base, num) => ({ kind: "mulRate", base, rate: { num, den: "1" }, r
|
|
|
70765
71049
|
var pct6 = (base, num, den) => ({ kind: "mulRate", base, rate: { num, den }, round: "half-up" });
|
|
70766
71050
|
var dollarsFromScaled8 = (n) => times7({ kind: "mulDiv", a: n, b: money35("1"), c: money35("1000000"), round: "half-up" }, "100");
|
|
70767
71051
|
var scaledSchedule7 = (base, rows) => add15(...rows.map((r, i) => {
|
|
70768
|
-
const
|
|
70769
|
-
const portion = i + 1 < rows.length ? { kind: "clamp", value:
|
|
71052
|
+
const excess2 = sub19(base, money35(r.thresholdCents));
|
|
71053
|
+
const portion = i + 1 < rows.length ? { kind: "clamp", value: excess2, lo: money35("0"), hi: money35(String(BigInt(rows[i + 1].thresholdCents) - BigInt(r.thresholdCents))) } : max019(excess2);
|
|
70770
71054
|
return times7(portion, r.rateNum);
|
|
70771
71055
|
}));
|
|
70772
71056
|
var sched = (rates, mfs) => {
|
|
@@ -73014,7 +73298,7 @@ var FORMS4 = "https://revenuefiles.delaware.gov/2025/PITForms_Instructions/";
|
|
|
73014
73298
|
var INSTR_URL2 = FORMS4 + "Instructions/PIT-RES_Instructions_2025-01.pdf";
|
|
73015
73299
|
var FORM_URL2 = FORMS4 + "PIT-RES_2025-01_PaperInteractiveIPM.pdf";
|
|
73016
73300
|
var TABLE_URL = "https://revenuefiles.delaware.gov/2025/TY25_taxtable.pdf";
|
|
73017
|
-
var DELC = (
|
|
73301
|
+
var DELC = (sub28) => `https://delcode.delaware.gov/title30/c011/${sub28}/index.html`;
|
|
73018
73302
|
var deRules = [
|
|
73019
73303
|
{
|
|
73020
73304
|
id: "us.de.income_tax",
|
|
@@ -73435,8 +73719,8 @@ var ndRules = [
|
|
|
73435
73719
|
parameters: { maximumCredit: { value: "31200", type: "money" }, taxableIncomeFloor: { value: "8103600", type: "money" }, lowerIncomeFloor: { value: "4755000", type: "money" }, halfJointStandardDeduction: { value: "1575000", type: "money" } },
|
|
73436
73720
|
formula: (() => {
|
|
73437
73721
|
const eligible = and9(isStatus30("mfj"), gt13(fact38("ndTaxableIncome"), money35("8103600")), gt13(fact38("ndLowerQualifiedIncome"), money35("4755000")));
|
|
73438
|
-
const
|
|
73439
|
-
return iff21(eligible, minE11(
|
|
73722
|
+
const excess2 = max025(sub25(max025(fact38("ndJointScheduleTax")), add21(max025(fact38("ndSingleScheduleTaxA")), max025(fact38("ndSingleScheduleTaxB")))));
|
|
73723
|
+
return iff21(eligible, minE11(excess2, money35("31200")), money35("0"));
|
|
73440
73724
|
})()
|
|
73441
73725
|
},
|
|
73442
73726
|
{
|
|
@@ -74557,133 +74841,275 @@ var stateParameterRules = [
|
|
|
74557
74841
|
...otherStateRules
|
|
74558
74842
|
];
|
|
74559
74843
|
|
|
74560
|
-
// ../corpus-us-federal/dist/rules/qbi.js
|
|
74844
|
+
// ../corpus-us-federal/dist/rules/qbi-businesses.js
|
|
74845
|
+
var J29 = "us.federal";
|
|
74561
74846
|
var fact39 = (factId) => ({ kind: "fact", factId });
|
|
74562
74847
|
var money36 = (cents) => ({ kind: "money", cents });
|
|
74848
|
+
var int15 = (value) => ({ kind: "int", value });
|
|
74563
74849
|
var ruleRef33 = (ruleId) => ({ kind: "rule", ruleId });
|
|
74564
|
-
var param23 = (name) => ({ kind: "param", name });
|
|
74565
74850
|
var zero26 = money36("0");
|
|
74566
|
-
var
|
|
74567
|
-
|
|
74568
|
-
|
|
74569
|
-
|
|
74570
|
-
|
|
74571
|
-
});
|
|
74851
|
+
var add23 = (...args) => ({ kind: "add", args });
|
|
74852
|
+
var sub27 = (left, right) => ({ kind: "sub", left, right });
|
|
74853
|
+
var max027 = (arg) => ({ kind: "max0", arg });
|
|
74854
|
+
var min6 = (...args) => ({ kind: "min", args });
|
|
74855
|
+
var neg2 = (e) => sub27(zero26, e);
|
|
74856
|
+
var cmp16 = (op, left, right) => ({ kind: "cmp", op, left, right });
|
|
74857
|
+
var iff23 = (cond, then, els) => ({ kind: "if", cond, then, else: els });
|
|
74858
|
+
var and11 = (...args) => ({ kind: "and", args });
|
|
74859
|
+
var pct11 = (num, den, base) => ({ kind: "mulRate", base, rate: { num, den }, round: "half-up" });
|
|
74860
|
+
var isStatus32 = (status) => cmp16("eq", fact39("filingStatus"), { kind: "enum", value: status });
|
|
74861
|
+
var CORNELL = "https://www.law.cornell.edu/uscode/text/26/199A";
|
|
74862
|
+
var REG_1 = "https://www.law.cornell.edu/cfr/text/26/1.199A-1";
|
|
74863
|
+
var REG_4 = "https://www.law.cornell.edu/cfr/text/26/1.199A-4";
|
|
74864
|
+
var QBI_LISTED = 5;
|
|
74865
|
+
var QBI_UNITS = [
|
|
74866
|
+
{ key: "main", label: "the main business (QBI not listed separately)", w2Fact: "qbiW2Wages", ubiaFact: "qbiUBIA", sstbFact: "businessIsSSTB", groupFact: "qbiAggregationGroup" },
|
|
74867
|
+
{ key: "spouse", label: "the second spouse's Schedule C business", w2Fact: "spouseQbiW2Wages", ubiaFact: "spouseQbiUBIA", sstbFact: "spouseBusinessIsSSTB", groupFact: "spouseQbiAggregationGroup" },
|
|
74868
|
+
...Array.from({ length: QBI_LISTED }, (_, i) => {
|
|
74869
|
+
const n = i + 2;
|
|
74870
|
+
return {
|
|
74871
|
+
key: `business${n}`,
|
|
74872
|
+
label: `listed business ${n}`,
|
|
74873
|
+
w2Fact: `qbiBusiness${n}W2Wages`,
|
|
74874
|
+
ubiaFact: `qbiBusiness${n}UBIA`,
|
|
74875
|
+
sstbFact: `qbiBusiness${n}IsSSTB`,
|
|
74876
|
+
groupFact: `qbiBusiness${n}AggregationGroup`
|
|
74877
|
+
};
|
|
74878
|
+
})
|
|
74879
|
+
];
|
|
74880
|
+
var LISTED = QBI_UNITS.slice(2);
|
|
74881
|
+
var id = (u, line2) => `${J29}.qbi.${u.key}.${line2}`;
|
|
74882
|
+
var qbiOf = (u) => ruleRef33(id(u, "qbi"));
|
|
74883
|
+
var presentOf = (u) => ruleRef33(id(u, "present"));
|
|
74884
|
+
var groupOf = (u) => ruleRef33(id(u, "aggregation_group"));
|
|
74885
|
+
var excess = ruleRef33(`${J29}.qbi.excess_over_threshold`);
|
|
74886
|
+
var range = ruleRef33(`${J29}.qbi.phase_in_range`);
|
|
74887
|
+
function rule(ruleId, title, section, url2, excerpt, type, formula, source = "26 U.S.C. \xA7 199A; Form 8995-A (2025) and Schedules A\u2013C") {
|
|
74888
|
+
return {
|
|
74889
|
+
id: ruleId,
|
|
74890
|
+
version: 1,
|
|
74891
|
+
jurisdiction: J29,
|
|
74892
|
+
title,
|
|
74893
|
+
citation: { source, section, url: url2, excerpt },
|
|
74894
|
+
effectiveFrom: "2025-01-01",
|
|
74895
|
+
output: { type },
|
|
74896
|
+
formula
|
|
74897
|
+
};
|
|
74898
|
+
}
|
|
74899
|
+
var scheduleCPool = add23(max027(sub27(fact39("selfEmploymentNetProfit"), add23(ruleRef33(`${J29}.se_tax_half_deduction.taxpayer`), ruleRef33(`${J29}.sep_deduction`), ruleRef33(`${J29}.sehi_deduction`)))), fact39("k1OrdinaryBusinessIncome"));
|
|
74900
|
+
var listedProfits = add23(...LISTED.map((u) => max027(qbiOf(u))));
|
|
74901
|
+
var listedLosses = add23(...LISTED.map((u) => max027(neg2(qbiOf(u)))));
|
|
74902
|
+
var rawQbiRules = [
|
|
74903
|
+
rule(id(QBI_UNITS[0], "qbi"), "QBI of the main business: the return's Schedule C and K-1 QBI less qbiLossOffset, less every listed business", "\xA7 199A(c); Reg. \xA7 1.199A-3(b)(1)(vi)", "https://www.law.cornell.edu/cfr/text/26/1.199A-3", "QBI includes the deductible part of self-employment tax, the self-employed health insurance deduction and contributions to qualified retirement plans attributable to the trade or business. [Main = max(0, selfEmploymentNetProfit \u2212 its \xBD-SE, SEP and SE-health deductions) + k1OrdinaryBusinessIncome \u2212 qbiLossOffset, less each listed business: a listed profit comes out of the Schedule C / K-1 QBI and a listed loss out of qbiLossOffset; listing more than the return holds is refused.]", "money", iff23(cmp16("gt", listedProfits, scheduleCPool), {
|
|
74904
|
+
kind: "unsupported",
|
|
74905
|
+
reason: "the listed businesses' QBI (qbiBusiness2Income\u2013qbiBusiness6Income) is more than the return's Schedule C and K-1 QBI: a listed business must already be in the totals (selfEmploymentNetProfit or k1OrdinaryBusinessIncome)"
|
|
74906
|
+
}, iff23(cmp16("gt", listedLosses, fact39("qbiLossOffset")), {
|
|
74907
|
+
kind: "unsupported",
|
|
74908
|
+
reason: "the listed businesses' QBI losses are more than qbiLossOffset: a listed loss business's QBI loss must already be in qbiLossOffset"
|
|
74909
|
+
}, sub27(sub27(scheduleCPool, listedProfits), sub27(fact39("qbiLossOffset"), listedLosses))))),
|
|
74910
|
+
rule(id(QBI_UNITS[1], "qbi"), "QBI of the second spouse's Schedule C business (net of their own \xBD-SE deduction)", "\xA7 199A(c); Reg. \xA7 1.199A-3(b)(1)(vi)", "https://www.law.cornell.edu/cfr/text/26/1.199A-3", "QBI includes the deductible part of self-employment tax attributable to the trade or business. [On a joint return the second spouse's Schedule C is its own trade or business: their net profit less their own \xBD-SE deduction. Their SEP, solo 401(k) and SE health insurance are not modeled (those inputs are the first spouse's).]", "money", max027(sub27(ruleRef33(`${J29}.se_net_profit.spouse`), ruleRef33(`${J29}.se_tax_half_deduction.spouse`)))),
|
|
74911
|
+
...LISTED.map((u, i) => rule(id(u, "qbi"), `QBI of ${u.label} (qbiBusiness${i + 2}Income, when qbiAdditionalBusinesses \u2265 ${i + 1})`, "\xA7 199A(c)(1)", CORNELL, "The term 'qualified business income' means, for any taxable year, the net amount of qualified items of income, gain, deduction, and loss with respect to any qualified trade or business of the taxpayer. [Entered per business, a loss as a negative number; read only when the return lists at least this many businesses.]", "money", iff23(cmp16("ge", fact39("qbiAdditionalBusinesses"), int15(String(i + 1))), fact39(`qbiBusiness${i + 2}Income`), zero26))),
|
|
74912
|
+
rule(`${J29}.qbi.total`, "Total QBI of all businesses (Form 8995 line 2)", "\xA7 199A(c)", CORNELL, "Qualified business income... with respect to any qualified trade or business of the taxpayer. [The sum over every business, losses included; the prior-year carryforward is separate.]", "money", add23(...QBI_UNITS.map(qbiOf))),
|
|
74913
|
+
...QBI_UNITS.map((u, i) => rule(id(u, "present"), `Whether the return has ${u.label}`, "Reg. \xA7 1.199A-4(b)", REG_4, i === 0 ? "[The main business is present when it has QBI or a QBI loss, or above the threshold when it has W-2 wages or UBIA: a business that breaks even can still bring its W-2 wages and UBIA to an aggregation group.]" : i === 1 ? "[The second spouse's business is present when it has QBI.]" : `[A listed business is present whenever the return lists it (qbiAdditionalBusinesses \u2265 ${i - 1}), even at zero QBI: a business that breaks even can still bring its W-2 wages and UBIA to an aggregation group.]`, "bool", i === 0 ? {
|
|
74914
|
+
kind: "or",
|
|
74915
|
+
args: [
|
|
74916
|
+
cmp16("ne", qbiOf(u), zero26),
|
|
74917
|
+
and11(cmp16("gt", excess, zero26), { kind: "or", args: [cmp16("gt", fact39(u.w2Fact), zero26), cmp16("gt", fact39(u.ubiaFact), zero26)] })
|
|
74918
|
+
]
|
|
74919
|
+
} : i === 1 ? cmp16("ne", qbiOf(u), zero26) : cmp16("ge", fact39("qbiAdditionalBusinesses"), int15(String(i - 1))))),
|
|
74920
|
+
rule(`${J29}.qbi.business_count`, "Number of businesses on the return", "Reg. \xA7 1.199A-4(a)", REG_4, "[Counts the businesses present; aggregation is asked about only when there are two or more.]", "int", add23(...QBI_UNITS.map((u) => iff23(presentOf(u), int15("1"), int15("0")))))
|
|
74921
|
+
];
|
|
74922
|
+
var thresholdRules = [
|
|
74923
|
+
{
|
|
74924
|
+
id: `${J29}.qbi.threshold`,
|
|
74925
|
+
version: 1,
|
|
74926
|
+
jurisdiction: J29,
|
|
74927
|
+
title: "\xA7 199A threshold amount (TY2025)",
|
|
74928
|
+
citation: {
|
|
74929
|
+
source: "26 U.S.C. \xA7 199A(e)(2); Rev. Proc. 2024-40 \xA7 2.27",
|
|
74930
|
+
section: "\xA7 199A(e)(2)",
|
|
74931
|
+
url: CORNELL,
|
|
74932
|
+
excerpt: "Threshold amount: $394,600 married filing jointly, $197,300 for all others (including married filing separately)."
|
|
74933
|
+
},
|
|
74934
|
+
effectiveFrom: "2025-01-01",
|
|
74935
|
+
effectiveTo: "2026-01-01",
|
|
74936
|
+
output: { type: "money" },
|
|
74937
|
+
formula: iff23(isStatus32("mfj"), money36("39460000"), money36("19730000"))
|
|
74938
|
+
},
|
|
74939
|
+
{
|
|
74940
|
+
id: `${J29}.qbi.threshold`,
|
|
74941
|
+
version: 2,
|
|
74942
|
+
jurisdiction: J29,
|
|
74943
|
+
title: "\xA7 199A threshold amount (TY2026)",
|
|
74944
|
+
citation: {
|
|
74945
|
+
source: "26 U.S.C. \xA7 199A(e)(2); Rev. Proc. 2025-32 \xA7 4.26",
|
|
74946
|
+
section: "\xA7 199A(e)(2)",
|
|
74947
|
+
url: CORNELL,
|
|
74948
|
+
excerpt: "Threshold amount: $403,500 married filing jointly, $201,775 married filing separately, $201,750 for all others."
|
|
74949
|
+
},
|
|
74950
|
+
effectiveFrom: "2026-01-01",
|
|
74951
|
+
effectiveTo: "2027-01-01",
|
|
74952
|
+
output: { type: "money" },
|
|
74953
|
+
formula: {
|
|
74954
|
+
kind: "match",
|
|
74955
|
+
on: fact39("filingStatus"),
|
|
74956
|
+
cases: [
|
|
74957
|
+
{ when: "mfj", value: money36("40350000") },
|
|
74958
|
+
{ when: "mfs", value: money36("20177500") },
|
|
74959
|
+
{ when: "single", value: money36("20175000") },
|
|
74960
|
+
{ when: "hoh", value: money36("20175000") },
|
|
74961
|
+
{ when: "qss", value: money36("20175000") }
|
|
74962
|
+
]
|
|
74963
|
+
}
|
|
74964
|
+
},
|
|
74965
|
+
{
|
|
74966
|
+
id: `${J29}.qbi.phase_in_range`,
|
|
74967
|
+
version: 1,
|
|
74968
|
+
jurisdiction: J29,
|
|
74969
|
+
title: "\xA7 199A phase-in range (TY2025: $50,000, $100,000 joint)",
|
|
74970
|
+
citation: {
|
|
74971
|
+
source: "26 U.S.C. \xA7 199A(b)(3)(B), (d)(3) as enacted by Pub. L. 115-97",
|
|
74972
|
+
section: "\xA7 199A(b)(3)(B)(ii)(II)",
|
|
74973
|
+
url: CORNELL,
|
|
74974
|
+
excerpt: "Form 8995-A line 23: Phase-in range. Enter $50,000 ($100,000 if married filing jointly)."
|
|
74975
|
+
},
|
|
74976
|
+
effectiveFrom: "2025-01-01",
|
|
74977
|
+
effectiveTo: "2026-01-01",
|
|
74978
|
+
output: { type: "money" },
|
|
74979
|
+
formula: iff23(isStatus32("mfj"), money36("10000000"), money36("5000000"))
|
|
74980
|
+
},
|
|
74981
|
+
{
|
|
74982
|
+
id: `${J29}.qbi.phase_in_range`,
|
|
74983
|
+
version: 2,
|
|
74984
|
+
jurisdiction: J29,
|
|
74985
|
+
title: "\xA7 199A phase-in range (TY2026: $75,000, $150,000 joint \u2014 OBBBA \xA7 70105)",
|
|
74986
|
+
citation: {
|
|
74987
|
+
source: "26 U.S.C. \xA7 199A(b)(3)(B), (d)(3) as amended by OBBBA \xA7 70105",
|
|
74988
|
+
section: "\xA7 199A(b)(3)(B)(ii)(II)",
|
|
74989
|
+
url: CORNELL,
|
|
74990
|
+
excerpt: "For taxable years beginning after December 31, 2025, the phase-in range is $75,000 ($150,000 for a joint return)."
|
|
74991
|
+
},
|
|
74992
|
+
effectiveFrom: "2026-01-01",
|
|
74993
|
+
effectiveTo: "2027-01-01",
|
|
74994
|
+
output: { type: "money" },
|
|
74995
|
+
formula: iff23(isStatus32("mfj"), money36("15000000"), money36("7500000"))
|
|
74996
|
+
},
|
|
74997
|
+
rule(`${J29}.qbi.excess_over_threshold`, "Taxable income before the QBI deduction over the \xA7 199A threshold (Form 8995-A line 22)", "\xA7 199A(b)(3)(B)", CORNELL, "Form 8995-A Part III line 22: subtract line 21 (threshold) from line 20 (taxable income before qualified business income deduction). [Zero at or below the threshold.]", "money", max027(sub27(ruleRef33(`${J29}.taxable_income_before_qbi`), ruleRef33(`${J29}.qbi.threshold`))))
|
|
74998
|
+
];
|
|
74999
|
+
function scheduleA(u, amount) {
|
|
75000
|
+
return iff23(
|
|
75001
|
+
{ kind: "not", arg: presentOf(u) },
|
|
75002
|
+
zero26,
|
|
75003
|
+
// no business, no questions
|
|
75004
|
+
iff23(
|
|
75005
|
+
cmp16("eq", excess, zero26),
|
|
75006
|
+
amount,
|
|
75007
|
+
// at or below the threshold the SSTB rules do not apply
|
|
75008
|
+
iff23(
|
|
75009
|
+
and11(cmp16("eq", qbiOf(u), zero26), cmp16("eq", groupOf(u), int15("0"))),
|
|
75010
|
+
zero26,
|
|
75011
|
+
// breaks even and stands alone: nothing to limit, no SSTB question
|
|
75012
|
+
iff23(fact39(u.sstbFact), iff23(cmp16("ge", excess, range), zero26, { kind: "mulDiv", a: amount, b: sub27(range, excess), c: range, round: "half-up" }), amount)
|
|
75013
|
+
)
|
|
75014
|
+
)
|
|
75015
|
+
);
|
|
75016
|
+
}
|
|
75017
|
+
var scheduleALines = [
|
|
75018
|
+
{ line: "sstb_qbi", title: "QBI after the SSTB applicable percentage", amount: qbiOf, formLine: "Schedule A line 11" },
|
|
75019
|
+
{ line: "sstb_w2_wages", title: "W-2 wages after the SSTB applicable percentage", amount: (u) => fact39(u.w2Fact), formLine: "Schedule A line 12" },
|
|
75020
|
+
{ line: "sstb_ubia", title: "UBIA after the SSTB applicable percentage", amount: (u) => fact39(u.ubiaFact), formLine: "Schedule A line 13" }
|
|
75021
|
+
];
|
|
75022
|
+
var scheduleARules = QBI_UNITS.flatMap((u) => scheduleALines.map(({ line: line2, title, amount, formLine }) => rule(id(u, line2), `${title} \u2014 ${u.label} (${formLine})`, "\xA7 199A(d)(3)", CORNELL, `\xA7 199A(d)(3): a specified service trade or business is a qualified trade or business only for the applicable percentage (100% less the excess over the threshold as a percentage of the phase-in range) of its items, and not at all past the range. [${formLine}; a business that is not an SSTB, or a return at or below the threshold, keeps the full amount. Exact ratio where the form rounds the percentage.]`, "money", scheduleA(u, amount(u)))));
|
|
75023
|
+
var aggregationGroupRules = QBI_UNITS.map((u) => rule(id(u, "aggregation_group"), `Aggregation group of ${u.label} (0 = not aggregated)`, "Reg. \xA7 1.199A-4(b)(1)", REG_4, "An individual may aggregate trades or businesses if... (iii) none of the aggregated trades or businesses can be a specified service trade or business. [Asked only above the threshold, for a business on the return, when the return has two or more businesses; an SSTB in a group is refused.]", "int", iff23(and11(cmp16("gt", excess, zero26), presentOf(u), cmp16("ge", ruleRef33(`${J29}.qbi.business_count`), int15("2"))), iff23(cmp16("eq", fact39(u.groupFact), int15("0")), int15("0"), iff23(fact39(u.sstbFact), {
|
|
75024
|
+
kind: "unsupported",
|
|
75025
|
+
reason: `${u.label} is a specified service trade or business, which may not be aggregated (Reg. \xA7 1.199A-4(b)(1)(iii)): set ${u.groupFact} to 0`
|
|
75026
|
+
}, fact39(u.groupFact))), int15("0"))));
|
|
75027
|
+
function aggregated(u, idx, line2) {
|
|
75028
|
+
const own2 = ruleRef33(id(u, line2));
|
|
75029
|
+
const g = groupOf(u);
|
|
75030
|
+
const earlierInGroup = QBI_UNITS.slice(0, idx).map((v) => cmp16("eq", groupOf(v), g));
|
|
75031
|
+
const members2 = add23(...QBI_UNITS.map((v) => iff23(cmp16("eq", groupOf(v), g), ruleRef33(id(v, line2)), zero26)));
|
|
75032
|
+
return iff23(cmp16("eq", g, int15("0")), own2, earlierInGroup.length === 0 ? members2 : iff23({ kind: "or", args: earlierInGroup }, zero26, members2));
|
|
75033
|
+
}
|
|
75034
|
+
var scheduleBLines = [
|
|
75035
|
+
{ from: "sstb_qbi", line: "aggregated_qbi", what: "QBI" },
|
|
75036
|
+
{ from: "sstb_w2_wages", line: "aggregated_w2_wages", what: "W-2 wages" },
|
|
75037
|
+
{ from: "sstb_ubia", line: "aggregated_ubia", what: "UBIA" }
|
|
75038
|
+
];
|
|
75039
|
+
var scheduleBRules = QBI_UNITS.flatMap((u, idx) => scheduleBLines.map(({ from, line: line2, what }) => rule(id(u, line2), `${what} of ${u.label} after aggregation (Schedule B line 4)`, "Reg. \xA7 1.199A-4(b)(1); Schedule B (Form 8995-A) line 4", REG_4, `Schedule B line 4: total the QBI, W-2 wages and UBIA of the aggregated trades or businesses. [The group's totals sit on its first member in the order main, spouse, business2\u2013business6; the other members carry zero. A business that is not aggregated keeps its own ${what}.]`, "money", aggregated(u, idx, from))));
|
|
75040
|
+
var aggQbi = (u) => ruleRef33(id(u, "aggregated_qbi"));
|
|
75041
|
+
var nettingIncome = ruleRef33(`${J29}.qbi.loss_netting.income`);
|
|
75042
|
+
var nettingNetted = ruleRef33(`${J29}.qbi.loss_netting.netted`);
|
|
75043
|
+
var scheduleCRules = [
|
|
75044
|
+
rule(`${J29}.qbi.loss_netting.losses`, "Business losses with the prior-year carryforward (Schedule C line 3, as a positive amount)", "\xA7 199A(c)(2); Reg. \xA7 1.199A-1(d)(2)(iii)", REG_1, "Schedule C line 3: combine the negative amounts on line 1, column (a), and line 2 (qualified business net loss carryforward from prior years).", "money", add23(fact39("qbiLossCarryforward"), ...QBI_UNITS.map((u) => max027(neg2(aggQbi(u)))))),
|
|
75045
|
+
rule(`${J29}.qbi.loss_netting.income`, "Business income (Schedule C line 4)", "Reg. \xA7 1.199A-1(d)(2)(iii)(A)", REG_1, "Schedule C line 4: add the positive amounts on line 1, column (a), for all trades, businesses, or aggregations.", "money", add23(...QBI_UNITS.map((u) => max027(aggQbi(u))))),
|
|
75046
|
+
rule(`${J29}.qbi.loss_netting.netted`, "Losses netted against other businesses' income (Schedule C line 5)", "Reg. \xA7 1.199A-1(d)(2)(iii)(A)", REG_1, "Schedule C line 5: the smaller of the absolute value of line 3 or line 4.", "money", min6(ruleRef33(`${J29}.qbi.loss_netting.losses`), nettingIncome)),
|
|
75047
|
+
...QBI_UNITS.map((u) => rule(id(u, "adjusted_qbi"), `Adjusted QBI of ${u.label} after loss netting (Schedule C line 1(c))`, "Reg. \xA7 1.199A-1(d)(2)(iii)(A)", REG_1, "If the net QBI from any trade or business is negative, it is apportioned among the trades or businesses with positive QBI in proportion to their relative amounts of QBI. [Schedule C line 1(c): this business's QBI less its share of line 5; zero for a business with no QBI or a loss.]", "money", iff23(cmp16("gt", aggQbi(u), zero26), sub27(aggQbi(u), { kind: "mulDiv", a: nettingNetted, b: aggQbi(u), c: nettingIncome, round: "half-up" }), zero26)))
|
|
75048
|
+
];
|
|
75049
|
+
function component(u) {
|
|
75050
|
+
const adj = ruleRef33(id(u, "adjusted_qbi"));
|
|
75051
|
+
const tentative = pct11("20", "100", adj);
|
|
75052
|
+
const w2 = ruleRef33(id(u, "aggregated_w2_wages"));
|
|
75053
|
+
const ubia = ruleRef33(id(u, "aggregated_ubia"));
|
|
75054
|
+
const wageLimit = {
|
|
75055
|
+
// line 10: greater of 50% of W-2 wages, or 25% of W-2 wages + 2.5% of UBIA
|
|
75056
|
+
kind: "max",
|
|
75057
|
+
args: [pct11("50", "100", w2), add23(pct11("25", "100", w2), pct11("25", "1000", ubia))]
|
|
75058
|
+
};
|
|
75059
|
+
return iff23(
|
|
75060
|
+
cmp16("le", adj, zero26),
|
|
75061
|
+
zero26,
|
|
75062
|
+
// no QBI left: its W-2 wages and UBIA do not count (Schedule C instructions)
|
|
75063
|
+
iff23(
|
|
75064
|
+
cmp16("ge", excess, range),
|
|
75065
|
+
min6(tentative, wageLimit),
|
|
75066
|
+
// line 11
|
|
75067
|
+
sub27(
|
|
75068
|
+
// Part III: line 17 − (line 17 − line 18) × line 24, never below the wage limit
|
|
75069
|
+
tentative,
|
|
75070
|
+
{ kind: "mulDiv", a: max027(sub27(tentative, wageLimit)), b: excess, c: range, round: "half-up" }
|
|
75071
|
+
)
|
|
75072
|
+
)
|
|
75073
|
+
);
|
|
75074
|
+
}
|
|
75075
|
+
var partIIRules = QBI_UNITS.map((u) => rule(id(u, "component"), `QBI component of ${u.label} (Form 8995-A line 15)`, "\xA7 199A(b)(2), (b)(3)", CORNELL, "The combined qualified business income amount is the sum of the lesser of 20 percent of the taxpayer's QBI with respect to the qualified trade or business, or the greater of 50 percent of the W-2 wages, or 25 percent of the W-2 wages plus 2.5 percent of the UBIA of qualified property, with respect to the qualified trade or business. [Form 8995-A lines 3\u201313 for this business; within the phase-in range the excess of 20% of QBI over the wage limit is reduced by the excess-over-threshold fraction (Part III). Exact ratio where the form rounds the percentage.]", "money", component(u)));
|
|
75076
|
+
var totalRules = [
|
|
75077
|
+
rule(`${J29}.qbi.active_total`, "QBI from qualified trades or businesses for the $1,000 test of the \xA7 199A(i) minimum deduction", "\xA7 199A(i)(2), (d)(3)", CORNELL, "\xA7 199A(i): a taxpayer whose aggregate QBI with respect to all active qualified trades or businesses is at least $1,000. Draft 2026 Form 8995 instructions, line 16: aggregate all active qualified business income taken into account for purposes of this form. [At or below the threshold, total QBI; above it, each business after Schedule A, so an SSTB past the phase-in range is not a qualified trade or business and one within it counts at its applicable percentage. The prior-year carryforward is its own line on the form and is not active QBI of this year. Material participation is assumed \u2014 disclosed.]", "money", iff23(cmp16("eq", excess, zero26), ruleRef33(`${J29}.qbi.total`), add23(...QBI_UNITS.map((u) => ruleRef33(id(u, "sstb_qbi")))))),
|
|
75078
|
+
rule(`${J29}.qbi.total_component`, "Total QBI component (Form 8995 line 5 at or below the threshold; Form 8995-A line 16 above it)", "\xA7 199A(b)(1)\u2013(2)", CORNELL, "Form 8995: total QBI (line 2) combined with the prior-year carryforward (line 3), times 20% if more than zero. Form 8995-A line 16: add all amounts reported on line 15.", "money", iff23(cmp16("eq", excess, zero26), pct11("20", "100", max027(sub27(ruleRef33(`${J29}.qbi.total`), fact39("qbiLossCarryforward")))), add23(...QBI_UNITS.map((u) => ruleRef33(id(u, "component")))))),
|
|
75079
|
+
rule(`${J29}.qbi.loss_carryforward`, "Qualified business net loss carried to next year, as a positive amount (Form 8995 line 16; Schedule C line 6)", "\xA7 199A(c)(2)", CORNELL, "If the net amount of qualified business income from all qualified trades or businesses during any taxable year is less than zero, such amount shall be treated as a loss from a qualified trade or business in the succeeding taxable year. [Form 8995 line 16 at or below the threshold; Schedule C (Form 8995-A) line 6 above it.]", "money", iff23(cmp16("eq", excess, zero26), max027(sub27(fact39("qbiLossCarryforward"), ruleRef33(`${J29}.qbi.total`))), sub27(ruleRef33(`${J29}.qbi.loss_netting.losses`), nettingNetted)))
|
|
75080
|
+
];
|
|
75081
|
+
var qbiBusinessRules = [
|
|
75082
|
+
...rawQbiRules,
|
|
75083
|
+
...thresholdRules,
|
|
75084
|
+
...scheduleARules,
|
|
75085
|
+
...aggregationGroupRules,
|
|
75086
|
+
...scheduleBRules,
|
|
75087
|
+
...scheduleCRules,
|
|
75088
|
+
...partIIRules,
|
|
75089
|
+
...totalRules
|
|
75090
|
+
];
|
|
75091
|
+
|
|
75092
|
+
// ../corpus-us-federal/dist/rules/qbi.js
|
|
75093
|
+
var fact40 = (factId) => ({ kind: "fact", factId });
|
|
75094
|
+
var money37 = (cents) => ({ kind: "money", cents });
|
|
75095
|
+
var ruleRef34 = (ruleId) => ({ kind: "rule", ruleId });
|
|
75096
|
+
var param23 = (name) => ({ kind: "param", name });
|
|
75097
|
+
var zero27 = money37("0");
|
|
74572
75098
|
var pctOf3 = (num, den, base) => ({
|
|
74573
75099
|
kind: "mulRate",
|
|
74574
75100
|
base,
|
|
74575
75101
|
rate: { num, den },
|
|
74576
75102
|
round: "half-up"
|
|
74577
75103
|
});
|
|
74578
|
-
var qbi = {
|
|
74579
|
-
kind: "max0",
|
|
74580
|
-
arg: {
|
|
74581
|
-
kind: "sub",
|
|
74582
|
-
left: {
|
|
74583
|
-
kind: "add",
|
|
74584
|
-
args: [
|
|
74585
|
-
{
|
|
74586
|
-
kind: "max0",
|
|
74587
|
-
arg: {
|
|
74588
|
-
kind: "sub",
|
|
74589
|
-
left: ruleRef33("us.federal.se_net_profit"),
|
|
74590
|
-
right: {
|
|
74591
|
-
kind: "add",
|
|
74592
|
-
args: [
|
|
74593
|
-
ruleRef33("us.federal.se_tax_half_deduction"),
|
|
74594
|
-
ruleRef33("us.federal.sep_deduction"),
|
|
74595
|
-
ruleRef33("us.federal.sehi_deduction")
|
|
74596
|
-
]
|
|
74597
|
-
}
|
|
74598
|
-
}
|
|
74599
|
-
},
|
|
74600
|
-
fact39("k1OrdinaryBusinessIncome")
|
|
74601
|
-
]
|
|
74602
|
-
},
|
|
74603
|
-
right: fact39("qbiLossOffset")
|
|
74604
|
-
}
|
|
74605
|
-
};
|
|
74606
75104
|
var hasBusinessIncome = {
|
|
74607
75105
|
kind: "or",
|
|
74608
75106
|
args: [
|
|
74609
|
-
{ kind: "cmp", op: "gt", left:
|
|
74610
|
-
{ kind: "cmp", op: "gt", left:
|
|
75107
|
+
{ kind: "cmp", op: "gt", left: ruleRef34("us.federal.se_net_profit"), right: zero27 },
|
|
75108
|
+
{ kind: "cmp", op: "gt", left: fact40("k1OrdinaryBusinessIncome"), right: zero27 }
|
|
74611
75109
|
]
|
|
74612
75110
|
};
|
|
74613
|
-
var taxableBeforeQbi =
|
|
74614
|
-
|
|
74615
|
-
kind: "max",
|
|
74616
|
-
args: [
|
|
74617
|
-
pctOf3("50", "100", w2),
|
|
74618
|
-
{ kind: "add", args: [pctOf3("25", "100", w2), pctOf3("25", "1000", ubia)] }
|
|
74619
|
-
// 2.5%
|
|
74620
|
-
]
|
|
74621
|
-
});
|
|
74622
|
-
function phasedReduction(tentative, wageLimit, excess, band) {
|
|
74623
|
-
return {
|
|
74624
|
-
kind: "sub",
|
|
74625
|
-
left: tentative,
|
|
74626
|
-
right: {
|
|
74627
|
-
kind: "mulDiv",
|
|
74628
|
-
a: { kind: "max0", arg: { kind: "sub", left: tentative, right: wageLimit } },
|
|
74629
|
-
b: excess,
|
|
74630
|
-
c: band,
|
|
74631
|
-
round: "half-up"
|
|
74632
|
-
}
|
|
74633
|
-
};
|
|
74634
|
-
}
|
|
74635
|
-
function qbiRule(version2, effectiveFrom, effectiveTo, yearLabel, threshold2, bandSingleCents, bandJointCents, source, withMinimum) {
|
|
74636
|
-
const band = {
|
|
74637
|
-
kind: "if",
|
|
74638
|
-
cond: isStatus32("mfj"),
|
|
74639
|
-
then: param23("bandJoint"),
|
|
74640
|
-
else: param23("band")
|
|
74641
|
-
};
|
|
74642
|
-
const excess = {
|
|
74643
|
-
kind: "max0",
|
|
74644
|
-
arg: { kind: "sub", left: taxableBeforeQbi, right: threshold2 }
|
|
74645
|
-
};
|
|
74646
|
-
const excessCapped = { kind: "min", args: [excess, band] };
|
|
74647
|
-
const tentative = pctOf3("20", "100", qbi);
|
|
74648
|
-
const w2 = fact39("qbiW2Wages");
|
|
74649
|
-
const ubia = fact39("qbiUBIA");
|
|
74650
|
-
const nonSstb = {
|
|
74651
|
-
kind: "if",
|
|
74652
|
-
cond: { kind: "cmp", op: "ge", left: excess, right: band },
|
|
74653
|
-
then: { kind: "min", args: [tentative, wageLimitOf(w2, ubia)] },
|
|
74654
|
-
else: phasedReduction(tentative, wageLimitOf(w2, ubia), excessCapped, band)
|
|
74655
|
-
};
|
|
74656
|
-
const remaining = { kind: "max0", arg: { kind: "sub", left: band, right: excess } };
|
|
74657
|
-
const scale = (e) => ({
|
|
74658
|
-
kind: "mulDiv",
|
|
74659
|
-
a: e,
|
|
74660
|
-
b: remaining,
|
|
74661
|
-
c: band,
|
|
74662
|
-
round: "half-up"
|
|
74663
|
-
});
|
|
74664
|
-
const sstb = {
|
|
74665
|
-
kind: "if",
|
|
74666
|
-
cond: { kind: "cmp", op: "ge", left: excess, right: band },
|
|
74667
|
-
then: zero26,
|
|
74668
|
-
else: phasedReduction(pctOf3("20", "100", scale(qbi)), wageLimitOf(scale(w2), scale(ubia)), excessCapped, band)
|
|
74669
|
-
};
|
|
74670
|
-
const businessPart = {
|
|
74671
|
-
kind: "if",
|
|
74672
|
-
cond: { kind: "cmp", op: "eq", left: excess, right: zero26 },
|
|
74673
|
-
then: tentative,
|
|
74674
|
-
// at or below the threshold: no SSTB question, no limits
|
|
74675
|
-
else: {
|
|
74676
|
-
// two spouses' Schedule C businesses: above the threshold each business has its
|
|
74677
|
-
// own W-2/UBIA limit and SSTB status (Form 8995-A Part II, one column each)
|
|
74678
|
-
kind: "if",
|
|
74679
|
-
cond: { kind: "cmp", op: "gt", left: ruleRef33("us.federal.se_net_profit.spouse"), right: zero26 },
|
|
74680
|
-
then: {
|
|
74681
|
-
kind: "unsupported",
|
|
74682
|
-
reason: "both spouses have self-employment income and taxable income is over the \xA7 199A threshold: each business then needs its own W-2 wage/UBIA limit and SSTB test (Form 8995-A Part II), and per-business QBI is not modeled yet"
|
|
74683
|
-
},
|
|
74684
|
-
else: { kind: "if", cond: fact39("businessIsSSTB"), then: sstb, else: nonSstb }
|
|
74685
|
-
}
|
|
74686
|
-
};
|
|
75111
|
+
var taxableBeforeQbi = ruleRef34("us.federal.taxable_income_before_qbi");
|
|
75112
|
+
function qbiRule(version2, effectiveFrom, effectiveTo, yearLabel, source, withMinimum) {
|
|
74687
75113
|
const overall = pctOf3("20", "100", {
|
|
74688
75114
|
kind: "max0",
|
|
74689
75115
|
arg: {
|
|
@@ -74691,15 +75117,15 @@ function qbiRule(version2, effectiveFrom, effectiveTo, yearLabel, threshold2, ba
|
|
|
74691
75117
|
left: taxableBeforeQbi,
|
|
74692
75118
|
right: {
|
|
74693
75119
|
kind: "add",
|
|
74694
|
-
args: [
|
|
75120
|
+
args: [ruleRef34("us.federal.schedule_d.preferential_lt_gain"), fact40("qualifiedDividends")]
|
|
74695
75121
|
}
|
|
74696
75122
|
}
|
|
74697
75123
|
});
|
|
74698
|
-
const limited = { kind: "min", args: [
|
|
75124
|
+
const limited = { kind: "min", args: [ruleRef34("us.federal.qbi.total_component"), overall] };
|
|
74699
75125
|
const withFloor = withMinimum ? {
|
|
74700
75126
|
// OBBBA § 70105: $400 minimum when QBI ≥ $1,000 (TY2026+)
|
|
74701
75127
|
kind: "if",
|
|
74702
|
-
cond: { kind: "cmp", op: "ge", left: qbi, right: param23("minQbiFloor") },
|
|
75128
|
+
cond: { kind: "cmp", op: "ge", left: ruleRef34("us.federal.qbi.active_total"), right: param23("minQbiFloor") },
|
|
74703
75129
|
then: { kind: "max", args: [limited, param23("minDeduction")] },
|
|
74704
75130
|
else: limited
|
|
74705
75131
|
} : limited;
|
|
@@ -74707,91 +75133,60 @@ function qbiRule(version2, effectiveFrom, effectiveTo, yearLabel, threshold2, ba
|
|
|
74707
75133
|
id: "us.federal.qbi_deduction",
|
|
74708
75134
|
version: version2,
|
|
74709
75135
|
jurisdiction: "us.federal",
|
|
74710
|
-
title: `Qualified business income deduction (TY${yearLabel};
|
|
75136
|
+
title: `Qualified business income deduction (TY${yearLabel}; per business, with aggregation and loss netting)`,
|
|
74711
75137
|
citation: {
|
|
74712
75138
|
source: `26 U.S.C. \xA7 199A; ${source}`,
|
|
74713
75139
|
section: "\xA7 199A(a)\u2013(d)",
|
|
74714
75140
|
url: "https://www.law.cornell.edu/uscode/text/26/199A",
|
|
74715
|
-
excerpt: `
|
|
75141
|
+
excerpt: `The lesser of the combined qualified business income amount \u2014 20 percent of each business's QBI, limited above the \xA7 199A(e)(2) threshold by that business's W-2 wages and UBIA and phased in over the ${yearLabel === "2025" ? "$50,000 ($100,000 joint) range" : "OBBBA-widened $75,000 ($150,000 joint) range (\xA7 70105, taxable years after 2025)"}, after the SSTB applicable percentage, aggregation and loss netting (us.federal.qbi.total_component) \u2014 or 20 percent of taxable income (without this deduction) less net capital gain.${withMinimum ? " OBBBA \xA7 70105 $400 minimum deduction with at least $1,000 of QBI (active participation assumed \u2014 disclosed)." : ""} [No REIT/PTP component or cooperative patron reduction; W-2 wages and UBIA default to $0, which is conservative; exact ratios where Form 8995-A rounds percentages \u2014 disclosed.]`
|
|
74716
75142
|
},
|
|
74717
75143
|
effectiveFrom,
|
|
74718
75144
|
effectiveTo,
|
|
74719
75145
|
output: { type: "money" },
|
|
74720
|
-
parameters: {
|
|
74721
|
-
|
|
74722
|
-
|
|
74723
|
-
|
|
74724
|
-
|
|
74725
|
-
|
|
74726
|
-
minQbiFloor: { value: "100000", type: "money" }
|
|
74727
|
-
// $1,000
|
|
74728
|
-
} : {}
|
|
74729
|
-
},
|
|
75146
|
+
parameters: withMinimum ? {
|
|
75147
|
+
minDeduction: { value: "40000", type: "money" },
|
|
75148
|
+
// $400
|
|
75149
|
+
minQbiFloor: { value: "100000", type: "money" }
|
|
75150
|
+
// $1,000
|
|
75151
|
+
} : {},
|
|
74730
75152
|
formula: {
|
|
74731
75153
|
kind: "if",
|
|
74732
75154
|
cond: hasBusinessIncome,
|
|
74733
75155
|
then: withFloor,
|
|
74734
|
-
else:
|
|
75156
|
+
else: zero27
|
|
74735
75157
|
}
|
|
74736
75158
|
};
|
|
74737
75159
|
}
|
|
74738
75160
|
var qbiRules = [
|
|
74739
75161
|
qbiRule(
|
|
74740
|
-
|
|
74741
|
-
//
|
|
75162
|
+
13,
|
|
75163
|
+
// v11 computed one business above the threshold and refused two spouses' businesses; v13 sums each business's component (us.federal.qbi.total_component). v9 counted one self-employed person; v7 counted qualifiedDividends in the § 199A(a)(2)/(e)(3) overall limit
|
|
74742
75164
|
"2025-01-01",
|
|
74743
75165
|
"2026-01-01",
|
|
74744
75166
|
"2025",
|
|
74745
|
-
{
|
|
74746
|
-
kind: "if",
|
|
74747
|
-
cond: isStatus32("mfj"),
|
|
74748
|
-
then: money36("39460000"),
|
|
74749
|
-
// $394,600
|
|
74750
|
-
else: money36("19730000")
|
|
74751
|
-
// $197,300 (incl. MFS)
|
|
74752
|
-
},
|
|
74753
|
-
"5000000",
|
|
74754
|
-
"10000000",
|
|
74755
|
-
// $50,000 / $100,000 band (TCJA)
|
|
74756
75167
|
"Rev. Proc. 2024-40 \xA7 2.27",
|
|
74757
75168
|
false
|
|
74758
75169
|
),
|
|
74759
75170
|
qbiRule(
|
|
74760
|
-
|
|
74761
|
-
//
|
|
75171
|
+
14,
|
|
75172
|
+
// v12 computed one business above the threshold and refused two spouses' businesses; v14 sums each business's component. v10 counted one self-employed person; v8 counted qualifiedDividends in the overall limit
|
|
74762
75173
|
"2026-01-01",
|
|
74763
75174
|
"2027-01-01",
|
|
74764
75175
|
"2026",
|
|
74765
|
-
|
|
74766
|
-
kind: "match",
|
|
74767
|
-
on: fact39("filingStatus"),
|
|
74768
|
-
cases: [
|
|
74769
|
-
{ when: "mfj", value: money36("40350000") },
|
|
74770
|
-
// $403,500
|
|
74771
|
-
{ when: "mfs", value: money36("20177500") },
|
|
74772
|
-
// $201,775
|
|
74773
|
-
{ when: "single", value: money36("20175000") },
|
|
74774
|
-
// $201,750
|
|
74775
|
-
{ when: "hoh", value: money36("20175000") },
|
|
74776
|
-
{ when: "qss", value: money36("20175000") }
|
|
74777
|
-
]
|
|
74778
|
-
},
|
|
74779
|
-
"7500000",
|
|
74780
|
-
"15000000",
|
|
74781
|
-
// $75,000 / $150,000 band (OBBBA § 70105)
|
|
74782
|
-
"Rev. Proc. 2025-32 \xA7 4.26; OBBBA \xA7 70105 (band + $400 minimum)",
|
|
75176
|
+
"Rev. Proc. 2025-32 \xA7 4.26; OBBBA \xA7 70105 (range + $400 minimum)",
|
|
74783
75177
|
true
|
|
74784
|
-
)
|
|
75178
|
+
),
|
|
75179
|
+
...qbiBusinessRules
|
|
74785
75180
|
];
|
|
74786
75181
|
|
|
74787
75182
|
// ../corpus-us-federal/dist/rules/self-employment.js
|
|
74788
|
-
var
|
|
74789
|
-
var
|
|
74790
|
-
var
|
|
75183
|
+
var fact41 = (factId) => ({ kind: "fact", factId });
|
|
75184
|
+
var money38 = (cents) => ({ kind: "money", cents });
|
|
75185
|
+
var ruleRef35 = (ruleId) => ({ kind: "rule", ruleId });
|
|
74791
75186
|
var param24 = (name) => ({ kind: "param", name });
|
|
74792
|
-
var
|
|
74793
|
-
var seNetEarnings =
|
|
74794
|
-
var spouseSeNetEarnings =
|
|
75187
|
+
var zero28 = money38("0");
|
|
75188
|
+
var seNetEarnings = ruleRef35("us.federal.se_net_earnings");
|
|
75189
|
+
var spouseSeNetEarnings = ruleRef35("us.federal.se_net_earnings.spouse");
|
|
74795
75190
|
function seTaxRule(person, version2, effectiveFrom, effectiveTo, wageBaseCents, yearLabel) {
|
|
74796
75191
|
const who = person.key === "taxpayer" ? "first spouse (or the single filer): selfEmploymentNetProfit; Schedule SE line 8a uses socialSecurityWages when given, else box-1 wages" : "second self-employed spouse on a joint return: spouseSelfEmploymentNetProfit; Schedule SE line 8a uses spouseSocialSecurityWages";
|
|
74797
75192
|
const wagesNote = person.key === "taxpayer" ? "reduced by W-2 social security wages (Schedule SE line 8a = box 3; approximated by box 1 when socialSecurityWages is not supplied)" : "reduced by THIS spouse's own W-2 social security wages (Schedule SE line 8a = their box 3, spouseSocialSecurityWages)";
|
|
@@ -74835,10 +75230,10 @@ function seTaxRule(person, version2, effectiveFrom, effectiveTo, wageBaseCents,
|
|
|
74835
75230
|
formula: {
|
|
74836
75231
|
kind: "if",
|
|
74837
75232
|
cond: { kind: "cmp", op: "lt", left: person.netEarnings, right: param24("seFloor") },
|
|
74838
|
-
then:
|
|
75233
|
+
then: zero28,
|
|
74839
75234
|
else: {
|
|
74840
75235
|
kind: "if",
|
|
74841
|
-
cond:
|
|
75236
|
+
cond: fact41("useFormulaMethod"),
|
|
74842
75237
|
then: { kind: "add", args: [oasdi, medicare] },
|
|
74843
75238
|
else: {
|
|
74844
75239
|
// printed Schedule SE: lines 10 and 11 each entered in whole dollars
|
|
@@ -74859,19 +75254,19 @@ var taxpayer = {
|
|
|
74859
75254
|
kind: "if",
|
|
74860
75255
|
cond: {
|
|
74861
75256
|
kind: "or",
|
|
74862
|
-
args: [
|
|
75257
|
+
args: [fact41("socialSecurityWagesProvided"), { kind: "cmp", op: "gt", left: fact41("socialSecurityWages"), right: zero28 }]
|
|
74863
75258
|
},
|
|
74864
|
-
then:
|
|
74865
|
-
else:
|
|
75259
|
+
then: fact41("socialSecurityWages"),
|
|
75260
|
+
else: fact41("wages")
|
|
74866
75261
|
}
|
|
74867
75262
|
};
|
|
74868
75263
|
var spouse = {
|
|
74869
75264
|
key: "spouse",
|
|
74870
75265
|
netEarnings: spouseSeNetEarnings,
|
|
74871
|
-
wagesForBase:
|
|
75266
|
+
wagesForBase: fact41("spouseSocialSecurityWages")
|
|
74872
75267
|
};
|
|
74873
75268
|
function halfDeductionRule(person) {
|
|
74874
|
-
const tax =
|
|
75269
|
+
const tax = ruleRef35(`us.federal.se_tax.${person.key}`);
|
|
74875
75270
|
const half3 = { kind: "mulRate", base: tax, rate: { num: "50", den: "100" }, round: "half-up" };
|
|
74876
75271
|
return {
|
|
74877
75272
|
id: `us.federal.se_tax_half_deduction.${person.key}`,
|
|
@@ -74888,7 +75283,7 @@ function halfDeductionRule(person) {
|
|
|
74888
75283
|
output: { type: "money" },
|
|
74889
75284
|
formula: {
|
|
74890
75285
|
kind: "if",
|
|
74891
|
-
cond:
|
|
75286
|
+
cond: fact41("useFormulaMethod"),
|
|
74892
75287
|
then: half3,
|
|
74893
75288
|
else: { kind: "roundToDollar", value: half3, mode: "half-up" }
|
|
74894
75289
|
}
|
|
@@ -74912,9 +75307,9 @@ var selfEmploymentRules = [
|
|
|
74912
75307
|
formula: {
|
|
74913
75308
|
// asked only on a joint return: no other return has a second spouse's Schedule SE
|
|
74914
75309
|
kind: "if",
|
|
74915
|
-
cond: { kind: "cmp", op: "eq", left:
|
|
74916
|
-
then:
|
|
74917
|
-
else:
|
|
75310
|
+
cond: { kind: "cmp", op: "eq", left: fact41("filingStatus"), right: { kind: "enum", value: "mfj" } },
|
|
75311
|
+
then: fact41("spouseSelfEmploymentNetProfit"),
|
|
75312
|
+
else: zero28
|
|
74918
75313
|
}
|
|
74919
75314
|
},
|
|
74920
75315
|
{
|
|
@@ -74932,7 +75327,7 @@ var selfEmploymentRules = [
|
|
|
74932
75327
|
output: { type: "money" },
|
|
74933
75328
|
formula: {
|
|
74934
75329
|
kind: "add",
|
|
74935
|
-
args: [
|
|
75330
|
+
args: [fact41("selfEmploymentNetProfit"), ruleRef35("us.federal.se_net_profit.spouse")]
|
|
74936
75331
|
}
|
|
74937
75332
|
},
|
|
74938
75333
|
{
|
|
@@ -74951,7 +75346,7 @@ var selfEmploymentRules = [
|
|
|
74951
75346
|
output: { type: "money" },
|
|
74952
75347
|
formula: {
|
|
74953
75348
|
kind: "mulRate",
|
|
74954
|
-
base:
|
|
75349
|
+
base: fact41("selfEmploymentNetProfit"),
|
|
74955
75350
|
rate: { num: "9235", den: "10000" },
|
|
74956
75351
|
round: "half-up"
|
|
74957
75352
|
}
|
|
@@ -74971,7 +75366,7 @@ var selfEmploymentRules = [
|
|
|
74971
75366
|
output: { type: "money" },
|
|
74972
75367
|
formula: {
|
|
74973
75368
|
kind: "mulRate",
|
|
74974
|
-
base:
|
|
75369
|
+
base: ruleRef35("us.federal.se_net_profit.spouse"),
|
|
74975
75370
|
rate: { num: "9235", den: "10000" },
|
|
74976
75371
|
round: "half-up"
|
|
74977
75372
|
}
|
|
@@ -75000,7 +75395,7 @@ var selfEmploymentRules = [
|
|
|
75000
75395
|
output: { type: "money" },
|
|
75001
75396
|
formula: {
|
|
75002
75397
|
kind: "add",
|
|
75003
|
-
args: [
|
|
75398
|
+
args: [ruleRef35("us.federal.se_tax.taxpayer"), ruleRef35("us.federal.se_tax.spouse")]
|
|
75004
75399
|
}
|
|
75005
75400
|
},
|
|
75006
75401
|
halfDeductionRule(taxpayer),
|
|
@@ -75022,25 +75417,25 @@ var selfEmploymentRules = [
|
|
|
75022
75417
|
formula: {
|
|
75023
75418
|
kind: "add",
|
|
75024
75419
|
args: [
|
|
75025
|
-
|
|
75026
|
-
|
|
75420
|
+
ruleRef35("us.federal.se_tax_half_deduction.taxpayer"),
|
|
75421
|
+
ruleRef35("us.federal.se_tax_half_deduction.spouse")
|
|
75027
75422
|
]
|
|
75028
75423
|
}
|
|
75029
75424
|
}
|
|
75030
75425
|
];
|
|
75031
75426
|
|
|
75032
75427
|
// ../corpus-us-federal/dist/rules/senior-deduction.js
|
|
75033
|
-
var
|
|
75034
|
-
var
|
|
75035
|
-
var
|
|
75428
|
+
var fact42 = (factId) => ({ kind: "fact", factId });
|
|
75429
|
+
var money39 = (cents) => ({ kind: "money", cents });
|
|
75430
|
+
var ruleRef36 = (ruleId) => ({ kind: "rule", ruleId });
|
|
75036
75431
|
var param25 = (name) => ({ kind: "param", name });
|
|
75037
75432
|
var isStatus33 = (status) => ({
|
|
75038
75433
|
kind: "cmp",
|
|
75039
75434
|
op: "eq",
|
|
75040
|
-
left:
|
|
75435
|
+
left: fact42("filingStatus"),
|
|
75041
75436
|
right: { kind: "enum", value: status }
|
|
75042
75437
|
});
|
|
75043
|
-
var
|
|
75438
|
+
var zero29 = money39("0");
|
|
75044
75439
|
function perSeniorNet() {
|
|
75045
75440
|
return {
|
|
75046
75441
|
kind: "max0",
|
|
@@ -75053,8 +75448,8 @@ function perSeniorNet() {
|
|
|
75053
75448
|
kind: "max0",
|
|
75054
75449
|
arg: {
|
|
75055
75450
|
kind: "sub",
|
|
75056
|
-
left:
|
|
75057
|
-
right:
|
|
75451
|
+
left: ruleRef36("us.federal.agi"),
|
|
75452
|
+
right: ruleRef36("us.federal.senior_deduction.magi_threshold")
|
|
75058
75453
|
}
|
|
75059
75454
|
},
|
|
75060
75455
|
rate: { num: "6", den: "100" },
|
|
@@ -75091,17 +75486,17 @@ var seniorDeductionRules = [
|
|
|
75091
75486
|
// § 151(d)(5)(C)(v): married taxpayers must file jointly — MFS gets $0.
|
|
75092
75487
|
kind: "if",
|
|
75093
75488
|
cond: isStatus33("mfs"),
|
|
75094
|
-
then:
|
|
75489
|
+
then: zero29,
|
|
75095
75490
|
else: {
|
|
75096
75491
|
// Only compute (and only demand the threshold) when a senior exists.
|
|
75097
75492
|
kind: "if",
|
|
75098
75493
|
cond: {
|
|
75099
75494
|
kind: "or",
|
|
75100
75495
|
args: [
|
|
75101
|
-
|
|
75496
|
+
fact42("isAge65OrOlder"),
|
|
75102
75497
|
{
|
|
75103
75498
|
kind: "and",
|
|
75104
|
-
args: [isStatus33("mfj"),
|
|
75499
|
+
args: [isStatus33("mfj"), fact42("spouseIsAge65OrOlder")]
|
|
75105
75500
|
}
|
|
75106
75501
|
]
|
|
75107
75502
|
},
|
|
@@ -75113,22 +75508,22 @@ var seniorDeductionRules = [
|
|
|
75113
75508
|
args: [
|
|
75114
75509
|
{
|
|
75115
75510
|
kind: "if",
|
|
75116
|
-
cond:
|
|
75511
|
+
cond: fact42("isAge65OrOlder"),
|
|
75117
75512
|
then: perSeniorNet(),
|
|
75118
|
-
else:
|
|
75513
|
+
else: zero29
|
|
75119
75514
|
},
|
|
75120
75515
|
{
|
|
75121
75516
|
kind: "if",
|
|
75122
75517
|
cond: {
|
|
75123
75518
|
kind: "and",
|
|
75124
|
-
args: [isStatus33("mfj"),
|
|
75519
|
+
args: [isStatus33("mfj"), fact42("spouseIsAge65OrOlder")]
|
|
75125
75520
|
},
|
|
75126
75521
|
then: perSeniorNet(),
|
|
75127
|
-
else:
|
|
75522
|
+
else: zero29
|
|
75128
75523
|
}
|
|
75129
75524
|
]
|
|
75130
75525
|
},
|
|
75131
|
-
else:
|
|
75526
|
+
else: zero29
|
|
75132
75527
|
}
|
|
75133
75528
|
}
|
|
75134
75529
|
},
|
|
@@ -75148,17 +75543,17 @@ var seniorDeductionRules = [
|
|
|
75148
75543
|
output: { type: "money" },
|
|
75149
75544
|
formula: {
|
|
75150
75545
|
kind: "match",
|
|
75151
|
-
on:
|
|
75546
|
+
on: fact42("filingStatus"),
|
|
75152
75547
|
cases: [
|
|
75153
75548
|
// $150,000 only "in the case of a joint return"; QSS is not a joint
|
|
75154
75549
|
// return. MFS is excluded from the deduction entirely (never reached).
|
|
75155
|
-
{ when: "mfj", value:
|
|
75550
|
+
{ when: "mfj", value: money39("15000000") },
|
|
75156
75551
|
// $150,000
|
|
75157
|
-
{ when: "single", value:
|
|
75552
|
+
{ when: "single", value: money39("7500000") },
|
|
75158
75553
|
// $75,000
|
|
75159
|
-
{ when: "hoh", value:
|
|
75554
|
+
{ when: "hoh", value: money39("7500000") },
|
|
75160
75555
|
// $75,000
|
|
75161
|
-
{ when: "qss", value:
|
|
75556
|
+
{ when: "qss", value: money39("7500000") }
|
|
75162
75557
|
// $75,000
|
|
75163
75558
|
]
|
|
75164
75559
|
}
|
|
@@ -75166,11 +75561,11 @@ var seniorDeductionRules = [
|
|
|
75166
75561
|
];
|
|
75167
75562
|
|
|
75168
75563
|
// ../corpus-us-federal/dist/rules/social-security.js
|
|
75169
|
-
var
|
|
75170
|
-
var
|
|
75171
|
-
var
|
|
75564
|
+
var fact43 = (factId) => ({ kind: "fact", factId });
|
|
75565
|
+
var money40 = (cents) => ({ kind: "money", cents });
|
|
75566
|
+
var ruleRef37 = (ruleId) => ({ kind: "rule", ruleId });
|
|
75172
75567
|
var param26 = (name) => ({ kind: "param", name });
|
|
75173
|
-
var
|
|
75568
|
+
var pct12 = (num, base) => ({
|
|
75174
75569
|
kind: "mulRate",
|
|
75175
75570
|
base,
|
|
75176
75571
|
rate: { num, den: "100" },
|
|
@@ -75183,53 +75578,53 @@ var magiBase = {
|
|
|
75183
75578
|
left: {
|
|
75184
75579
|
kind: "add",
|
|
75185
75580
|
args: [
|
|
75186
|
-
|
|
75187
|
-
|
|
75188
|
-
|
|
75581
|
+
fact43("wages"),
|
|
75582
|
+
fact43("taxableInterest"),
|
|
75583
|
+
fact43("taxExemptInterest"),
|
|
75189
75584
|
// § 86(b)(2)(B): "increased by the amount of interest… exempt from tax"
|
|
75190
|
-
|
|
75191
|
-
|
|
75192
|
-
|
|
75193
|
-
|
|
75194
|
-
|
|
75195
|
-
|
|
75196
|
-
|
|
75197
|
-
|
|
75198
|
-
|
|
75199
|
-
|
|
75200
|
-
|
|
75201
|
-
|
|
75202
|
-
|
|
75585
|
+
ruleRef37("us.federal.schedule_d.preferential_lt_gain"),
|
|
75586
|
+
fact43("qualifiedDividends"),
|
|
75587
|
+
ruleRef37("us.federal.schedule_d.ordinary_st_gain"),
|
|
75588
|
+
fact43("ordinaryDividends"),
|
|
75589
|
+
ruleRef37("us.federal.se_net_profit"),
|
|
75590
|
+
fact43("k1OrdinaryBusinessIncome"),
|
|
75591
|
+
fact43("taxableIraDistributions"),
|
|
75592
|
+
fact43("taxablePensionsAndAnnuities"),
|
|
75593
|
+
ruleRef37("us.federal.pension.simplified_method_taxable"),
|
|
75594
|
+
fact43("unemploymentCompensation"),
|
|
75595
|
+
fact43("otherOrdinaryIncome"),
|
|
75596
|
+
fact43("scheduleENetIncome"),
|
|
75597
|
+
ruleRef37("us.federal.rental.net_income")
|
|
75203
75598
|
]
|
|
75204
75599
|
},
|
|
75205
75600
|
right: {
|
|
75206
75601
|
kind: "add",
|
|
75207
75602
|
args: [
|
|
75208
|
-
|
|
75209
|
-
|
|
75603
|
+
ruleRef37("us.federal.capital_loss_ordinary_offset"),
|
|
75604
|
+
fact43("nonpassiveScheduleELoss")
|
|
75210
75605
|
]
|
|
75211
75606
|
}
|
|
75212
75607
|
},
|
|
75213
75608
|
right: {
|
|
75214
75609
|
kind: "add",
|
|
75215
75610
|
args: [
|
|
75216
|
-
|
|
75217
|
-
|
|
75611
|
+
ruleRef37("us.federal.above_the_line_adjustments"),
|
|
75612
|
+
ruleRef37("us.federal.ira_deduction")
|
|
75218
75613
|
]
|
|
75219
75614
|
}
|
|
75220
75615
|
};
|
|
75221
|
-
var ss =
|
|
75222
|
-
var provisional = { kind: "add", args: [magiBase,
|
|
75616
|
+
var ss = fact43("socialSecurityBenefits");
|
|
75617
|
+
var provisional = { kind: "add", args: [magiBase, pct12("50", ss)] };
|
|
75223
75618
|
var isMfs10 = {
|
|
75224
75619
|
kind: "cmp",
|
|
75225
75620
|
op: "eq",
|
|
75226
|
-
left:
|
|
75621
|
+
left: fact43("filingStatus"),
|
|
75227
75622
|
right: { kind: "enum", value: "mfs" }
|
|
75228
75623
|
};
|
|
75229
75624
|
var isMfj6 = {
|
|
75230
75625
|
kind: "cmp",
|
|
75231
75626
|
op: "eq",
|
|
75232
|
-
left:
|
|
75627
|
+
left: fact43("filingStatus"),
|
|
75233
75628
|
right: { kind: "enum", value: "mfj" }
|
|
75234
75629
|
};
|
|
75235
75630
|
var byJoint = (joint, other) => ({
|
|
@@ -75270,25 +75665,25 @@ var socialSecurityRules = [
|
|
|
75270
75665
|
},
|
|
75271
75666
|
formula: {
|
|
75272
75667
|
kind: "if",
|
|
75273
|
-
cond: { kind: "cmp", op: "eq", left: ss, right:
|
|
75274
|
-
then:
|
|
75668
|
+
cond: { kind: "cmp", op: "eq", left: ss, right: money40("0") },
|
|
75669
|
+
then: money40("0"),
|
|
75275
75670
|
else: {
|
|
75276
75671
|
kind: "if",
|
|
75277
75672
|
// § 86(c)(1)(C)(ii): the $0 base applies to an MFS filer who did NOT live apart from the
|
|
75278
75673
|
// spouse at all times during the year; one who did is treated as unmarried ($25,000/$34,000)
|
|
75279
|
-
cond: { kind: "and", args: [isMfs10, { kind: "not", arg:
|
|
75674
|
+
cond: { kind: "and", args: [isMfs10, { kind: "not", arg: fact43("mfsLivedApartAllYear") }] },
|
|
75280
75675
|
then: {
|
|
75281
75676
|
kind: "min",
|
|
75282
|
-
args: [
|
|
75677
|
+
args: [pct12("85", ss), pct12("85", { kind: "max0", arg: provisional })]
|
|
75283
75678
|
},
|
|
75284
75679
|
else: {
|
|
75285
75680
|
kind: "min",
|
|
75286
75681
|
args: [
|
|
75287
|
-
|
|
75682
|
+
pct12("85", ss),
|
|
75288
75683
|
{
|
|
75289
75684
|
kind: "add",
|
|
75290
75685
|
args: [
|
|
75291
|
-
|
|
75686
|
+
pct12("85", {
|
|
75292
75687
|
kind: "max0",
|
|
75293
75688
|
arg: {
|
|
75294
75689
|
kind: "sub",
|
|
@@ -75302,8 +75697,8 @@ var socialSecurityRules = [
|
|
|
75302
75697
|
{
|
|
75303
75698
|
kind: "min",
|
|
75304
75699
|
args: [
|
|
75305
|
-
|
|
75306
|
-
|
|
75700
|
+
pct12("50", ss),
|
|
75701
|
+
pct12("50", {
|
|
75307
75702
|
kind: "max0",
|
|
75308
75703
|
arg: {
|
|
75309
75704
|
kind: "sub",
|
|
@@ -75326,14 +75721,14 @@ var socialSecurityRules = [
|
|
|
75326
75721
|
];
|
|
75327
75722
|
|
|
75328
75723
|
// ../corpus-us-federal/dist/rules/standard-deduction.js
|
|
75329
|
-
var
|
|
75330
|
-
var
|
|
75331
|
-
var
|
|
75332
|
-
var
|
|
75724
|
+
var J30 = "us.federal";
|
|
75725
|
+
var fact44 = (factId) => ({ kind: "fact", factId });
|
|
75726
|
+
var money41 = (cents) => ({ kind: "money", cents });
|
|
75727
|
+
var ruleRef38 = (ruleId) => ({ kind: "rule", ruleId });
|
|
75333
75728
|
var isStatus34 = (status) => ({
|
|
75334
75729
|
kind: "cmp",
|
|
75335
75730
|
op: "eq",
|
|
75336
|
-
left:
|
|
75731
|
+
left: fact44("filingStatus"),
|
|
75337
75732
|
right: { kind: "enum", value: status }
|
|
75338
75733
|
});
|
|
75339
75734
|
var standardDeductionRules = [
|
|
@@ -75341,7 +75736,7 @@ var standardDeductionRules = [
|
|
|
75341
75736
|
id: "us.federal.standard_deduction.base_amount",
|
|
75342
75737
|
version: 2,
|
|
75343
75738
|
// v1 held pre-OBBBA Rev. Proc. 2024-40 amounts ($15,000/$30,000/$22,500)
|
|
75344
|
-
jurisdiction:
|
|
75739
|
+
jurisdiction: J30,
|
|
75345
75740
|
title: "Basic standard deduction amount by filing status (TY2025, as amended by OBBBA)",
|
|
75346
75741
|
citation: {
|
|
75347
75742
|
source: "26 U.S.C. \xA7 63(c), as amended by Pub. L. 119-21 (OBBBA) \xA7 70102",
|
|
@@ -75354,17 +75749,17 @@ var standardDeductionRules = [
|
|
|
75354
75749
|
output: { type: "money" },
|
|
75355
75750
|
formula: {
|
|
75356
75751
|
kind: "match",
|
|
75357
|
-
on:
|
|
75752
|
+
on: fact44("filingStatus"),
|
|
75358
75753
|
cases: [
|
|
75359
|
-
{ when: "single", value:
|
|
75754
|
+
{ when: "single", value: money41("1575000") },
|
|
75360
75755
|
// $15,750
|
|
75361
|
-
{ when: "mfs", value:
|
|
75756
|
+
{ when: "mfs", value: money41("1575000") },
|
|
75362
75757
|
// $15,750 (same as single)
|
|
75363
|
-
{ when: "mfj", value:
|
|
75758
|
+
{ when: "mfj", value: money41("3150000") },
|
|
75364
75759
|
// $31,500
|
|
75365
|
-
{ when: "qss", value:
|
|
75760
|
+
{ when: "qss", value: money41("3150000") },
|
|
75366
75761
|
// $31,500 (§ 1(j)(2)(A): "…and Surviving Spouses")
|
|
75367
|
-
{ when: "hoh", value:
|
|
75762
|
+
{ when: "hoh", value: money41("2362500") }
|
|
75368
75763
|
// $23,625
|
|
75369
75764
|
]
|
|
75370
75765
|
}
|
|
@@ -75372,7 +75767,7 @@ var standardDeductionRules = [
|
|
|
75372
75767
|
{
|
|
75373
75768
|
id: "us.federal.standard_deduction.base_amount",
|
|
75374
75769
|
version: 3,
|
|
75375
|
-
jurisdiction:
|
|
75770
|
+
jurisdiction: J30,
|
|
75376
75771
|
title: "Basic standard deduction amount by filing status (TY2026)",
|
|
75377
75772
|
citation: {
|
|
75378
75773
|
source: "26 U.S.C. \xA7 63(c); Rev. Proc. 2025-32",
|
|
@@ -75385,17 +75780,17 @@ var standardDeductionRules = [
|
|
|
75385
75780
|
output: { type: "money" },
|
|
75386
75781
|
formula: {
|
|
75387
75782
|
kind: "match",
|
|
75388
|
-
on:
|
|
75783
|
+
on: fact44("filingStatus"),
|
|
75389
75784
|
cases: [
|
|
75390
|
-
{ when: "single", value:
|
|
75785
|
+
{ when: "single", value: money41("1610000") },
|
|
75391
75786
|
// $16,100
|
|
75392
|
-
{ when: "mfs", value:
|
|
75787
|
+
{ when: "mfs", value: money41("1610000") },
|
|
75393
75788
|
// $16,100 ("single or married filing separately")
|
|
75394
|
-
{ when: "mfj", value:
|
|
75789
|
+
{ when: "mfj", value: money41("3220000") },
|
|
75395
75790
|
// $32,200
|
|
75396
|
-
{ when: "qss", value:
|
|
75791
|
+
{ when: "qss", value: money41("3220000") },
|
|
75397
75792
|
// $32,200 (surviving spouse)
|
|
75398
|
-
{ when: "hoh", value:
|
|
75793
|
+
{ when: "hoh", value: money41("2415000") }
|
|
75399
75794
|
// $24,150
|
|
75400
75795
|
]
|
|
75401
75796
|
}
|
|
@@ -75403,7 +75798,7 @@ var standardDeductionRules = [
|
|
|
75403
75798
|
{
|
|
75404
75799
|
id: "us.federal.standard_deduction.base",
|
|
75405
75800
|
version: 1,
|
|
75406
|
-
jurisdiction:
|
|
75801
|
+
jurisdiction: J30,
|
|
75407
75802
|
title: "Basic standard deduction",
|
|
75408
75803
|
citation: {
|
|
75409
75804
|
source: "26 U.S.C. \xA7 63(c)(2)",
|
|
@@ -75414,12 +75809,12 @@ var standardDeductionRules = [
|
|
|
75414
75809
|
effectiveFrom: "2025-01-01",
|
|
75415
75810
|
// structural: open-ended
|
|
75416
75811
|
output: { type: "money" },
|
|
75417
|
-
formula:
|
|
75812
|
+
formula: ruleRef38("us.federal.standard_deduction.base_amount")
|
|
75418
75813
|
},
|
|
75419
75814
|
{
|
|
75420
75815
|
id: "us.federal.standard_deduction.dependent_limit",
|
|
75421
75816
|
version: 1,
|
|
75422
|
-
jurisdiction:
|
|
75817
|
+
jurisdiction: J30,
|
|
75423
75818
|
title: "Limitation on basic standard deduction of a dependent",
|
|
75424
75819
|
citation: {
|
|
75425
75820
|
source: "26 U.S.C. \xA7 63(c)(5); Rev. Proc. 2024-40 \xA7 2.15(2); Rev. Proc. 2025-32 \xA7 4.14(2)",
|
|
@@ -75431,19 +75826,19 @@ var standardDeductionRules = [
|
|
|
75431
75826
|
effectiveTo: "2027-01-01",
|
|
75432
75827
|
// same dollar amounts apply in 2025 and 2026
|
|
75433
75828
|
output: { type: "money" },
|
|
75434
|
-
applicability:
|
|
75829
|
+
applicability: fact44("isClaimedAsDependent"),
|
|
75435
75830
|
// min(normal base amount, max($1,350, earned income + $450))
|
|
75436
75831
|
// simplified: earned income approximated as wages
|
|
75437
75832
|
formula: {
|
|
75438
75833
|
kind: "min",
|
|
75439
75834
|
args: [
|
|
75440
|
-
|
|
75835
|
+
ruleRef38("us.federal.standard_deduction.base_amount"),
|
|
75441
75836
|
{
|
|
75442
75837
|
kind: "max",
|
|
75443
75838
|
args: [
|
|
75444
|
-
|
|
75839
|
+
money41("135000"),
|
|
75445
75840
|
// $1,350
|
|
75446
|
-
{ kind: "add", args: [
|
|
75841
|
+
{ kind: "add", args: [fact44("wages"), money41("45000")] }
|
|
75447
75842
|
// + $450
|
|
75448
75843
|
]
|
|
75449
75844
|
}
|
|
@@ -75454,7 +75849,7 @@ var standardDeductionRules = [
|
|
|
75454
75849
|
{
|
|
75455
75850
|
id: "us.federal.standard_deduction.mfs_spouse_itemizes",
|
|
75456
75851
|
version: 1,
|
|
75457
|
-
jurisdiction:
|
|
75852
|
+
jurisdiction: J30,
|
|
75458
75853
|
title: "MFS standard deduction is zero when the spouse itemizes",
|
|
75459
75854
|
citation: {
|
|
75460
75855
|
source: "26 U.S.C. \xA7 63(c)(6)(A)",
|
|
@@ -75470,10 +75865,10 @@ var standardDeductionRules = [
|
|
|
75470
75865
|
applicability: {
|
|
75471
75866
|
kind: "if",
|
|
75472
75867
|
cond: isStatus34("mfs"),
|
|
75473
|
-
then:
|
|
75868
|
+
then: fact44("spouseItemizes"),
|
|
75474
75869
|
else: { kind: "bool", value: false }
|
|
75475
75870
|
},
|
|
75476
|
-
formula:
|
|
75871
|
+
formula: money41("0"),
|
|
75477
75872
|
// § 63(c)(6) zeroes the ENTIRE standard deduction (basic + additional),
|
|
75478
75873
|
// so this overrides the sum rule, not just the basic component.
|
|
75479
75874
|
overrides: { ruleId: "us.federal.standard_deduction", priority: 10 }
|
|
@@ -75493,7 +75888,7 @@ var standardDeductionRules = [
|
|
|
75493
75888
|
{
|
|
75494
75889
|
id: "us.federal.standard_deduction",
|
|
75495
75890
|
version: 1,
|
|
75496
|
-
jurisdiction:
|
|
75891
|
+
jurisdiction: J30,
|
|
75497
75892
|
title: "Standard deduction",
|
|
75498
75893
|
citation: {
|
|
75499
75894
|
source: "26 U.S.C. \xA7 63(c)(1)",
|
|
@@ -75507,8 +75902,8 @@ var standardDeductionRules = [
|
|
|
75507
75902
|
formula: {
|
|
75508
75903
|
kind: "add",
|
|
75509
75904
|
args: [
|
|
75510
|
-
|
|
75511
|
-
|
|
75905
|
+
ruleRef38("us.federal.standard_deduction.base"),
|
|
75906
|
+
ruleRef38("us.federal.standard_deduction.additional")
|
|
75512
75907
|
]
|
|
75513
75908
|
}
|
|
75514
75909
|
}
|
|
@@ -75516,7 +75911,7 @@ var standardDeductionRules = [
|
|
|
75516
75911
|
function additionalRule(version2, effectiveFrom, effectiveTo, marriedCents, unmarriedCents, label) {
|
|
75517
75912
|
const perStatusAmount = {
|
|
75518
75913
|
kind: "match",
|
|
75519
|
-
on:
|
|
75914
|
+
on: fact44("filingStatus"),
|
|
75520
75915
|
cases: [
|
|
75521
75916
|
// the higher amount is for "unmarried AND not a surviving spouse" —
|
|
75522
75917
|
// MFS and QSS get the married amount (read from both Rev. Procs.)
|
|
@@ -75531,12 +75926,12 @@ function additionalRule(version2, effectiveFrom, effectiveTo, marriedCents, unma
|
|
|
75531
75926
|
kind: "if",
|
|
75532
75927
|
cond,
|
|
75533
75928
|
then: perStatusAmount,
|
|
75534
|
-
else:
|
|
75929
|
+
else: money41("0")
|
|
75535
75930
|
});
|
|
75536
75931
|
return {
|
|
75537
75932
|
id: "us.federal.standard_deduction.additional",
|
|
75538
75933
|
version: version2,
|
|
75539
|
-
jurisdiction:
|
|
75934
|
+
jurisdiction: J30,
|
|
75540
75935
|
title: `Additional standard deduction for the aged and blind (TY${label.year})`,
|
|
75541
75936
|
citation: {
|
|
75542
75937
|
source: `26 U.S.C. \xA7 63(f); ${label.sourceRevProc}`,
|
|
@@ -75554,15 +75949,15 @@ function additionalRule(version2, effectiveFrom, effectiveTo, marriedCents, unma
|
|
|
75554
75949
|
formula: {
|
|
75555
75950
|
kind: "add",
|
|
75556
75951
|
args: [
|
|
75557
|
-
addIf(
|
|
75558
|
-
addIf(
|
|
75952
|
+
addIf(fact44("isAge65OrOlder")),
|
|
75953
|
+
addIf(fact44("isBlind")),
|
|
75559
75954
|
addIf({
|
|
75560
75955
|
kind: "and",
|
|
75561
|
-
args: [isStatus34("mfj"),
|
|
75956
|
+
args: [isStatus34("mfj"), fact44("spouseIsAge65OrOlder")]
|
|
75562
75957
|
}),
|
|
75563
75958
|
addIf({
|
|
75564
75959
|
kind: "and",
|
|
75565
|
-
args: [isStatus34("mfj"),
|
|
75960
|
+
args: [isStatus34("mfj"), fact44("spouseIsBlind")]
|
|
75566
75961
|
})
|
|
75567
75962
|
]
|
|
75568
75963
|
}
|
|
@@ -75570,12 +75965,12 @@ function additionalRule(version2, effectiveFrom, effectiveTo, marriedCents, unma
|
|
|
75570
75965
|
}
|
|
75571
75966
|
|
|
75572
75967
|
// ../corpus-us-federal/dist/rules/tips-eligibility.js
|
|
75573
|
-
var
|
|
75968
|
+
var fact45 = (factId) => ({ kind: "fact", factId });
|
|
75574
75969
|
var boolLit = (value) => ({ kind: "bool", value });
|
|
75575
75970
|
var isStatus35 = (status) => ({
|
|
75576
75971
|
kind: "cmp",
|
|
75577
75972
|
op: "eq",
|
|
75578
|
-
left:
|
|
75973
|
+
left: fact45("filingStatus"),
|
|
75579
75974
|
right: { kind: "enum", value: status }
|
|
75580
75975
|
});
|
|
75581
75976
|
var WINDOW = { effectiveFrom: "2025-01-01", effectiveTo: "2029-01-01" };
|
|
@@ -75595,7 +75990,7 @@ var tipsEligibilityRules = [
|
|
|
75595
75990
|
output: { type: "bool" },
|
|
75596
75991
|
formula: {
|
|
75597
75992
|
kind: "match",
|
|
75598
|
-
on:
|
|
75993
|
+
on: fact45("occupation"),
|
|
75599
75994
|
cases: [
|
|
75600
75995
|
...TIPPED_OCCUPATIONS.map((o) => ({ when: o.slug, value: boolLit(true) })),
|
|
75601
75996
|
{ when: "other", value: boolLit(false) }
|
|
@@ -75622,23 +76017,23 @@ var tipsEligibilityRules = [
|
|
|
75622
76017
|
args: [
|
|
75623
76018
|
{ kind: "not", arg: isStatus35("mfs") },
|
|
75624
76019
|
{ kind: "rule", ruleId: "us.federal.eligible.tips_occupation" },
|
|
75625
|
-
|
|
75626
|
-
{ kind: "not", arg:
|
|
76020
|
+
fact45("tipsWereVoluntary"),
|
|
76021
|
+
{ kind: "not", arg: fact45("employerIsSSTB") }
|
|
75627
76022
|
]
|
|
75628
76023
|
}
|
|
75629
76024
|
}
|
|
75630
76025
|
];
|
|
75631
76026
|
|
|
75632
76027
|
// ../corpus-us-federal/dist/rules/tips-overtime.js
|
|
75633
|
-
var
|
|
75634
|
-
var
|
|
75635
|
-
var
|
|
76028
|
+
var fact46 = (factId) => ({ kind: "fact", factId });
|
|
76029
|
+
var money42 = (cents) => ({ kind: "money", cents });
|
|
76030
|
+
var ruleRef39 = (ruleId) => ({ kind: "rule", ruleId });
|
|
75636
76031
|
var param27 = (name) => ({ kind: "param", name });
|
|
75637
|
-
var
|
|
76032
|
+
var zero30 = money42("0");
|
|
75638
76033
|
var isStatus36 = (status) => ({
|
|
75639
76034
|
kind: "cmp",
|
|
75640
76035
|
op: "eq",
|
|
75641
|
-
left:
|
|
76036
|
+
left: fact46("filingStatus"),
|
|
75642
76037
|
right: { kind: "enum", value: status }
|
|
75643
76038
|
});
|
|
75644
76039
|
function cappedPhasedDeduction(qualifiedFactId, cap, ineligible = isStatus36("mfs")) {
|
|
@@ -75646,22 +76041,22 @@ function cappedPhasedDeduction(qualifiedFactId, cap, ineligible = isStatus36("mf
|
|
|
75646
76041
|
kind: "if",
|
|
75647
76042
|
// LAZY FIRST: with no qualified amount, no eligibility facts are ever
|
|
75648
76043
|
// demanded — a taxpayer without tips is never asked their occupation
|
|
75649
|
-
cond: { kind: "cmp", op: "gt", left:
|
|
76044
|
+
cond: { kind: "cmp", op: "gt", left: fact46(qualifiedFactId), right: zero30 },
|
|
75650
76045
|
then: {
|
|
75651
76046
|
kind: "if",
|
|
75652
76047
|
cond: ineligible,
|
|
75653
|
-
then:
|
|
76048
|
+
then: zero30,
|
|
75654
76049
|
else: {
|
|
75655
76050
|
kind: "max0",
|
|
75656
76051
|
arg: {
|
|
75657
76052
|
kind: "sub",
|
|
75658
76053
|
left: {
|
|
75659
76054
|
kind: "min",
|
|
75660
|
-
args: [
|
|
76055
|
+
args: [fact46(qualifiedFactId), cap]
|
|
75661
76056
|
},
|
|
75662
76057
|
right: {
|
|
75663
76058
|
kind: "mulInt",
|
|
75664
|
-
base:
|
|
76059
|
+
base: money42("10000"),
|
|
75665
76060
|
// $100 per step
|
|
75666
76061
|
count: {
|
|
75667
76062
|
kind: "stepUnits",
|
|
@@ -75669,7 +76064,7 @@ function cappedPhasedDeduction(qualifiedFactId, cap, ineligible = isStatus36("mf
|
|
|
75669
76064
|
kind: "max0",
|
|
75670
76065
|
arg: {
|
|
75671
76066
|
kind: "sub",
|
|
75672
|
-
left:
|
|
76067
|
+
left: ruleRef39("us.federal.agi"),
|
|
75673
76068
|
right: {
|
|
75674
76069
|
kind: "if",
|
|
75675
76070
|
cond: isStatus36("mfj"),
|
|
@@ -75687,7 +76082,7 @@ function cappedPhasedDeduction(qualifiedFactId, cap, ineligible = isStatus36("mf
|
|
|
75687
76082
|
}
|
|
75688
76083
|
}
|
|
75689
76084
|
},
|
|
75690
|
-
else:
|
|
76085
|
+
else: zero30
|
|
75691
76086
|
};
|
|
75692
76087
|
}
|
|
75693
76088
|
var WINDOW2 = { effectiveFrom: "2025-01-01", effectiveTo: "2029-01-01" };
|
|
@@ -75754,7 +76149,7 @@ var tipsOvertimeRules = [
|
|
|
75754
76149
|
// ../corpus-us-federal/dist/index.js
|
|
75755
76150
|
var corpusInput = {
|
|
75756
76151
|
name: "@invaro/opentax-corpus-us-federal",
|
|
75757
|
-
version: "0.
|
|
76152
|
+
version: "0.43.0",
|
|
75758
76153
|
rules: [
|
|
75759
76154
|
...corporateRules,
|
|
75760
76155
|
...corporate1120Rules,
|
|
@@ -75918,8 +76313,8 @@ function compileDocuments(docs, asOf, ctx = {}) {
|
|
|
75918
76313
|
const notes = [];
|
|
75919
76314
|
const missing = [];
|
|
75920
76315
|
const unsupported = [];
|
|
75921
|
-
const
|
|
75922
|
-
sums[
|
|
76316
|
+
const add24 = (id2, c2) => {
|
|
76317
|
+
sums[id2] = (sums[id2] ?? 0n) + c2;
|
|
75923
76318
|
};
|
|
75924
76319
|
const born65Cutoff = (dobStr) => ageAtYearEnd(dobStr, taxYear) >= 65;
|
|
75925
76320
|
if (docs.taxpayerDateOfBirth) {
|
|
@@ -75947,7 +76342,7 @@ function compileDocuments(docs, asOf, ctx = {}) {
|
|
|
75947
76342
|
if (allTagged) {
|
|
75948
76343
|
const own2 = w2s.filter((w) => w.recipient === earner);
|
|
75949
76344
|
const ssw = own2.reduce((t, w) => t + toCents(w.box3 ?? w.box1), 0n);
|
|
75950
|
-
|
|
76345
|
+
add24("socialSecurityWages", ssw);
|
|
75951
76346
|
bools.socialSecurityWagesProvided = true;
|
|
75952
76347
|
notes.push(`Schedule SE line 8a: ${own2.length} W-2(s) belong to the ${earner} (the SE earner) \u2014 social security wages $${dollars5(ssw)} coordinate the OASDI wage base${own2.some((w) => w.box3 === void 0) ? " (box 1 used where box 3 was not transcribed)" : ""}; the other spouse's W-2 does not`);
|
|
75953
76348
|
} else if (joint || multiW2) {
|
|
@@ -75959,10 +76354,10 @@ function compileDocuments(docs, asOf, ctx = {}) {
|
|
|
75959
76354
|
let w2Box1Cents = (docs.w2s ?? []).length ? 0n : void 0;
|
|
75960
76355
|
let ssTaxWithheld = 0n;
|
|
75961
76356
|
for (const [i, w] of (docs.w2s ?? []).entries()) {
|
|
75962
|
-
|
|
76357
|
+
add24("wages", toCents(w.box1));
|
|
75963
76358
|
w2Box1Cents = (w2Box1Cents ?? 0n) + toCents(w.box1);
|
|
75964
76359
|
if (w.box2 !== void 0)
|
|
75965
|
-
|
|
76360
|
+
add24("federalTaxWithheld", toCents(w.box2));
|
|
75966
76361
|
else {
|
|
75967
76362
|
missing.push(`documents.w2s[${i}].box2`);
|
|
75968
76363
|
notes.push(`W-2 #${i + 1}: box 2 NOT transcribed \u2014 federal income tax withheld treated as $0 for this W-2; pass box2 (0 if the box is blank) to confirm, or set strict: true to refuse instead`);
|
|
@@ -75970,19 +76365,19 @@ function compileDocuments(docs, asOf, ctx = {}) {
|
|
|
75970
76365
|
if (w.box4 !== void 0)
|
|
75971
76366
|
ssTaxWithheld += toCents(w.box4);
|
|
75972
76367
|
if (w.box3 !== void 0 && !multiW2 && !allTagged && !joint && !ctx.socialSecurityWagesSupplied) {
|
|
75973
|
-
|
|
76368
|
+
add24("socialSecurityWages", toCents(w.box3));
|
|
75974
76369
|
if (hasSE)
|
|
75975
76370
|
bools.socialSecurityWagesProvided = true;
|
|
75976
76371
|
}
|
|
75977
76372
|
if (w.box5 !== void 0) {
|
|
75978
76373
|
const b5 = toCents(w.box5);
|
|
75979
|
-
|
|
76374
|
+
add24("medicareWages", b5);
|
|
75980
76375
|
if (w.box6 !== void 0 && b5 > 20000000n) {
|
|
75981
76376
|
const regular = (b5 * 145n + 5000n) / 10000n;
|
|
75982
|
-
const
|
|
75983
|
-
if (
|
|
75984
|
-
|
|
75985
|
-
notes.push(`W-2 #${i + 1}: Form 8959 Part IV \u2014 box 6 exceeds 1.45% of box 5 by $${dollars5(
|
|
76377
|
+
const excess2 = toCents(w.box6) - regular;
|
|
76378
|
+
if (excess2 > 0n) {
|
|
76379
|
+
add24("federalTaxWithheld", excess2);
|
|
76380
|
+
notes.push(`W-2 #${i + 1}: Form 8959 Part IV \u2014 box 6 exceeds 1.45% of box 5 by $${dollars5(excess2)}; added to withholding`);
|
|
75986
76381
|
}
|
|
75987
76382
|
}
|
|
75988
76383
|
}
|
|
@@ -76007,9 +76402,9 @@ function compileDocuments(docs, asOf, ctx = {}) {
|
|
|
76007
76402
|
for (const [who, p] of byPerson) {
|
|
76008
76403
|
if (p.n < 2 || max2 === void 0 || p.withheld <= max2)
|
|
76009
76404
|
continue;
|
|
76010
|
-
const
|
|
76011
|
-
excessTotal +=
|
|
76012
|
-
notes.push(`W-2 box 4 total $${dollars5(p.withheld)} across ${p.n} employers (${who}) exceeds the ${taxYear} maximum $${dollars5(max2)} by $${dollars5(
|
|
76405
|
+
const excess2 = p.withheld - max2;
|
|
76406
|
+
excessTotal += excess2;
|
|
76407
|
+
notes.push(`W-2 box 4 total $${dollars5(p.withheld)} across ${p.n} employers (${who}) exceeds the ${taxYear} maximum $${dollars5(max2)} by $${dollars5(excess2)} \u2014 the Schedule 3 line 11 excess social security withholding credit is NOT computed by this engine; the completed return must claim it (see \`incomplete\`)`);
|
|
76013
76408
|
}
|
|
76014
76409
|
if (excessTotal > 0n) {
|
|
76015
76410
|
unsupported.push({
|
|
@@ -76032,7 +76427,7 @@ function compileDocuments(docs, asOf, ctx = {}) {
|
|
|
76032
76427
|
const PENALTY_EXEMPT_CODES = /* @__PURE__ */ new Set(["2", "3", "4", "7", "G", "H", "Q", "T", "C"]);
|
|
76033
76428
|
for (const [i, r] of (docs.f1099rs ?? []).entries()) {
|
|
76034
76429
|
if (r.box4 !== void 0)
|
|
76035
|
-
|
|
76430
|
+
add24("federalTaxWithheld", toCents(r.box4));
|
|
76036
76431
|
const taxable3 = toCents(r.box2a);
|
|
76037
76432
|
if (r.rolledOver || r.box7.toUpperCase().includes("G") && taxable3 === 0n) {
|
|
76038
76433
|
notes.push(`1099-R #${i + 1}: treated as ROLLOVER (${r.rolledOver ? "interview-confirmed" : "code G"}) \u2014 gross on 4a/5a only, $0 taxable`);
|
|
@@ -76042,65 +76437,65 @@ function compileDocuments(docs, asOf, ctx = {}) {
|
|
|
76042
76437
|
notes.push(`1099-R #${i + 1}: code G with box 2a $${dollars5(taxable3)} \u2014 a direct rollover to a ROTH (conversion): box 2a is taxable on line ${r.iraSepSimple ? "4b" : "5b"}, the balance is the rollover`);
|
|
76043
76438
|
}
|
|
76044
76439
|
if (r.disabilityBeforeRetirementAge) {
|
|
76045
|
-
|
|
76046
|
-
|
|
76440
|
+
add24("wages", taxable3);
|
|
76441
|
+
add24("scheduleRDisabilityIncome", taxable3);
|
|
76047
76442
|
notes.push(`1099-R #${i + 1}: code-3 disability before minimum retirement age \u2014 $${dollars5(taxable3)} reported as WAGES (Pub. 525, Form 1040 line 1h \u2014 NOT line 1a, which is W-2 box 1 only) and counted as \xA7 22 disability income`);
|
|
76048
76443
|
continue;
|
|
76049
76444
|
}
|
|
76050
76445
|
if (r.iraSepSimple)
|
|
76051
|
-
|
|
76446
|
+
add24("taxableIraDistributions", taxable3);
|
|
76052
76447
|
else
|
|
76053
|
-
|
|
76448
|
+
add24("taxablePensionsAndAnnuities", taxable3);
|
|
76054
76449
|
const dobStr = r.recipient === "spouse" ? docs.spouseDateOfBirth : docs.taxpayerDateOfBirth;
|
|
76055
76450
|
const code = r.box7.toUpperCase();
|
|
76056
76451
|
if ([...code].some((c2) => c2 === "1")) {
|
|
76057
76452
|
if (dobStr && ageYearsExact(dobStr, taxYear) >= 59.5) {
|
|
76058
76453
|
notes.push(`1099-R #${i + 1}: payer code 1 (early) but the ${r.recipient ?? "taxpayer"} is over 59\xBD \u2014 no \xA7 72(t) penalty (age controls, not the box code)`);
|
|
76059
76454
|
} else if ([...code].every((c2) => !PENALTY_EXEMPT_CODES.has(c2))) {
|
|
76060
|
-
|
|
76455
|
+
add24("earlyDistributionSubjectToPenalty", taxable3);
|
|
76061
76456
|
notes.push(`1099-R #${i + 1}: code 1 and no age exception established \u2014 $${dollars5(taxable3)} subject to the 10% \xA7 72(t) tax`);
|
|
76062
76457
|
}
|
|
76063
76458
|
}
|
|
76064
76459
|
}
|
|
76065
76460
|
for (const s of docs.ssa1099s ?? []) {
|
|
76066
|
-
|
|
76461
|
+
add24("socialSecurityBenefits", toCents(s.box5));
|
|
76067
76462
|
if (s.box6 !== void 0)
|
|
76068
|
-
|
|
76463
|
+
add24("federalTaxWithheld", toCents(s.box6));
|
|
76069
76464
|
}
|
|
76070
76465
|
let seGross = 0n;
|
|
76071
76466
|
for (const n of docs.f1099necs ?? []) {
|
|
76072
76467
|
seGross += toCents(n.box1);
|
|
76073
76468
|
if (n.box4 !== void 0)
|
|
76074
|
-
|
|
76469
|
+
add24("federalTaxWithheld", toCents(n.box4));
|
|
76075
76470
|
}
|
|
76076
76471
|
for (const k of docs.f1099ks ?? []) {
|
|
76077
76472
|
seGross += toCents(k.box1a);
|
|
76078
76473
|
if (k.box4 !== void 0)
|
|
76079
|
-
|
|
76474
|
+
add24("federalTaxWithheld", toCents(k.box4));
|
|
76080
76475
|
}
|
|
76081
76476
|
if (seGross > 0n || docs.scheduleCExpensesTotal !== void 0) {
|
|
76082
76477
|
const expenses = docs.scheduleCExpensesTotal !== void 0 ? toCents(docs.scheduleCExpensesTotal) : 0n;
|
|
76083
76478
|
const net = seGross - expenses;
|
|
76084
76479
|
if (net >= 0n) {
|
|
76085
76480
|
if (net > 0n)
|
|
76086
|
-
|
|
76481
|
+
add24("selfEmploymentNetProfit", net);
|
|
76087
76482
|
notes.push(`Schedule C: $${dollars5(seGross)} gross (1099-NEC/K) \u2212 $${dollars5(expenses)} expenses = $${dollars5(net)} net profit \u2192 SE tax + QBI machinery engage on it`);
|
|
76088
76483
|
} else {
|
|
76089
|
-
|
|
76484
|
+
add24("scheduleCNetLoss", -net);
|
|
76090
76485
|
notes.push(`Schedule C: expenses exceed 1099-NEC/K gross by $${dollars5(-net)} \u2014 recorded as scheduleCNetLoss`);
|
|
76091
76486
|
}
|
|
76092
76487
|
}
|
|
76093
76488
|
for (const [i, t] of (docs.f1099ints ?? []).entries()) {
|
|
76094
76489
|
if (t.box1 !== void 0)
|
|
76095
|
-
|
|
76490
|
+
add24("taxableInterest", toCents(t.box1));
|
|
76096
76491
|
if (t.box3 !== void 0 && toCents(t.box3) > 0n) {
|
|
76097
|
-
|
|
76492
|
+
add24("taxableInterest", toCents(t.box3));
|
|
76098
76493
|
notes.push(`1099-INT #${i + 1}: box 3 Treasury interest $${dollars5(toCents(t.box3))} is federally taxable (state returns exempt it \u2014 the state composers handle that subtraction)`);
|
|
76099
76494
|
}
|
|
76100
76495
|
if (t.box8 !== void 0)
|
|
76101
|
-
|
|
76496
|
+
add24("taxExemptInterest", toCents(t.box8));
|
|
76102
76497
|
if (t.box4 !== void 0)
|
|
76103
|
-
|
|
76498
|
+
add24("federalTaxWithheld", toCents(t.box4));
|
|
76104
76499
|
}
|
|
76105
76500
|
for (const [i, d3] of (docs.f1099divs ?? []).entries()) {
|
|
76106
76501
|
const total = toCents(d3.box1a);
|
|
@@ -76109,15 +76504,15 @@ function compileDocuments(docs, asOf, ctx = {}) {
|
|
|
76109
76504
|
throw new Error(`1099-DIV #${i + 1}: box 1b (qualified, $${dollars5(qualified2)}) exceeds box 1a (total, $${dollars5(total)}) \u2014 transcription error`);
|
|
76110
76505
|
}
|
|
76111
76506
|
if (qualified2 > 0n)
|
|
76112
|
-
|
|
76507
|
+
add24("qualifiedDividends", qualified2);
|
|
76113
76508
|
if (total - qualified2 > 0n)
|
|
76114
|
-
|
|
76509
|
+
add24("ordinaryDividends", total - qualified2);
|
|
76115
76510
|
if (d3.box2a !== void 0 && toCents(d3.box2a) > 0n) {
|
|
76116
|
-
|
|
76511
|
+
add24("__ltProceeds", toCents(d3.box2a));
|
|
76117
76512
|
notes.push(`1099-DIV #${i + 1}: box 2a capital gain distributions $${dollars5(toCents(d3.box2a))} \u2014 long-term by statute (\xA7 852(b)(3)(B)), joined to the Schedule D long-term bucket`);
|
|
76118
76513
|
}
|
|
76119
76514
|
if (d3.box4 !== void 0)
|
|
76120
|
-
|
|
76515
|
+
add24("federalTaxWithheld", toCents(d3.box4));
|
|
76121
76516
|
}
|
|
76122
76517
|
let stNet = 0n;
|
|
76123
76518
|
let ltNet = sums.__ltProceeds ?? 0n;
|
|
@@ -76132,24 +76527,24 @@ function compileDocuments(docs, asOf, ctx = {}) {
|
|
|
76132
76527
|
else
|
|
76133
76528
|
ltNet += lot;
|
|
76134
76529
|
if (b.box4 !== void 0)
|
|
76135
|
-
|
|
76530
|
+
add24("federalTaxWithheld", toCents(b.box4));
|
|
76136
76531
|
}
|
|
76137
76532
|
if (sawB) {
|
|
76138
76533
|
if (stNet > 0n)
|
|
76139
|
-
|
|
76534
|
+
add24("shortTermCapitalGains", stNet);
|
|
76140
76535
|
else if (stNet < 0n)
|
|
76141
|
-
|
|
76536
|
+
add24("shortTermCapitalLoss", -stNet);
|
|
76142
76537
|
if (ltNet > 0n)
|
|
76143
|
-
|
|
76538
|
+
add24("longTermCapitalGains", ltNet);
|
|
76144
76539
|
else if (ltNet < 0n)
|
|
76145
|
-
|
|
76540
|
+
add24("longTermCapitalLoss", -ltNet);
|
|
76146
76541
|
notes.push(`Schedule D buckets from 1099-B/DIV: short-term net $${dollars5(stNet)}, long-term net $${dollars5(ltNet)} \u2014 the \xA7 1222 netting rules combine them (character preserved, \xA7 1211(b) caps any overall loss)`);
|
|
76147
76542
|
}
|
|
76148
76543
|
for (const [i, g] of (docs.f1099gs ?? []).entries()) {
|
|
76149
76544
|
if (g.box1 !== void 0)
|
|
76150
|
-
|
|
76545
|
+
add24("unemploymentCompensation", toCents(g.box1));
|
|
76151
76546
|
if (g.box4 !== void 0)
|
|
76152
|
-
|
|
76547
|
+
add24("federalTaxWithheld", toCents(g.box4));
|
|
76153
76548
|
if (g.box2 !== void 0 && toCents(g.box2) > 0n) {
|
|
76154
76549
|
notes.push(`1099-G #${i + 1}: box 2 state refund $${dollars5(toCents(g.box2))} NOT auto-included \u2014 taxable only to the extent the prior-year SALT deduction produced a benefit (\xA7 111); add it to otherOrdinaryIncome yourself if it did`);
|
|
76155
76550
|
}
|
|
@@ -76187,23 +76582,23 @@ function compileDocuments(docs, asOf, ctx = {}) {
|
|
|
76187
76582
|
}
|
|
76188
76583
|
}
|
|
76189
76584
|
const facts2 = { ...bools };
|
|
76190
|
-
for (const [
|
|
76191
|
-
facts2[
|
|
76192
|
-
for (const [
|
|
76193
|
-
facts2[
|
|
76585
|
+
for (const [id2, c2] of Object.entries(sums))
|
|
76586
|
+
facts2[id2] = dollars5(c2);
|
|
76587
|
+
for (const [id2, n] of Object.entries(ints))
|
|
76588
|
+
facts2[id2] = n;
|
|
76194
76589
|
return { facts: facts2, notes, w2Box1Cents, missing, unsupported };
|
|
76195
76590
|
}
|
|
76196
76591
|
|
|
76197
76592
|
// dist/schema.js
|
|
76198
76593
|
var corpus = getCorpus();
|
|
76199
|
-
var
|
|
76594
|
+
var money43 = external_exports.union([external_exports.number(), external_exports.string()]).describe('dollars, e.g. 50000 or "1234.56"');
|
|
76200
76595
|
function zodForFact(f) {
|
|
76201
76596
|
if (f.id === "occupation") {
|
|
76202
76597
|
return external_exports.string().describe('tipped occupation, fuzzy-matched to the Treasury Tipped Occupation list (Treas. Reg. \xA7 1.224-1) \u2014 e.g. "bartender", "nanny" \u2014 or "other" if genuinely unlisted. Only needed when qualifiedTips > 0.');
|
|
76203
76598
|
}
|
|
76204
76599
|
switch (f.type) {
|
|
76205
76600
|
case "money":
|
|
76206
|
-
return
|
|
76601
|
+
return money43.describe(f.description);
|
|
76207
76602
|
case "bool":
|
|
76208
76603
|
return external_exports.boolean().describe(f.description);
|
|
76209
76604
|
case "int":
|
|
@@ -76233,12 +76628,12 @@ var DEPENDENT_EXTRAS = /* @__PURE__ */ new Set([
|
|
|
76233
76628
|
"taxpayerIsCustodialParent",
|
|
76234
76629
|
"custodialParentReleasedClaim"
|
|
76235
76630
|
]);
|
|
76236
|
-
function domainOf(
|
|
76237
|
-
if (
|
|
76631
|
+
function domainOf(id2) {
|
|
76632
|
+
if (id2.startsWith("corp") || id2.startsWith("sCorp") || BUSINESS_EXTRAS.has(id2))
|
|
76238
76633
|
return "business";
|
|
76239
|
-
if (
|
|
76634
|
+
if (id2.startsWith("fiduciary"))
|
|
76240
76635
|
return "fiduciary";
|
|
76241
|
-
if (/^dep[A-Z]/.test(
|
|
76636
|
+
if (/^dep[A-Z]/.test(id2) || DEPENDENT_EXTRAS.has(id2))
|
|
76242
76637
|
return "dependent";
|
|
76243
76638
|
return "individual";
|
|
76244
76639
|
}
|
|
@@ -76322,6 +76717,12 @@ var INDIVIDUAL_GROUPS = {
|
|
|
76322
76717
|
"qbiW2Wages",
|
|
76323
76718
|
"qbiUBIA",
|
|
76324
76719
|
"businessIsSSTB",
|
|
76720
|
+
"qbiAggregationGroup",
|
|
76721
|
+
"spouseQbiW2Wages",
|
|
76722
|
+
"spouseQbiUBIA",
|
|
76723
|
+
"spouseBusinessIsSSTB",
|
|
76724
|
+
"spouseQbiAggregationGroup",
|
|
76725
|
+
"qbiLossCarryforward",
|
|
76325
76726
|
"sepContribution",
|
|
76326
76727
|
"selfEmployedHealthPremiums",
|
|
76327
76728
|
"homeOfficeSquareFeet",
|
|
@@ -76422,6 +76823,34 @@ var INDIVIDUAL_GROUPS = {
|
|
|
76422
76823
|
"qsbsAcquiredAfterSept2010",
|
|
76423
76824
|
"qsbsHoldingPeriodYears"
|
|
76424
76825
|
],
|
|
76826
|
+
qbi_businesses: [
|
|
76827
|
+
"qbiAdditionalBusinesses",
|
|
76828
|
+
"qbiBusiness2Income",
|
|
76829
|
+
"qbiBusiness2W2Wages",
|
|
76830
|
+
"qbiBusiness2UBIA",
|
|
76831
|
+
"qbiBusiness2IsSSTB",
|
|
76832
|
+
"qbiBusiness2AggregationGroup",
|
|
76833
|
+
"qbiBusiness3Income",
|
|
76834
|
+
"qbiBusiness3W2Wages",
|
|
76835
|
+
"qbiBusiness3UBIA",
|
|
76836
|
+
"qbiBusiness3IsSSTB",
|
|
76837
|
+
"qbiBusiness3AggregationGroup",
|
|
76838
|
+
"qbiBusiness4Income",
|
|
76839
|
+
"qbiBusiness4W2Wages",
|
|
76840
|
+
"qbiBusiness4UBIA",
|
|
76841
|
+
"qbiBusiness4IsSSTB",
|
|
76842
|
+
"qbiBusiness4AggregationGroup",
|
|
76843
|
+
"qbiBusiness5Income",
|
|
76844
|
+
"qbiBusiness5W2Wages",
|
|
76845
|
+
"qbiBusiness5UBIA",
|
|
76846
|
+
"qbiBusiness5IsSSTB",
|
|
76847
|
+
"qbiBusiness5AggregationGroup",
|
|
76848
|
+
"qbiBusiness6Income",
|
|
76849
|
+
"qbiBusiness6W2Wages",
|
|
76850
|
+
"qbiBusiness6UBIA",
|
|
76851
|
+
"qbiBusiness6IsSSTB",
|
|
76852
|
+
"qbiBusiness6AggregationGroup"
|
|
76853
|
+
],
|
|
76425
76854
|
rentals_passive: [
|
|
76426
76855
|
"scheduleENetIncome",
|
|
76427
76856
|
"passiveActivityIncome",
|
|
@@ -76987,11 +77416,11 @@ var GROUP_NAMES = new Set(Object.keys(INDIVIDUAL_GROUPS));
|
|
|
76987
77416
|
var factById = new Map(corpus.facts.map((f) => [f.id, f]));
|
|
76988
77417
|
function shapeFor(ids) {
|
|
76989
77418
|
const shape = {};
|
|
76990
|
-
for (const
|
|
76991
|
-
const f = factById.get(
|
|
77419
|
+
for (const id2 of ids) {
|
|
77420
|
+
const f = factById.get(id2);
|
|
76992
77421
|
if (!f)
|
|
76993
77422
|
continue;
|
|
76994
|
-
shape[
|
|
77423
|
+
shape[id2] = zodForFact(f).optional();
|
|
76995
77424
|
}
|
|
76996
77425
|
return shape;
|
|
76997
77426
|
}
|
|
@@ -77004,6 +77433,7 @@ var GROUP_DESCRIPTIONS = {
|
|
|
77004
77433
|
tips_overtime: "\xA7 224 tips and \xA7 225 overtime deductions (OBBBA)",
|
|
77005
77434
|
retirement: "social security, IRA/pension distributions, early-distribution penalty",
|
|
77006
77435
|
self_employment: "Schedule C / K-1, QBI inputs, SE deductions, home office",
|
|
77436
|
+
qbi_businesses: "\xA7 199A per business (Form 8995-A): up to five businesses listed separately from the main one, each with its own QBI, W-2 wages, UBIA, SSTB status and aggregation group",
|
|
77007
77437
|
adjustments: "IRA/HSA contributions, student-loan and car-loan interest",
|
|
77008
77438
|
itemized: "Schedule A: SALT, mortgage, medical, charitable",
|
|
77009
77439
|
credits: "CTC/ODC counts, dependent care, saver's, adoption, education",
|
|
@@ -77166,11 +77596,11 @@ function buildFactsValidated(factsArg, defaultTarget) {
|
|
|
77166
77596
|
compiled.facts.wages = 0;
|
|
77167
77597
|
documentNotes.push("no W-2 in the documents block: wages $0 (Form 1040 line 1a)");
|
|
77168
77598
|
}
|
|
77169
|
-
for (const [
|
|
77170
|
-
if (
|
|
77171
|
-
throw new Error(`fact "${
|
|
77599
|
+
for (const [id2, v] of Object.entries(compiled.facts)) {
|
|
77600
|
+
if (id2 in flat) {
|
|
77601
|
+
throw new Error(`fact "${id2}" was derived from the documents block AND passed directly \u2014 remove the direct value (the compiled document value is authoritative; to override, drop the document entry and disclose)`);
|
|
77172
77602
|
}
|
|
77173
|
-
flat[
|
|
77603
|
+
flat[id2] = v;
|
|
77174
77604
|
}
|
|
77175
77605
|
}
|
|
77176
77606
|
if ("otherEarnedIncome" in flat) {
|
|
@@ -77234,12 +77664,12 @@ var fmt2 = (cents) => {
|
|
|
77234
77664
|
dollars6 += "," + digits.slice(i, i + 3);
|
|
77235
77665
|
return `${sign}$${dollars6}.${(abs % 100n).toString().padStart(2, "0")}`;
|
|
77236
77666
|
};
|
|
77237
|
-
function ruleDependencies(
|
|
77667
|
+
function ruleDependencies(rule2) {
|
|
77238
77668
|
const rules = /* @__PURE__ */ new Set();
|
|
77239
77669
|
const facts2 = /* @__PURE__ */ new Set();
|
|
77240
|
-
const roots = [
|
|
77241
|
-
if (
|
|
77242
|
-
roots.push(
|
|
77670
|
+
const roots = [rule2.formula];
|
|
77671
|
+
if (rule2.applicability)
|
|
77672
|
+
roots.push(rule2.applicability);
|
|
77243
77673
|
for (const root of roots) {
|
|
77244
77674
|
walkExpr(root, (e) => {
|
|
77245
77675
|
if (e.kind === "rule")
|
|
@@ -77271,33 +77701,33 @@ var FORM_5695_FACTS = [
|
|
|
77271
77701
|
"heatPumpBiomassCosts"
|
|
77272
77702
|
];
|
|
77273
77703
|
function composeForm5695(facts2, asOf, get) {
|
|
77274
|
-
const present = FORM_5695_FACTS.some((
|
|
77275
|
-
const f = facts2[
|
|
77704
|
+
const present = FORM_5695_FACTS.some((id2) => {
|
|
77705
|
+
const f = facts2[id2];
|
|
77276
77706
|
return f !== void 0 && f.type !== "bool" && BigInt(String(f.value)) !== 0n;
|
|
77277
77707
|
});
|
|
77278
77708
|
if (!present)
|
|
77279
77709
|
return null;
|
|
77280
77710
|
const rd26 = (c2) => {
|
|
77281
|
-
const
|
|
77282
|
-
const abs =
|
|
77711
|
+
const neg3 = c2 < 0n;
|
|
77712
|
+
const abs = neg3 ? -c2 : c2;
|
|
77283
77713
|
const r = (abs + 50n) / 100n * 100n;
|
|
77284
|
-
return
|
|
77714
|
+
return neg3 ? -r : r;
|
|
77285
77715
|
};
|
|
77286
77716
|
const d3 = (c2) => fmt2(rd26(c2));
|
|
77287
|
-
const
|
|
77288
|
-
const f = facts2[
|
|
77717
|
+
const money44 = (id2) => {
|
|
77718
|
+
const f = facts2[id2];
|
|
77289
77719
|
return f && f.type === "money" ? BigInt(String(f.value)) : 0n;
|
|
77290
77720
|
};
|
|
77291
77721
|
const E = (s) => get(`us.federal.energy.${s}`);
|
|
77292
77722
|
const year = asOf.slice(0, 4);
|
|
77293
77723
|
if (year !== "2025") {
|
|
77294
77724
|
const costs = {};
|
|
77295
|
-
for (const
|
|
77296
|
-
if (
|
|
77725
|
+
for (const id2 of FORM_5695_FACTS) {
|
|
77726
|
+
if (id2 === "fuelCellHalfKilowatts" || id2 === "residentialCleanEnergyCarryforward")
|
|
77297
77727
|
continue;
|
|
77298
|
-
const c2 =
|
|
77728
|
+
const c2 = money44(id2);
|
|
77299
77729
|
if (c2 !== 0n)
|
|
77300
|
-
costs[
|
|
77730
|
+
costs[id2] = d3(c2);
|
|
77301
77731
|
}
|
|
77302
77732
|
return {
|
|
77303
77733
|
"12_carryforward_from_prior_year": d3(E("clean.line12")),
|
|
@@ -77311,14 +77741,14 @@ function composeForm5695(facts2, asOf, get) {
|
|
|
77311
77741
|
};
|
|
77312
77742
|
}
|
|
77313
77743
|
return {
|
|
77314
|
-
"1_solar_electric": d3(
|
|
77315
|
-
"2_solar_water_heating": d3(
|
|
77316
|
-
"3_small_wind": d3(
|
|
77317
|
-
"4_geothermal_heat_pump": d3(
|
|
77318
|
-
"5b_battery_storage": d3(
|
|
77744
|
+
"1_solar_electric": d3(money44("solarElectricCosts")),
|
|
77745
|
+
"2_solar_water_heating": d3(money44("solarWaterHeatingCosts")),
|
|
77746
|
+
"3_small_wind": d3(money44("smallWindEnergyCosts")),
|
|
77747
|
+
"4_geothermal_heat_pump": d3(money44("geothermalHeatPumpCosts")),
|
|
77748
|
+
"5b_battery_storage": d3(money44("batteryStorageCosts")),
|
|
77319
77749
|
"6a_total": d3(E("clean.line6a")),
|
|
77320
77750
|
"6b_30_percent": d3(E("clean.line6b")),
|
|
77321
|
-
"8_fuel_cell_costs": d3(
|
|
77751
|
+
"8_fuel_cell_costs": d3(money44("fuelCellPropertyCosts")),
|
|
77322
77752
|
"9_30_percent": d3(E("clean.line9")),
|
|
77323
77753
|
"10_kilowatt_capacity_x_1000": d3(E("clean.line10")),
|
|
77324
77754
|
"11_smaller_of_9_or_10": d3(E("clean.line11")),
|
|
@@ -77327,28 +77757,28 @@ function composeForm5695(facts2, asOf, get) {
|
|
|
77327
77757
|
"14_limitation": d3(E("clean.line14")),
|
|
77328
77758
|
"15_residential_clean_energy_credit": d3(E("clean_energy_credit")),
|
|
77329
77759
|
"16_carryforward_to_next_year": d3(E("clean.carryforward")),
|
|
77330
|
-
"18a_insulation_air_sealing": d3(
|
|
77760
|
+
"18a_insulation_air_sealing": d3(money44("insulationAirSealingCosts")),
|
|
77331
77761
|
"18b_30_percent_max_1200": d3(E("improvement.line18b")),
|
|
77332
|
-
"19a_most_expensive_door": d3(
|
|
77762
|
+
"19a_most_expensive_door": d3(money44("exteriorDoorMostExpensiveCost")),
|
|
77333
77763
|
"19c_30_percent_max_250": d3(E("improvement.line19c")),
|
|
77334
|
-
"19f_other_doors": d3(
|
|
77764
|
+
"19f_other_doors": d3(money44("exteriorDoorOtherCosts")),
|
|
77335
77765
|
"19g_30_percent": d3(E("improvement.line19g")),
|
|
77336
77766
|
"19h_doors_max_500": d3(E("improvement.line19h")),
|
|
77337
|
-
"20c_windows_skylights": d3(
|
|
77767
|
+
"20c_windows_skylights": d3(money44("windowsSkylightsCosts")),
|
|
77338
77768
|
"20d_30_percent_max_600": d3(E("improvement.line20d")),
|
|
77339
|
-
"22c_central_air_conditioners": d3(
|
|
77769
|
+
"22c_central_air_conditioners": d3(money44("centralAirConditionerCosts")),
|
|
77340
77770
|
"22d_30_percent_max_600": d3(E("improvement.line22d")),
|
|
77341
|
-
"23c_gas_oil_water_heaters": d3(
|
|
77771
|
+
"23c_gas_oil_water_heaters": d3(money44("gasOilWaterHeaterCosts")),
|
|
77342
77772
|
"23d_30_percent_max_600": d3(E("improvement.line23d")),
|
|
77343
|
-
"24c_gas_oil_furnaces_boilers": d3(
|
|
77773
|
+
"24c_gas_oil_furnaces_boilers": d3(money44("gasOilFurnaceBoilerCosts")),
|
|
77344
77774
|
"24d_30_percent_max_600": d3(E("improvement.line24d")),
|
|
77345
|
-
"25c_enabling_property": d3(
|
|
77775
|
+
"25c_enabling_property": d3(money44("electricalPanelCosts")),
|
|
77346
77776
|
"25e_30_percent_max_600": d3(E("improvement.line25e")),
|
|
77347
|
-
"26b_home_energy_audit": d3(
|
|
77777
|
+
"26b_home_energy_audit": d3(money44("homeEnergyAuditCosts")),
|
|
77348
77778
|
"26c_30_percent_max_150": d3(E("improvement.line26c")),
|
|
77349
77779
|
"27_total": d3(E("improvement.line27")),
|
|
77350
77780
|
"28_smaller_of_27_or_1200": d3(E("improvement.line28")),
|
|
77351
|
-
"29g_heat_pumps_biomass": d3(
|
|
77781
|
+
"29g_heat_pumps_biomass": d3(money44("heatPumpBiomassCosts")),
|
|
77352
77782
|
"29h_30_percent_max_2000": d3(E("improvement.line29h")),
|
|
77353
77783
|
"30_total": d3(E("improvement.line30")),
|
|
77354
77784
|
"31_limitation": d3(E("improvement.line31")),
|
|
@@ -77520,22 +77950,22 @@ function createServer(options = {}) {
|
|
|
77520
77950
|
if (args.strict === true && incomplete.length)
|
|
77521
77951
|
throw new IncompleteReturnError(incomplete);
|
|
77522
77952
|
const rd26 = (c2) => {
|
|
77523
|
-
const
|
|
77524
|
-
const abs =
|
|
77953
|
+
const neg3 = c2 < 0n;
|
|
77954
|
+
const abs = neg3 ? -c2 : c2;
|
|
77525
77955
|
const r = (abs + 50n) / 100n * 100n;
|
|
77526
|
-
return
|
|
77956
|
+
return neg3 ? -r : r;
|
|
77527
77957
|
};
|
|
77528
77958
|
const facts2 = {};
|
|
77529
77959
|
let roundedInputs = 0;
|
|
77530
|
-
for (const [
|
|
77960
|
+
for (const [id2, v] of Object.entries(built.facts)) {
|
|
77531
77961
|
if (v.type === "money") {
|
|
77532
77962
|
const cents = BigInt(v.value);
|
|
77533
77963
|
const r = rd26(cents);
|
|
77534
77964
|
if (r !== cents)
|
|
77535
77965
|
roundedInputs += 1;
|
|
77536
|
-
facts2[
|
|
77966
|
+
facts2[id2] = { type: "money", value: r.toString() };
|
|
77537
77967
|
} else
|
|
77538
|
-
facts2[
|
|
77968
|
+
facts2[id2] = v;
|
|
77539
77969
|
}
|
|
77540
77970
|
const w2Box1Cents = built.w2Box1Cents === void 0 ? void 0 : rd26(built.w2Box1Cents);
|
|
77541
77971
|
if (roundedInputs > 0) {
|
|
@@ -77633,7 +78063,7 @@ function createServer(options = {}) {
|
|
|
77633
78063
|
description: `Verify a claimed tax amount (yours, a user's, or another tool's) against the law. Returns verdict 'verified' or 'refuted' with the correct value. Use this as a self-check before presenting any tax number. Put asOf (and target, if any) INSIDE the facts object \u2014 e.g. facts: {..., "asOf": "2025-12-31"} \u2014 otherwise the claim is checked under today's law.`,
|
|
77634
78064
|
inputSchema: legacyJsonSchema(external_exports.object({
|
|
77635
78065
|
facts: factsObjectParam,
|
|
77636
|
-
claimedAmount:
|
|
78066
|
+
claimedAmount: money43.describe("the amount to verify (negative = refund)"),
|
|
77637
78067
|
toleranceDollars: external_exports.number().min(0).optional().describe("default 1")
|
|
77638
78068
|
}).strict())
|
|
77639
78069
|
}, async (args) => {
|
|
@@ -77683,7 +78113,7 @@ function createServer(options = {}) {
|
|
|
77683
78113
|
}, async ({ ruleId, asOf }) => {
|
|
77684
78114
|
const versions2 = corpus.byId.get(ruleId);
|
|
77685
78115
|
if (!versions2) {
|
|
77686
|
-
const near = [...corpus.byId.keys()].filter((
|
|
78116
|
+
const near = [...corpus.byId.keys()].filter((id2) => id2.includes(ruleId));
|
|
77687
78117
|
return fail(new Error(`unknown rule "${ruleId}"${near.length ? ` \u2014 did you mean: ${near.slice(0, 5).join(", ")}` : ""}`));
|
|
77688
78118
|
}
|
|
77689
78119
|
const shown = asOf ? versions2.filter((r) => r.effectiveFrom <= asOf && (r.effectiveTo === void 0 || asOf < r.effectiveTo)) : versions2;
|
|
@@ -77822,7 +78252,7 @@ function createServer(options = {}) {
|
|
|
77822
78252
|
description: "Fact-check a claimed dollar amount about tax law ('the 2026 MFJ standard deduction is $32,200', 'CTC is $2,000 per child') against the corpus. Returns verified / refuted (with the correct value and citation) / unknown. Never states a verdict it cannot ground.",
|
|
77823
78253
|
inputSchema: legacyJsonSchema(external_exports.object({
|
|
77824
78254
|
query: external_exports.string().max(2e3).describe("what the amount is, e.g. 'standard deduction'"),
|
|
77825
|
-
claimedAmount:
|
|
78255
|
+
claimedAmount: money43,
|
|
77826
78256
|
filingStatus: external_exports.enum(["single", "mfj", "mfs", "hoh", "qss"]).optional(),
|
|
77827
78257
|
asOf: external_exports.string().regex(/^\d{4}-\d{2}-\d{2}$/).optional()
|
|
77828
78258
|
}).strict())
|