@alfadocs/ui-kit-debug 1.130.2 → 1.131.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/_chunks/bill-line-table-DHKb_O7c.js +2000 -0
- package/dist/_chunks/bill-line-table-DHKb_O7c.js.map +1 -0
- package/dist/_chunks/{data-grid-C9xlUMLt.js → data-grid-B2oaI7Lt.js} +2345 -2328
- package/dist/_chunks/data-grid-B2oaI7Lt.js.map +1 -0
- package/dist/_chunks/{default-tabs-BryvhiHv.js → default-tabs-DbebYO04.js} +3 -3
- package/dist/_chunks/{default-tabs-BryvhiHv.js.map → default-tabs-DbebYO04.js.map} +1 -1
- package/dist/_chunks/{invoice-upload-list-868v1oDe.js → invoice-upload-list-B5aMffTy.js} +21 -21
- package/dist/_chunks/{invoice-upload-list-868v1oDe.js.map → invoice-upload-list-B5aMffTy.js.map} +1 -1
- package/dist/_chunks/{toolbar-BK6S9PhI.js → toolbar-CfdoJzMV.js} +2 -2
- package/dist/_chunks/{toolbar-BK6S9PhI.js.map → toolbar-CfdoJzMV.js.map} +1 -1
- package/dist/_chunks/{warehouse-load-summary-DkAKXcw0.js → warehouse-load-summary-CMMYzTDv.js} +75 -66
- package/dist/_chunks/warehouse-load-summary-CMMYzTDv.js.map +1 -0
- package/dist/agent-catalog.json +10 -10
- package/dist/agent-i18n/en.json +3 -3
- package/dist/browser-support.js +1 -1
- package/dist/components/_shared/decimal.d.ts +2 -0
- package/dist/components/_shared/decimal.d.ts.map +1 -1
- package/dist/components/bill-line-table/bill-line-table.agent.d.ts.map +1 -1
- package/dist/components/bill-line-table/bill-line-table.columns.d.ts +4 -0
- package/dist/components/bill-line-table/bill-line-table.columns.d.ts.map +1 -1
- package/dist/components/bill-line-table/bill-line-table.d.ts.map +1 -1
- package/dist/components/bill-line-table/bill-line-table.header.d.ts +6 -0
- package/dist/components/bill-line-table/bill-line-table.header.d.ts.map +1 -1
- package/dist/components/bill-line-table/bill-line-table.invoice-cell.d.ts +6 -0
- package/dist/components/bill-line-table/bill-line-table.invoice-cell.d.ts.map +1 -0
- package/dist/components/bill-line-table/bill-line-table.model.d.ts +23 -10
- package/dist/components/bill-line-table/bill-line-table.model.d.ts.map +1 -1
- package/dist/components/bill-line-table/bill-line-table.scope.d.ts +56 -0
- package/dist/components/bill-line-table/bill-line-table.scope.d.ts.map +1 -0
- package/dist/components/bill-line-table/bill-line-table.types.d.ts +90 -10
- package/dist/components/bill-line-table/bill-line-table.types.d.ts.map +1 -1
- package/dist/components/bill-line-table/bill-line-table.variants.d.ts +2 -0
- package/dist/components/bill-line-table/bill-line-table.variants.d.ts.map +1 -1
- package/dist/components/bill-line-table/index.d.ts +3 -2
- package/dist/components/bill-line-table/index.d.ts.map +1 -1
- package/dist/components/bill-line-table/index.js +20 -18
- package/dist/components/bill-table/index.js +1 -1
- package/dist/components/data-grid/body.d.ts.map +1 -1
- package/dist/components/data-grid/data-grid.d.ts.map +1 -1
- package/dist/components/data-grid/data-grid.variants.d.ts.map +1 -1
- package/dist/components/data-grid/index.js +2 -2
- package/dist/components/data-grid/types.d.ts +6 -0
- package/dist/components/data-grid/types.d.ts.map +1 -1
- package/dist/components/data-grid/use-data-grid-engine.d.ts.map +1 -1
- package/dist/components/invoice-upload-list/index.js +1 -1
- package/dist/components/invoice-upload-list/invoice-upload-list.d.ts.map +1 -1
- package/dist/components/warehouse-load-summary/index.js +1 -1
- package/dist/components/warehouse-load-summary/warehouse-load-summary.d.ts.map +1 -1
- package/dist/core.css +1 -1
- package/dist/decimal/index.js +32 -28
- package/dist/decimal/index.js.map +1 -1
- package/dist/host-compat.css +4 -1
- package/dist/index.js +1060 -1058
- package/dist/tokens.css +1 -1
- package/package.json +1 -1
- package/dist/_chunks/bill-line-table-CzYzg-Qh.js +0 -1757
- package/dist/_chunks/bill-line-table-CzYzg-Qh.js.map +0 -1
- package/dist/_chunks/data-grid-C9xlUMLt.js.map +0 -1
- package/dist/_chunks/warehouse-load-summary-DkAKXcw0.js.map +0 -1
package/dist/decimal/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
const
|
|
1
|
+
const g = {
|
|
2
2
|
quantity: {
|
|
3
3
|
allowNegative: !1,
|
|
4
4
|
maxIntegerDigits: 12,
|
|
@@ -24,11 +24,11 @@ const l = {
|
|
|
24
24
|
maxFractionDigits: 2
|
|
25
25
|
}
|
|
26
26
|
}, M = {
|
|
27
|
-
quantity: { ...
|
|
28
|
-
unitPrice: { ...
|
|
29
|
-
lineTotal: { ...
|
|
30
|
-
rate: { ...
|
|
31
|
-
}, p = /^(-)?([0-9]+)(?:\.([0-9]+))?$/, x = BigInt(Number.MAX_SAFE_INTEGER), F = BigInt(10), f = BigInt(0), N = BigInt(1), T = BigInt(2), $ = 15,
|
|
27
|
+
quantity: { ...g.quantity, minFractionDigits: 0 },
|
|
28
|
+
unitPrice: { ...g.unitPrice, minFractionDigits: 0 },
|
|
29
|
+
lineTotal: { ...g.lineTotal, minFractionDigits: 0 },
|
|
30
|
+
rate: { ...g.rate, minFractionDigits: 0 }
|
|
31
|
+
}, p = /^(-)?([0-9]+)(?:\.([0-9]+))?$/, x = BigInt(Number.MAX_SAFE_INTEGER), F = BigInt(10), f = BigInt(0), N = BigInt(1), T = BigInt(2), $ = 15, l = (t) => F ** BigInt(t), D = (t) => t < f ? -t : t;
|
|
32
32
|
function a(t, n) {
|
|
33
33
|
return D(t) > x ? null : { units: Number(t) || 0, scale: n };
|
|
34
34
|
}
|
|
@@ -37,23 +37,23 @@ function I(t, n) {
|
|
|
37
37
|
if (i === "") return { ok: !1, error: "empty" };
|
|
38
38
|
const e = p.exec(i);
|
|
39
39
|
if (!e) return { ok: !1, error: "syntax" };
|
|
40
|
-
const [, r, s = "",
|
|
41
|
-
if (
|
|
40
|
+
const [, r, s = "", c = ""] = e, o = r === "-";
|
|
41
|
+
if (o && n.allowNegative === !1)
|
|
42
42
|
return { ok: !1, error: "negative" };
|
|
43
43
|
const h = s.replace(/^0+(?=\d)/, "");
|
|
44
44
|
if (n.maxIntegerDigits !== void 0 && h.length > n.maxIntegerDigits)
|
|
45
45
|
return { ok: !1, error: "integer-digits" };
|
|
46
46
|
const d = n.minFractionDigits ?? 0, B = n.maxFractionDigits ?? Number.POSITIVE_INFINITY;
|
|
47
|
-
if (
|
|
47
|
+
if (c.length < d || c.length > B)
|
|
48
48
|
return { ok: !1, error: "fraction-digits" };
|
|
49
|
-
const m = BigInt(s +
|
|
49
|
+
const m = BigInt(s + c);
|
|
50
50
|
return {
|
|
51
51
|
ok: !0,
|
|
52
|
-
units:
|
|
53
|
-
scale:
|
|
52
|
+
units: o ? -m : m,
|
|
53
|
+
scale: c.length,
|
|
54
54
|
whole: s,
|
|
55
|
-
fraction:
|
|
56
|
-
negative:
|
|
55
|
+
fraction: c,
|
|
56
|
+
negative: o
|
|
57
57
|
};
|
|
58
58
|
}
|
|
59
59
|
function A(t, n = {}) {
|
|
@@ -80,8 +80,8 @@ function _(t, n = 0) {
|
|
|
80
80
|
return r ? `${s}${e}.${r}` : `${s}${e}`;
|
|
81
81
|
}
|
|
82
82
|
function u(t, n, i) {
|
|
83
|
-
if (i >= n) return t *
|
|
84
|
-
const e =
|
|
83
|
+
if (i >= n) return t * l(i - n);
|
|
84
|
+
const e = l(n - i), r = D(t);
|
|
85
85
|
let s = r / e;
|
|
86
86
|
return r % e * T >= e && (s += N), t < f ? -s : s;
|
|
87
87
|
}
|
|
@@ -94,7 +94,7 @@ function S(t, n, i) {
|
|
|
94
94
|
}
|
|
95
95
|
function b(t, n, i) {
|
|
96
96
|
if (n.units === 0) return null;
|
|
97
|
-
const e = i + 1 + n.scale - t.scale, r = e >= 0 ? BigInt(t.units) *
|
|
97
|
+
const e = i + 1 + n.scale - t.scale, r = e >= 0 ? BigInt(t.units) * l(e) / BigInt(n.units) : BigInt(t.units) / (BigInt(n.units) * l(-e));
|
|
98
98
|
return a(u(r, i + 1, i), i);
|
|
99
99
|
}
|
|
100
100
|
function y(t) {
|
|
@@ -103,27 +103,30 @@ function y(t) {
|
|
|
103
103
|
for (const e of t) i += u(BigInt(e.units), e.scale, n);
|
|
104
104
|
return a(i, n);
|
|
105
105
|
}
|
|
106
|
-
function O(t
|
|
106
|
+
function O(t) {
|
|
107
|
+
return t.units === 0 ? t : { units: -t.units, scale: t.scale };
|
|
108
|
+
}
|
|
109
|
+
function q(t, n) {
|
|
107
110
|
const i = Math.max(t.scale, n.scale), e = u(BigInt(t.units), t.scale, i), r = u(BigInt(n.units), n.scale, i);
|
|
108
111
|
return e < r ? -1 : e > r ? 1 : 0;
|
|
109
112
|
}
|
|
110
113
|
function E(t) {
|
|
111
114
|
return String(Math.abs(t)).replace(/0+$/, "").length || 1;
|
|
112
115
|
}
|
|
113
|
-
function
|
|
116
|
+
function R(t) {
|
|
114
117
|
return E(t.units) > $ ? null : +`${t.units}e-${t.scale}`;
|
|
115
118
|
}
|
|
116
119
|
function k(t) {
|
|
117
120
|
const n = String(t), i = n.indexOf("e");
|
|
118
121
|
if (i === -1) return n;
|
|
119
|
-
const e = n.startsWith("-") ? "-" : "", [r = "", s = ""] = n.slice(e.length, i).split("."),
|
|
120
|
-
return
|
|
122
|
+
const e = n.startsWith("-") ? "-" : "", [r = "", s = ""] = n.slice(e.length, i).split("."), c = r + s, o = r.length + Number(n.slice(i + 1));
|
|
123
|
+
return o <= 0 ? `${e}0.${"0".repeat(-o)}${c}` : o >= c.length ? e + c + "0".repeat(o - c.length) : `${e}${c.slice(0, o)}.${c.slice(o)}`;
|
|
121
124
|
}
|
|
122
|
-
function
|
|
125
|
+
function L(t, n) {
|
|
123
126
|
const [i, e = "0"] = String(t).split("e");
|
|
124
127
|
return +`${i}e${Number(e) + n}`;
|
|
125
128
|
}
|
|
126
|
-
function
|
|
129
|
+
function U(t, n) {
|
|
127
130
|
if (!Number.isFinite(t)) return null;
|
|
128
131
|
const i = I(k(t), {});
|
|
129
132
|
if (!i.ok) return null;
|
|
@@ -131,18 +134,19 @@ function L(t, n) {
|
|
|
131
134
|
return a(u(i.units, i.scale, r), r);
|
|
132
135
|
}
|
|
133
136
|
export {
|
|
134
|
-
|
|
137
|
+
g as FATTURAPA_DECIMAL,
|
|
135
138
|
M as FATTURAPA_VALUE,
|
|
136
|
-
|
|
137
|
-
|
|
139
|
+
q as compareDecimal,
|
|
140
|
+
R as decimalToNumber,
|
|
138
141
|
b as divideDecimal,
|
|
139
142
|
_ as formatDecimal,
|
|
140
143
|
w as isDecimalString,
|
|
141
144
|
S as multiplyDecimal,
|
|
142
|
-
|
|
145
|
+
O as negateDecimal,
|
|
146
|
+
U as numberToDecimal,
|
|
143
147
|
A as parseDecimal,
|
|
144
148
|
P as rescaleDecimal,
|
|
145
|
-
|
|
149
|
+
L as shiftDecimal,
|
|
146
150
|
y as sumDecimals,
|
|
147
151
|
k as toPlainString
|
|
148
152
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sources":["../../src/components/_shared/decimal.ts"],"sourcesContent":["/**\n * Exact decimal strings, with no float step.\n *\n * FatturaPA (Italian e-invoice) values such as `Quantita` \"2.50000000\" or\n * `PrezzoUnitario` \"12.345600\" carry up to 8 decimal places, and no double\n * holds most of them exactly. This module reads such text into integer\n * units plus a scale, computes with BigInt, and rounds once, half away from\n * zero, the rule NumberInput and Money use.\n *\n * React-free on purpose: hosts can use it in plain TypeScript through\n * `@alfadocs/ui-kit/decimal`. Money takes the result as `value={units}`\n * and `scale={scale}`; NumberInput takes `decimalToNumber(value)` and\n * reports back through `numberToDecimal(n, digits)`.\n */\n\n/**\n * A plain decimal as text: an optional \"-\", digits, then optionally \".\" and\n * digits. Dot only: no grouping, no exponent, no \"+\". It is the form\n * FatturaPA uses (`Quantita` `[0-9]{1,12}\\.[0-9]{2,8}`, `PrezzoUnitario`\n * and `PrezzoTotale` `[\\-]?[0-9]{1,11}\\.[0-9]{2,8}`) and the form a JSON\n * API should send for these fields.\n */\nexport type DecimalString = string;\n\n/** value = units / 10^scale. `units` is always a safe integer and `scale`\n * a whole number of 0 or more. */\nexport interface ScaledDecimal {\n units: number;\n scale: number;\n}\n\n/** Why a text is not a valid decimal. Codes, not copy: the host maps them\n * to its own messages. */\nexport type DecimalError =\n | 'empty'\n | 'syntax'\n | 'negative'\n | 'integer-digits'\n | 'fraction-digits'\n | 'unsafe';\n\nexport type ParseDecimalResult =\n | { ok: true; value: ScaledDecimal }\n | { ok: false; error: DecimalError };\n\nexport interface DecimalRules {\n /** Default true: credit notes (TD04, TD08) and discounts carry a minus. */\n allowNegative?: boolean;\n /** Most digits before the point (leading zeros not counted). */\n maxIntegerDigits?: number;\n /** Fewest digits after the point. Default 0 (the point is optional). */\n minFractionDigits?: number;\n /** Most digits after the point. Default: no limit. */\n maxFractionDigits?: number;\n}\n\n/**\n * FatturaPA 1.2 field rules, for validating XML text (the wire). `Quantita`\n * is unsigned with 2 to 8 decimals; `PrezzoUnitario` and `PrezzoTotale` are\n * signed with 2 to 8; `AliquotaIVA` has exactly 2. Check them against the\n * published schema before relying on them for anything but display.\n */\nexport const FATTURAPA_DECIMAL = {\n quantity: {\n allowNegative: false,\n maxIntegerDigits: 12,\n minFractionDigits: 2,\n maxFractionDigits: 8,\n },\n unitPrice: {\n allowNegative: true,\n maxIntegerDigits: 11,\n minFractionDigits: 2,\n maxFractionDigits: 8,\n },\n lineTotal: {\n allowNegative: true,\n maxIntegerDigits: 11,\n minFractionDigits: 2,\n maxFractionDigits: 8,\n },\n rate: {\n allowNegative: false,\n maxIntegerDigits: 3,\n minFractionDigits: 2,\n maxFractionDigits: 2,\n },\n} as const satisfies Record<string, DecimalRules>;\n\n/**\n * The same limits with the point optional (`minFractionDigits: 0`), for\n * values a kit component holds and normalises rather than XML text: \"1\"\n * (the platform's value when `Quantita` is absent) and \"2.5\" (an edited\n * quantity) are valid here and invalid as FatturaPA text.\n */\nexport const FATTURAPA_VALUE = {\n quantity: { ...FATTURAPA_DECIMAL.quantity, minFractionDigits: 0 },\n unitPrice: { ...FATTURAPA_DECIMAL.unitPrice, minFractionDigits: 0 },\n lineTotal: { ...FATTURAPA_DECIMAL.lineTotal, minFractionDigits: 0 },\n rate: { ...FATTURAPA_DECIMAL.rate, minFractionDigits: 0 },\n} as const satisfies Record<string, DecimalRules>;\n\nconst DECIMAL_PATTERN = /^(-)?([0-9]+)(?:\\.([0-9]+))?$/;\nconst MAX_SAFE = BigInt(Number.MAX_SAFE_INTEGER);\nconst TEN = BigInt(10);\nconst ZERO = BigInt(0);\nconst ONE = BigInt(1);\nconst TWO = BigInt(2);\n\n/** Significant digits a double always gives back unchanged (DBL_DIG). */\nconst EXACT_DOUBLE_DIGITS = 15;\n\nconst pow10 = (n: number): bigint => TEN ** BigInt(n);\nconst absBig = (v: bigint): bigint => (v < ZERO ? -v : v);\n\nfunction toSafe(units: bigint, scale: number): ScaledDecimal | null {\n if (absBig(units) > MAX_SAFE) return null;\n // `|| 0` turns -0 into 0: a zero credit line shows no minus sign.\n return { units: Number(units) || 0, scale };\n}\n\ninterface BigDecimal {\n ok: true;\n units: bigint;\n scale: number;\n whole: string;\n fraction: string;\n negative: boolean;\n}\n\n/** Exact parse with no safety limit, for the rounding paths. */\nfunction parseDecimalBig(\n text: string,\n rules: DecimalRules,\n): BigDecimal | { ok: false; error: DecimalError } {\n const source = text.trim();\n if (source === '') return { ok: false, error: 'empty' };\n const match = DECIMAL_PATTERN.exec(source);\n if (!match) return { ok: false, error: 'syntax' };\n const [, minus, whole = '', fraction = ''] = match;\n const negative = minus === '-';\n if (negative && rules.allowNegative === false) {\n return { ok: false, error: 'negative' };\n }\n const significantWhole = whole.replace(/^0+(?=\\d)/, '');\n if (\n rules.maxIntegerDigits !== undefined &&\n significantWhole.length > rules.maxIntegerDigits\n ) {\n return { ok: false, error: 'integer-digits' };\n }\n const minFraction = rules.minFractionDigits ?? 0;\n const maxFraction = rules.maxFractionDigits ?? Number.POSITIVE_INFINITY;\n if (fraction.length < minFraction || fraction.length > maxFraction) {\n return { ok: false, error: 'fraction-digits' };\n }\n const magnitude = BigInt(whole + fraction);\n return {\n ok: true,\n units: negative ? -magnitude : magnitude,\n scale: fraction.length,\n whole,\n fraction,\n negative,\n };\n}\n\n/**\n * Split a decimal string into integer units and a scale with no float step:\n * \"12.345600\" gives `{ units: 12345600, scale: 6 }`, the string's own\n * scale. Surrounding whitespace is trimmed (XML text nodes). When the units\n * would pass `Number.MAX_SAFE_INTEGER`, trailing zeros are dropped first\n * (same value, smaller scale), and the result is `'unsafe'` only when that\n * is still too big. With no rules, any sign and any number of digits pass.\n */\nexport function parseDecimal(\n text: string,\n rules: DecimalRules = {},\n): ParseDecimalResult {\n const parsed = parseDecimalBig(text, rules);\n if (!parsed.ok) return parsed;\n let value = toSafe(parsed.units, parsed.scale);\n if (!value) {\n const fraction = parsed.fraction.replace(/0+$/, '');\n const magnitude = BigInt(parsed.whole + fraction);\n value = toSafe(parsed.negative ? -magnitude : magnitude, fraction.length);\n }\n return value ? { ok: true, value } : { ok: false, error: 'unsafe' };\n}\n\n/** Does the text parse under these rules? */\nexport function isDecimalString(text: string, rules?: DecimalRules): boolean {\n return parseDecimal(text, rules).ok;\n}\n\n/** Exact text for a scaled decimal, padded with zeros to\n * `minFractionDigits` (FatturaPA wants at least 2). Never rounds and never\n * drops digits: `{ units: 25, scale: 1 }` gives \"2.5\", or \"2.50\" with 2. */\nexport function formatDecimal(\n value: ScaledDecimal,\n minFractionDigits = 0,\n): DecimalString {\n const magnitude = String(Math.abs(value.units)).padStart(\n value.scale + 1,\n '0',\n );\n const whole = magnitude.slice(0, magnitude.length - value.scale);\n let fraction = magnitude.slice(magnitude.length - value.scale);\n if (fraction.length < minFractionDigits) {\n fraction = fraction.padEnd(minFractionDigits, '0');\n }\n const sign = value.units < 0 ? '-' : '';\n return fraction ? `${sign}${whole}.${fraction}` : `${sign}${whole}`;\n}\n\n/** Round half away from zero, the kit's one rule (NumberInput, Money). */\nfunction roundBig(units: bigint, fromScale: number, toScale: number): bigint {\n if (toScale >= fromScale) return units * pow10(toScale - fromScale);\n const divisor = pow10(fromScale - toScale);\n const magnitude = absBig(units);\n let quotient = magnitude / divisor;\n if ((magnitude % divisor) * TWO >= divisor) quotient += ONE;\n return units < ZERO ? -quotient : quotient;\n}\n\n/** The same value at another scale, rounded half away from zero when the\n * scale shrinks. `null` when the result is not a safe integer. */\nexport function rescaleDecimal(\n value: ScaledDecimal,\n scale: number,\n): ScaledDecimal | null {\n return toSafe(roundBig(BigInt(value.units), value.scale, scale), scale);\n}\n\n/** a × b at `scale` (scale 2 for a line amount in cents), exact until the\n * one final rounding. `null` when the result is not a safe integer. */\nexport function multiplyDecimal(\n a: ScaledDecimal,\n b: ScaledDecimal,\n scale: number,\n): ScaledDecimal | null {\n const product = BigInt(a.units) * BigInt(b.units);\n return toSafe(roundBig(product, a.scale + b.scale, scale), scale);\n}\n\n/** a ÷ b at `scale`, with one rounding half away from zero (the net unit\n * cost of a line: `PrezzoTotale` ÷ quantity). `null` when `b` is zero or\n * the result is not a safe integer. */\nexport function divideDecimal(\n a: ScaledDecimal,\n b: ScaledDecimal,\n scale: number,\n): ScaledDecimal | null {\n if (b.units === 0) return null;\n // Truncate to `scale` + 1 digits (BigInt division truncates towards\n // zero), then round that last digit once: a truncated digit of 5 or more\n // means the exact quotient is at least half way.\n const shift = scale + 1 + b.scale - a.scale;\n const quotient =\n shift >= 0\n ? (BigInt(a.units) * pow10(shift)) / BigInt(b.units)\n : BigInt(a.units) / (BigInt(b.units) * pow10(-shift));\n return toSafe(roundBig(quotient, scale + 1, scale), scale);\n}\n\n/** The exact sum at the largest scale given (a totals footer). `null` when\n * the result is not a safe integer. An empty list sums to 0. */\nexport function sumDecimals(\n values: readonly ScaledDecimal[],\n): ScaledDecimal | null {\n const scale = values.reduce((max, v) => Math.max(max, v.scale), 0);\n let total = ZERO;\n for (const v of values) total += roundBig(BigInt(v.units), v.scale, scale);\n return toSafe(total, scale);\n}\n\n/** Compare by value, whatever the scales: \"1.50\" equals \"1.5\". */\nexport function compareDecimal(a: ScaledDecimal, b: ScaledDecimal): -1 | 0 | 1 {\n const scale = Math.max(a.scale, b.scale);\n const x = roundBig(BigInt(a.units), a.scale, scale);\n const y = roundBig(BigInt(b.units), b.scale, scale);\n return x < y ? -1 : x > y ? 1 : 0;\n}\n\n/** Significant digits of a safe integer, trailing zeros not counted. */\nfunction significantDigits(units: number): number {\n return String(Math.abs(units)).replace(/0+$/, '').length || 1;\n}\n\n/**\n * The number for NumberInput's `value`, only when it is exact both ways: up\n * to 15 significant digits a double gives back the same decimal text, so\n * the field shows what the platform sent. `null` beyond that: the host\n * keeps the value read-only rather than lose digits.\n */\nexport function decimalToNumber(value: ScaledDecimal): number | null {\n if (significantDigits(value.units) > EXACT_DOUBLE_DIGITS) return null;\n return Number(`${value.units}e-${value.scale}`);\n}\n\n/**\n * A finite number as plain decimal text, never exponent notation:\n * `String(2e-7)` is \"2e-7\", which an edit text cannot use. Values from 1e-6\n * up to 1e21 already print plainly and pass through.\n */\nexport function toPlainString(n: number): string {\n const s = String(n);\n const at = s.indexOf('e');\n if (at === -1) return s;\n const sign = s.startsWith('-') ? '-' : '';\n const [whole = '', fraction = ''] = s.slice(sign.length, at).split('.');\n const digits = whole + fraction;\n const point = whole.length + Number(s.slice(at + 1));\n if (point <= 0) return `${sign}0.${'0'.repeat(-point)}${digits}`;\n if (point >= digits.length) {\n return sign + digits + '0'.repeat(point - digits.length);\n }\n return `${sign}${digits.slice(0, point)}.${digits.slice(point)}`;\n}\n\n/**\n * Move the decimal point `by` places. Working on the exponent, not by\n * multiplying, avoids binary error: `0.07 * 100` is 7.000000000000001 and\n * `Math.round(1.005 * 100) / 100` is 1, where this gives 7 and 100.5.\n * Handles values that print in exponent notation (5e-7, 1e21) by adding to\n * their exponent instead of appending a second one.\n */\nexport function shiftDecimal(n: number, by: number): number {\n const [mantissa, exponent = '0'] = String(n).split('e');\n return Number(`${mantissa}e${Number(exponent) + by}`);\n}\n\n/**\n * NumberInput's `onChange` value back to a decimal: the double's shortest\n * text, rounded half away from zero to `maxFractionDigits` (8 for a\n * FatturaPA quantity). `null` for NaN, Infinity or an unsafe result. Then\n * `formatDecimal` gives the text to store.\n */\nexport function numberToDecimal(\n n: number,\n maxFractionDigits: number,\n): ScaledDecimal | null {\n if (!Number.isFinite(n)) return null;\n // Round on the exact digits first: 0.1 + 0.2 prints with 17 fraction\n // digits, more than a safe integer holds, and still means 0.3 at 8.\n const parsed = parseDecimalBig(toPlainString(n), {});\n if (!parsed.ok) return null;\n const digits = Math.max(0, Math.floor(maxFractionDigits));\n const scale = Math.min(parsed.scale, digits);\n return toSafe(roundBig(parsed.units, parsed.scale, scale), scale);\n}\n"],"names":["FATTURAPA_DECIMAL","FATTURAPA_VALUE","DECIMAL_PATTERN","MAX_SAFE","TEN","ZERO","ONE","TWO","EXACT_DOUBLE_DIGITS","pow10","n","absBig","v","toSafe","units","scale","parseDecimalBig","text","rules","source","match","minus","whole","fraction","negative","significantWhole","minFraction","maxFraction","magnitude","parseDecimal","parsed","value","isDecimalString","formatDecimal","minFractionDigits","sign","roundBig","fromScale","toScale","divisor","quotient","rescaleDecimal","multiplyDecimal","a","b","product","divideDecimal","shift","sumDecimals","values","max","total","compareDecimal","x","y","significantDigits","decimalToNumber","toPlainString","s","at","digits","point","shiftDecimal","by","mantissa","exponent","numberToDecimal","maxFractionDigits"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.js","sources":["../../src/components/_shared/decimal.ts"],"sourcesContent":["/**\n * Exact decimal strings, with no float step.\n *\n * FatturaPA (Italian e-invoice) values such as `Quantita` \"2.50000000\" or\n * `PrezzoUnitario` \"12.345600\" carry up to 8 decimal places, and no double\n * holds most of them exactly. This module reads such text into integer\n * units plus a scale, computes with BigInt, and rounds once, half away from\n * zero, the rule NumberInput and Money use.\n *\n * React-free on purpose: hosts can use it in plain TypeScript through\n * `@alfadocs/ui-kit/decimal`. Money takes the result as `value={units}`\n * and `scale={scale}`; NumberInput takes `decimalToNumber(value)` and\n * reports back through `numberToDecimal(n, digits)`.\n */\n\n/**\n * A plain decimal as text: an optional \"-\", digits, then optionally \".\" and\n * digits. Dot only: no grouping, no exponent, no \"+\". It is the form\n * FatturaPA uses (`Quantita` `[0-9]{1,12}\\.[0-9]{2,8}`, `PrezzoUnitario`\n * and `PrezzoTotale` `[\\-]?[0-9]{1,11}\\.[0-9]{2,8}`) and the form a JSON\n * API should send for these fields.\n */\nexport type DecimalString = string;\n\n/** value = units / 10^scale. `units` is always a safe integer and `scale`\n * a whole number of 0 or more. */\nexport interface ScaledDecimal {\n units: number;\n scale: number;\n}\n\n/** Why a text is not a valid decimal. Codes, not copy: the host maps them\n * to its own messages. */\nexport type DecimalError =\n | 'empty'\n | 'syntax'\n | 'negative'\n | 'integer-digits'\n | 'fraction-digits'\n | 'unsafe';\n\nexport type ParseDecimalResult =\n | { ok: true; value: ScaledDecimal }\n | { ok: false; error: DecimalError };\n\nexport interface DecimalRules {\n /** Default true: credit notes (TD04, TD08) and discounts carry a minus. */\n allowNegative?: boolean;\n /** Most digits before the point (leading zeros not counted). */\n maxIntegerDigits?: number;\n /** Fewest digits after the point. Default 0 (the point is optional). */\n minFractionDigits?: number;\n /** Most digits after the point. Default: no limit. */\n maxFractionDigits?: number;\n}\n\n/**\n * FatturaPA 1.2 field rules, for validating XML text (the wire). `Quantita`\n * is unsigned with 2 to 8 decimals; `PrezzoUnitario` and `PrezzoTotale` are\n * signed with 2 to 8; `AliquotaIVA` has exactly 2. Check them against the\n * published schema before relying on them for anything but display.\n */\nexport const FATTURAPA_DECIMAL = {\n quantity: {\n allowNegative: false,\n maxIntegerDigits: 12,\n minFractionDigits: 2,\n maxFractionDigits: 8,\n },\n unitPrice: {\n allowNegative: true,\n maxIntegerDigits: 11,\n minFractionDigits: 2,\n maxFractionDigits: 8,\n },\n lineTotal: {\n allowNegative: true,\n maxIntegerDigits: 11,\n minFractionDigits: 2,\n maxFractionDigits: 8,\n },\n rate: {\n allowNegative: false,\n maxIntegerDigits: 3,\n minFractionDigits: 2,\n maxFractionDigits: 2,\n },\n} as const satisfies Record<string, DecimalRules>;\n\n/**\n * The same limits with the point optional (`minFractionDigits: 0`), for\n * values a kit component holds and normalises rather than XML text: \"1\"\n * (the platform's value when `Quantita` is absent) and \"2.5\" (an edited\n * quantity) are valid here and invalid as FatturaPA text.\n */\nexport const FATTURAPA_VALUE = {\n quantity: { ...FATTURAPA_DECIMAL.quantity, minFractionDigits: 0 },\n unitPrice: { ...FATTURAPA_DECIMAL.unitPrice, minFractionDigits: 0 },\n lineTotal: { ...FATTURAPA_DECIMAL.lineTotal, minFractionDigits: 0 },\n rate: { ...FATTURAPA_DECIMAL.rate, minFractionDigits: 0 },\n} as const satisfies Record<string, DecimalRules>;\n\nconst DECIMAL_PATTERN = /^(-)?([0-9]+)(?:\\.([0-9]+))?$/;\nconst MAX_SAFE = BigInt(Number.MAX_SAFE_INTEGER);\nconst TEN = BigInt(10);\nconst ZERO = BigInt(0);\nconst ONE = BigInt(1);\nconst TWO = BigInt(2);\n\n/** Significant digits a double always gives back unchanged (DBL_DIG). */\nconst EXACT_DOUBLE_DIGITS = 15;\n\nconst pow10 = (n: number): bigint => TEN ** BigInt(n);\nconst absBig = (v: bigint): bigint => (v < ZERO ? -v : v);\n\nfunction toSafe(units: bigint, scale: number): ScaledDecimal | null {\n if (absBig(units) > MAX_SAFE) return null;\n // `|| 0` turns -0 into 0: a zero credit line shows no minus sign.\n return { units: Number(units) || 0, scale };\n}\n\ninterface BigDecimal {\n ok: true;\n units: bigint;\n scale: number;\n whole: string;\n fraction: string;\n negative: boolean;\n}\n\n/** Exact parse with no safety limit, for the rounding paths. */\nfunction parseDecimalBig(\n text: string,\n rules: DecimalRules,\n): BigDecimal | { ok: false; error: DecimalError } {\n const source = text.trim();\n if (source === '') return { ok: false, error: 'empty' };\n const match = DECIMAL_PATTERN.exec(source);\n if (!match) return { ok: false, error: 'syntax' };\n const [, minus, whole = '', fraction = ''] = match;\n const negative = minus === '-';\n if (negative && rules.allowNegative === false) {\n return { ok: false, error: 'negative' };\n }\n const significantWhole = whole.replace(/^0+(?=\\d)/, '');\n if (\n rules.maxIntegerDigits !== undefined &&\n significantWhole.length > rules.maxIntegerDigits\n ) {\n return { ok: false, error: 'integer-digits' };\n }\n const minFraction = rules.minFractionDigits ?? 0;\n const maxFraction = rules.maxFractionDigits ?? Number.POSITIVE_INFINITY;\n if (fraction.length < minFraction || fraction.length > maxFraction) {\n return { ok: false, error: 'fraction-digits' };\n }\n const magnitude = BigInt(whole + fraction);\n return {\n ok: true,\n units: negative ? -magnitude : magnitude,\n scale: fraction.length,\n whole,\n fraction,\n negative,\n };\n}\n\n/**\n * Split a decimal string into integer units and a scale with no float step:\n * \"12.345600\" gives `{ units: 12345600, scale: 6 }`, the string's own\n * scale. Surrounding whitespace is trimmed (XML text nodes). When the units\n * would pass `Number.MAX_SAFE_INTEGER`, trailing zeros are dropped first\n * (same value, smaller scale), and the result is `'unsafe'` only when that\n * is still too big. With no rules, any sign and any number of digits pass.\n */\nexport function parseDecimal(\n text: string,\n rules: DecimalRules = {},\n): ParseDecimalResult {\n const parsed = parseDecimalBig(text, rules);\n if (!parsed.ok) return parsed;\n let value = toSafe(parsed.units, parsed.scale);\n if (!value) {\n const fraction = parsed.fraction.replace(/0+$/, '');\n const magnitude = BigInt(parsed.whole + fraction);\n value = toSafe(parsed.negative ? -magnitude : magnitude, fraction.length);\n }\n return value ? { ok: true, value } : { ok: false, error: 'unsafe' };\n}\n\n/** Does the text parse under these rules? */\nexport function isDecimalString(text: string, rules?: DecimalRules): boolean {\n return parseDecimal(text, rules).ok;\n}\n\n/** Exact text for a scaled decimal, padded with zeros to\n * `minFractionDigits` (FatturaPA wants at least 2). Never rounds and never\n * drops digits: `{ units: 25, scale: 1 }` gives \"2.5\", or \"2.50\" with 2. */\nexport function formatDecimal(\n value: ScaledDecimal,\n minFractionDigits = 0,\n): DecimalString {\n const magnitude = String(Math.abs(value.units)).padStart(\n value.scale + 1,\n '0',\n );\n const whole = magnitude.slice(0, magnitude.length - value.scale);\n let fraction = magnitude.slice(magnitude.length - value.scale);\n if (fraction.length < minFractionDigits) {\n fraction = fraction.padEnd(minFractionDigits, '0');\n }\n const sign = value.units < 0 ? '-' : '';\n return fraction ? `${sign}${whole}.${fraction}` : `${sign}${whole}`;\n}\n\n/** Round half away from zero, the kit's one rule (NumberInput, Money). */\nfunction roundBig(units: bigint, fromScale: number, toScale: number): bigint {\n if (toScale >= fromScale) return units * pow10(toScale - fromScale);\n const divisor = pow10(fromScale - toScale);\n const magnitude = absBig(units);\n let quotient = magnitude / divisor;\n if ((magnitude % divisor) * TWO >= divisor) quotient += ONE;\n return units < ZERO ? -quotient : quotient;\n}\n\n/** The same value at another scale, rounded half away from zero when the\n * scale shrinks. `null` when the result is not a safe integer. */\nexport function rescaleDecimal(\n value: ScaledDecimal,\n scale: number,\n): ScaledDecimal | null {\n return toSafe(roundBig(BigInt(value.units), value.scale, scale), scale);\n}\n\n/** a × b at `scale` (scale 2 for a line amount in cents), exact until the\n * one final rounding. `null` when the result is not a safe integer. */\nexport function multiplyDecimal(\n a: ScaledDecimal,\n b: ScaledDecimal,\n scale: number,\n): ScaledDecimal | null {\n const product = BigInt(a.units) * BigInt(b.units);\n return toSafe(roundBig(product, a.scale + b.scale, scale), scale);\n}\n\n/** a ÷ b at `scale`, with one rounding half away from zero (the net unit\n * cost of a line: `PrezzoTotale` ÷ quantity). `null` when `b` is zero or\n * the result is not a safe integer. */\nexport function divideDecimal(\n a: ScaledDecimal,\n b: ScaledDecimal,\n scale: number,\n): ScaledDecimal | null {\n if (b.units === 0) return null;\n // Truncate to `scale` + 1 digits (BigInt division truncates towards\n // zero), then round that last digit once: a truncated digit of 5 or more\n // means the exact quotient is at least half way.\n const shift = scale + 1 + b.scale - a.scale;\n const quotient =\n shift >= 0\n ? (BigInt(a.units) * pow10(shift)) / BigInt(b.units)\n : BigInt(a.units) / (BigInt(b.units) * pow10(-shift));\n return toSafe(roundBig(quotient, scale + 1, scale), scale);\n}\n\n/** The exact sum at the largest scale given (a totals footer). `null` when\n * the result is not a safe integer. An empty list sums to 0. */\nexport function sumDecimals(\n values: readonly ScaledDecimal[],\n): ScaledDecimal | null {\n const scale = values.reduce((max, v) => Math.max(max, v.scale), 0);\n let total = ZERO;\n for (const v of values) total += roundBig(BigInt(v.units), v.scale, scale);\n return toSafe(total, scale);\n}\n\n/** The same value with the opposite sign (zero stays zero). */\nexport function negateDecimal(value: ScaledDecimal): ScaledDecimal {\n return value.units === 0\n ? value\n : { units: -value.units, scale: value.scale };\n}\n\n/** Compare by value, whatever the scales: \"1.50\" equals \"1.5\". */\nexport function compareDecimal(a: ScaledDecimal, b: ScaledDecimal): -1 | 0 | 1 {\n const scale = Math.max(a.scale, b.scale);\n const x = roundBig(BigInt(a.units), a.scale, scale);\n const y = roundBig(BigInt(b.units), b.scale, scale);\n return x < y ? -1 : x > y ? 1 : 0;\n}\n\n/** Significant digits of a safe integer, trailing zeros not counted. */\nfunction significantDigits(units: number): number {\n return String(Math.abs(units)).replace(/0+$/, '').length || 1;\n}\n\n/**\n * The number for NumberInput's `value`, only when it is exact both ways: up\n * to 15 significant digits a double gives back the same decimal text, so\n * the field shows what the platform sent. `null` beyond that: the host\n * keeps the value read-only rather than lose digits.\n */\nexport function decimalToNumber(value: ScaledDecimal): number | null {\n if (significantDigits(value.units) > EXACT_DOUBLE_DIGITS) return null;\n return Number(`${value.units}e-${value.scale}`);\n}\n\n/**\n * A finite number as plain decimal text, never exponent notation:\n * `String(2e-7)` is \"2e-7\", which an edit text cannot use. Values from 1e-6\n * up to 1e21 already print plainly and pass through.\n */\nexport function toPlainString(n: number): string {\n const s = String(n);\n const at = s.indexOf('e');\n if (at === -1) return s;\n const sign = s.startsWith('-') ? '-' : '';\n const [whole = '', fraction = ''] = s.slice(sign.length, at).split('.');\n const digits = whole + fraction;\n const point = whole.length + Number(s.slice(at + 1));\n if (point <= 0) return `${sign}0.${'0'.repeat(-point)}${digits}`;\n if (point >= digits.length) {\n return sign + digits + '0'.repeat(point - digits.length);\n }\n return `${sign}${digits.slice(0, point)}.${digits.slice(point)}`;\n}\n\n/**\n * Move the decimal point `by` places. Working on the exponent, not by\n * multiplying, avoids binary error: `0.07 * 100` is 7.000000000000001 and\n * `Math.round(1.005 * 100) / 100` is 1, where this gives 7 and 100.5.\n * Handles values that print in exponent notation (5e-7, 1e21) by adding to\n * their exponent instead of appending a second one.\n */\nexport function shiftDecimal(n: number, by: number): number {\n const [mantissa, exponent = '0'] = String(n).split('e');\n return Number(`${mantissa}e${Number(exponent) + by}`);\n}\n\n/**\n * NumberInput's `onChange` value back to a decimal: the double's shortest\n * text, rounded half away from zero to `maxFractionDigits` (8 for a\n * FatturaPA quantity). `null` for NaN, Infinity or an unsafe result. Then\n * `formatDecimal` gives the text to store.\n */\nexport function numberToDecimal(\n n: number,\n maxFractionDigits: number,\n): ScaledDecimal | null {\n if (!Number.isFinite(n)) return null;\n // Round on the exact digits first: 0.1 + 0.2 prints with 17 fraction\n // digits, more than a safe integer holds, and still means 0.3 at 8.\n const parsed = parseDecimalBig(toPlainString(n), {});\n if (!parsed.ok) return null;\n const digits = Math.max(0, Math.floor(maxFractionDigits));\n const scale = Math.min(parsed.scale, digits);\n return toSafe(roundBig(parsed.units, parsed.scale, scale), scale);\n}\n"],"names":["FATTURAPA_DECIMAL","FATTURAPA_VALUE","DECIMAL_PATTERN","MAX_SAFE","TEN","ZERO","ONE","TWO","EXACT_DOUBLE_DIGITS","pow10","n","absBig","v","toSafe","units","scale","parseDecimalBig","text","rules","source","match","minus","whole","fraction","negative","significantWhole","minFraction","maxFraction","magnitude","parseDecimal","parsed","value","isDecimalString","formatDecimal","minFractionDigits","sign","roundBig","fromScale","toScale","divisor","quotient","rescaleDecimal","multiplyDecimal","a","b","product","divideDecimal","shift","sumDecimals","values","max","total","negateDecimal","compareDecimal","x","y","significantDigits","decimalToNumber","toPlainString","s","at","digits","point","shiftDecimal","by","mantissa","exponent","numberToDecimal","maxFractionDigits"],"mappings":"AA8DO,MAAMA,IAAoB;AAAA,EAC/B,UAAU;AAAA,IACR,eAAe;AAAA,IACf,kBAAkB;AAAA,IAClB,mBAAmB;AAAA,IACnB,mBAAmB;AAAA,EAAA;AAAA,EAErB,WAAW;AAAA,IACT,eAAe;AAAA,IACf,kBAAkB;AAAA,IAClB,mBAAmB;AAAA,IACnB,mBAAmB;AAAA,EAAA;AAAA,EAErB,WAAW;AAAA,IACT,eAAe;AAAA,IACf,kBAAkB;AAAA,IAClB,mBAAmB;AAAA,IACnB,mBAAmB;AAAA,EAAA;AAAA,EAErB,MAAM;AAAA,IACJ,eAAe;AAAA,IACf,kBAAkB;AAAA,IAClB,mBAAmB;AAAA,IACnB,mBAAmB;AAAA,EAAA;AAEvB,GAQaC,IAAkB;AAAA,EAC7B,UAAU,EAAE,GAAGD,EAAkB,UAAU,mBAAmB,EAAA;AAAA,EAC9D,WAAW,EAAE,GAAGA,EAAkB,WAAW,mBAAmB,EAAA;AAAA,EAChE,WAAW,EAAE,GAAGA,EAAkB,WAAW,mBAAmB,EAAA;AAAA,EAChE,MAAM,EAAE,GAAGA,EAAkB,MAAM,mBAAmB,EAAA;AACxD,GAEME,IAAkB,iCAClBC,IAAW,OAAO,OAAO,gBAAgB,GACzCC,IAAM,OAAO,EAAE,GACfC,IAAO,OAAO,CAAC,GACfC,IAAM,OAAO,CAAC,GACdC,IAAM,OAAO,CAAC,GAGdC,IAAsB,IAEtBC,IAAQ,CAACC,MAAsBN,KAAO,OAAOM,CAAC,GAC9CC,IAAS,CAACC,MAAuBA,IAAIP,IAAO,CAACO,IAAIA;AAEvD,SAASC,EAAOC,GAAeC,GAAqC;AAClE,SAAIJ,EAAOG,CAAK,IAAIX,IAAiB,OAE9B,EAAE,OAAO,OAAOW,CAAK,KAAK,GAAG,OAAAC,EAAA;AACtC;AAYA,SAASC,EACPC,GACAC,GACiD;AACjD,QAAMC,IAASF,EAAK,KAAA;AACpB,MAAIE,MAAW,GAAI,QAAO,EAAE,IAAI,IAAO,OAAO,QAAA;AAC9C,QAAMC,IAAQlB,EAAgB,KAAKiB,CAAM;AACzC,MAAI,CAACC,EAAO,QAAO,EAAE,IAAI,IAAO,OAAO,SAAA;AACvC,QAAM,CAAA,EAAGC,GAAOC,IAAQ,IAAIC,IAAW,EAAE,IAAIH,GACvCI,IAAWH,MAAU;AAC3B,MAAIG,KAAYN,EAAM,kBAAkB;AACtC,WAAO,EAAE,IAAI,IAAO,OAAO,WAAA;AAE7B,QAAMO,IAAmBH,EAAM,QAAQ,aAAa,EAAE;AACtD,MACEJ,EAAM,qBAAqB,UAC3BO,EAAiB,SAASP,EAAM;AAEhC,WAAO,EAAE,IAAI,IAAO,OAAO,iBAAA;AAE7B,QAAMQ,IAAcR,EAAM,qBAAqB,GACzCS,IAAcT,EAAM,qBAAqB,OAAO;AACtD,MAAIK,EAAS,SAASG,KAAeH,EAAS,SAASI;AACrD,WAAO,EAAE,IAAI,IAAO,OAAO,kBAAA;AAE7B,QAAMC,IAAY,OAAON,IAAQC,CAAQ;AACzC,SAAO;AAAA,IACL,IAAI;AAAA,IACJ,OAAOC,IAAW,CAACI,IAAYA;AAAA,IAC/B,OAAOL,EAAS;AAAA,IAChB,OAAAD;AAAA,IACA,UAAAC;AAAA,IACA,UAAAC;AAAA,EAAA;AAEJ;AAUO,SAASK,EACdZ,GACAC,IAAsB,IACF;AACpB,QAAMY,IAASd,EAAgBC,GAAMC,CAAK;AAC1C,MAAI,CAACY,EAAO,GAAI,QAAOA;AACvB,MAAIC,IAAQlB,EAAOiB,EAAO,OAAOA,EAAO,KAAK;AAC7C,MAAI,CAACC,GAAO;AACV,UAAMR,IAAWO,EAAO,SAAS,QAAQ,OAAO,EAAE,GAC5CF,IAAY,OAAOE,EAAO,QAAQP,CAAQ;AAChD,IAAAQ,IAAQlB,EAAOiB,EAAO,WAAW,CAACF,IAAYA,GAAWL,EAAS,MAAM;AAAA,EAC1E;AACA,SAAOQ,IAAQ,EAAE,IAAI,IAAM,OAAAA,MAAU,EAAE,IAAI,IAAO,OAAO,SAAA;AAC3D;AAGO,SAASC,EAAgBf,GAAcC,GAA+B;AAC3E,SAAOW,EAAaZ,GAAMC,CAAK,EAAE;AACnC;AAKO,SAASe,EACdF,GACAG,IAAoB,GACL;AACf,QAAMN,IAAY,OAAO,KAAK,IAAIG,EAAM,KAAK,CAAC,EAAE;AAAA,IAC9CA,EAAM,QAAQ;AAAA,IACd;AAAA,EAAA,GAEIT,IAAQM,EAAU,MAAM,GAAGA,EAAU,SAASG,EAAM,KAAK;AAC/D,MAAIR,IAAWK,EAAU,MAAMA,EAAU,SAASG,EAAM,KAAK;AAC7D,EAAIR,EAAS,SAASW,MACpBX,IAAWA,EAAS,OAAOW,GAAmB,GAAG;AAEnD,QAAMC,IAAOJ,EAAM,QAAQ,IAAI,MAAM;AACrC,SAAOR,IAAW,GAAGY,CAAI,GAAGb,CAAK,IAAIC,CAAQ,KAAK,GAAGY,CAAI,GAAGb,CAAK;AACnE;AAGA,SAASc,EAAStB,GAAeuB,GAAmBC,GAAyB;AAC3E,MAAIA,KAAWD,EAAW,QAAOvB,IAAQL,EAAM6B,IAAUD,CAAS;AAClE,QAAME,IAAU9B,EAAM4B,IAAYC,CAAO,GACnCV,IAAYjB,EAAOG,CAAK;AAC9B,MAAI0B,IAAWZ,IAAYW;AAC3B,SAAKX,IAAYW,IAAWhC,KAAOgC,MAASC,KAAYlC,IACjDQ,IAAQT,IAAO,CAACmC,IAAWA;AACpC;AAIO,SAASC,EACdV,GACAhB,GACsB;AACtB,SAAOF,EAAOuB,EAAS,OAAOL,EAAM,KAAK,GAAGA,EAAM,OAAOhB,CAAK,GAAGA,CAAK;AACxE;AAIO,SAAS2B,EACdC,GACAC,GACA7B,GACsB;AACtB,QAAM8B,IAAU,OAAOF,EAAE,KAAK,IAAI,OAAOC,EAAE,KAAK;AAChD,SAAO/B,EAAOuB,EAASS,GAASF,EAAE,QAAQC,EAAE,OAAO7B,CAAK,GAAGA,CAAK;AAClE;AAKO,SAAS+B,EACdH,GACAC,GACA7B,GACsB;AACtB,MAAI6B,EAAE,UAAU,EAAG,QAAO;AAI1B,QAAMG,IAAQhC,IAAQ,IAAI6B,EAAE,QAAQD,EAAE,OAChCH,IACJO,KAAS,IACJ,OAAOJ,EAAE,KAAK,IAAIlC,EAAMsC,CAAK,IAAK,OAAOH,EAAE,KAAK,IACjD,OAAOD,EAAE,KAAK,KAAK,OAAOC,EAAE,KAAK,IAAInC,EAAM,CAACsC,CAAK;AACvD,SAAOlC,EAAOuB,EAASI,GAAUzB,IAAQ,GAAGA,CAAK,GAAGA,CAAK;AAC3D;AAIO,SAASiC,EACdC,GACsB;AACtB,QAAMlC,IAAQkC,EAAO,OAAO,CAACC,GAAKtC,MAAM,KAAK,IAAIsC,GAAKtC,EAAE,KAAK,GAAG,CAAC;AACjE,MAAIuC,IAAQ9C;AACZ,aAAWO,KAAKqC,EAAQ,CAAAE,KAASf,EAAS,OAAOxB,EAAE,KAAK,GAAGA,EAAE,OAAOG,CAAK;AACzE,SAAOF,EAAOsC,GAAOpC,CAAK;AAC5B;AAGO,SAASqC,EAAcrB,GAAqC;AACjE,SAAOA,EAAM,UAAU,IACnBA,IACA,EAAE,OAAO,CAACA,EAAM,OAAO,OAAOA,EAAM,MAAA;AAC1C;AAGO,SAASsB,EAAeV,GAAkBC,GAA8B;AAC7E,QAAM7B,IAAQ,KAAK,IAAI4B,EAAE,OAAOC,EAAE,KAAK,GACjCU,IAAIlB,EAAS,OAAOO,EAAE,KAAK,GAAGA,EAAE,OAAO5B,CAAK,GAC5CwC,IAAInB,EAAS,OAAOQ,EAAE,KAAK,GAAGA,EAAE,OAAO7B,CAAK;AAClD,SAAOuC,IAAIC,IAAI,KAAKD,IAAIC,IAAI,IAAI;AAClC;AAGA,SAASC,EAAkB1C,GAAuB;AAChD,SAAO,OAAO,KAAK,IAAIA,CAAK,CAAC,EAAE,QAAQ,OAAO,EAAE,EAAE,UAAU;AAC9D;AAQO,SAAS2C,EAAgB1B,GAAqC;AACnE,SAAIyB,EAAkBzB,EAAM,KAAK,IAAIvB,IAA4B,OAC1D,CAAO,GAAGuB,EAAM,KAAK,KAAKA,EAAM,KAAK;AAC9C;AAOO,SAAS2B,EAAchD,GAAmB;AAC/C,QAAMiD,IAAI,OAAOjD,CAAC,GACZkD,IAAKD,EAAE,QAAQ,GAAG;AACxB,MAAIC,MAAO,GAAI,QAAOD;AACtB,QAAMxB,IAAOwB,EAAE,WAAW,GAAG,IAAI,MAAM,IACjC,CAACrC,IAAQ,IAAIC,IAAW,EAAE,IAAIoC,EAAE,MAAMxB,EAAK,QAAQyB,CAAE,EAAE,MAAM,GAAG,GAChEC,IAASvC,IAAQC,GACjBuC,IAAQxC,EAAM,SAAS,OAAOqC,EAAE,MAAMC,IAAK,CAAC,CAAC;AACnD,SAAIE,KAAS,IAAU,GAAG3B,CAAI,KAAK,IAAI,OAAO,CAAC2B,CAAK,CAAC,GAAGD,CAAM,KAC1DC,KAASD,EAAO,SACX1B,IAAO0B,IAAS,IAAI,OAAOC,IAAQD,EAAO,MAAM,IAElD,GAAG1B,CAAI,GAAG0B,EAAO,MAAM,GAAGC,CAAK,CAAC,IAAID,EAAO,MAAMC,CAAK,CAAC;AAChE;AASO,SAASC,EAAarD,GAAWsD,GAAoB;AAC1D,QAAM,CAACC,GAAUC,IAAW,GAAG,IAAI,OAAOxD,CAAC,EAAE,MAAM,GAAG;AACtD,SAAO,CAAO,GAAGuD,CAAQ,IAAI,OAAOC,CAAQ,IAAIF,CAAE;AACpD;AAQO,SAASG,EACdzD,GACA0D,GACsB;AACtB,MAAI,CAAC,OAAO,SAAS1D,CAAC,EAAG,QAAO;AAGhC,QAAMoB,IAASd,EAAgB0C,EAAchD,CAAC,GAAG,CAAA,CAAE;AACnD,MAAI,CAACoB,EAAO,GAAI,QAAO;AACvB,QAAM+B,IAAS,KAAK,IAAI,GAAG,KAAK,MAAMO,CAAiB,CAAC,GAClDrD,IAAQ,KAAK,IAAIe,EAAO,OAAO+B,CAAM;AAC3C,SAAOhD,EAAOuB,EAASN,EAAO,OAAOA,EAAO,OAAOf,CAAK,GAAGA,CAAK;AAClE;"}
|
package/dist/host-compat.css
CHANGED
|
@@ -214,7 +214,7 @@
|
|
|
214
214
|
|
|
215
215
|
/* ───────────────────────────────────────────────────────────────────────
|
|
216
216
|
SECTION B — non-token declarations. ORIGINAL LAYER PRESERVED.
|
|
217
|
-
|
|
217
|
+
175 declarations across 171 rules.
|
|
218
218
|
|
|
219
219
|
Kit-authored arbitrary-value utilities (`ds:w-[20rem]`) and the
|
|
220
220
|
vendored AG Grid rules. These set real properties on real elements,
|
|
@@ -601,6 +601,9 @@
|
|
|
601
601
|
.ds\:\[inline-size\:26rem\] {
|
|
602
602
|
inline-size:416px;
|
|
603
603
|
}
|
|
604
|
+
.ds\:\[inline-size\:30rem\] {
|
|
605
|
+
inline-size:480px;
|
|
606
|
+
}
|
|
604
607
|
.ds\:\[inline-size\:32rem\] {
|
|
605
608
|
inline-size:512px;
|
|
606
609
|
}
|