@oxyhq/bloom 0.7.7 → 0.8.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/lib/commonjs/normalize-colors.d.js +2 -0
- package/lib/commonjs/normalize-colors.d.js.map +1 -0
- package/lib/commonjs/theme/apply-dark-class.js +8 -24
- package/lib/commonjs/theme/apply-dark-class.js.map +1 -1
- package/lib/commonjs/theme/build-theme.js +39 -61
- package/lib/commonjs/theme/build-theme.js.map +1 -1
- package/lib/commonjs/theme/color-presets.js +9 -9
- package/lib/commonjs/theme/color-scope/index.web.js +7 -14
- package/lib/commonjs/theme/color-scope/index.web.js.map +1 -1
- package/lib/commonjs/theme/color-scope/style-builder.js +7 -6
- package/lib/commonjs/theme/color-scope/style-builder.js.map +1 -1
- package/lib/commonjs/theme/color-space.js +76 -0
- package/lib/commonjs/theme/color-space.js.map +1 -0
- package/lib/commonjs/theme/index.js +0 -6
- package/lib/commonjs/theme/index.js.map +1 -1
- package/lib/commonjs/theme/native-root-vars.native.js +28 -18
- package/lib/commonjs/theme/native-root-vars.native.js.map +1 -1
- package/lib/commonjs/theme/preset-vars.js +20 -152
- package/lib/commonjs/theme/preset-vars.js.map +1 -1
- package/lib/commonjs/theme/token-registry.js +123 -0
- package/lib/commonjs/theme/token-registry.js.map +1 -0
- package/lib/module/normalize-colors.d.js +2 -0
- package/lib/module/normalize-colors.d.js.map +1 -0
- package/lib/module/theme/apply-dark-class.js +8 -19
- package/lib/module/theme/apply-dark-class.js.map +1 -1
- package/lib/module/theme/build-theme.js +39 -61
- package/lib/module/theme/build-theme.js.map +1 -1
- package/lib/module/theme/color-presets.js +9 -9
- package/lib/module/theme/color-scope/index.web.js +7 -14
- package/lib/module/theme/color-scope/index.web.js.map +1 -1
- package/lib/module/theme/color-scope/style-builder.js +7 -6
- package/lib/module/theme/color-scope/style-builder.js.map +1 -1
- package/lib/module/theme/color-space.js +69 -0
- package/lib/module/theme/color-space.js.map +1 -0
- package/lib/module/theme/index.js +1 -1
- package/lib/module/theme/index.js.map +1 -1
- package/lib/module/theme/native-root-vars.native.js +29 -18
- package/lib/module/theme/native-root-vars.native.js.map +1 -1
- package/lib/module/theme/preset-vars.js +19 -150
- package/lib/module/theme/preset-vars.js.map +1 -1
- package/lib/module/theme/token-registry.js +113 -0
- package/lib/module/theme/token-registry.js.map +1 -0
- package/lib/typescript/commonjs/theme/apply-dark-class.d.ts +5 -10
- package/lib/typescript/commonjs/theme/apply-dark-class.d.ts.map +1 -1
- package/lib/typescript/commonjs/theme/build-theme.d.ts +1 -1
- package/lib/typescript/commonjs/theme/build-theme.d.ts.map +1 -1
- package/lib/typescript/commonjs/theme/color-presets.d.ts +9 -9
- package/lib/typescript/commonjs/theme/color-scope/index.web.d.ts.map +1 -1
- package/lib/typescript/commonjs/theme/color-scope/style-builder.d.ts +5 -2
- package/lib/typescript/commonjs/theme/color-scope/style-builder.d.ts.map +1 -1
- package/lib/typescript/commonjs/theme/color-space.d.ts +28 -0
- package/lib/typescript/commonjs/theme/color-space.d.ts.map +1 -0
- package/lib/typescript/commonjs/theme/index.d.ts +1 -2
- package/lib/typescript/commonjs/theme/index.d.ts.map +1 -1
- package/lib/typescript/commonjs/theme/native-root-vars.native.d.ts +25 -15
- package/lib/typescript/commonjs/theme/native-root-vars.native.d.ts.map +1 -1
- package/lib/typescript/commonjs/theme/preset-vars.d.ts +11 -74
- package/lib/typescript/commonjs/theme/preset-vars.d.ts.map +1 -1
- package/lib/typescript/commonjs/theme/token-registry.d.ts +53 -0
- package/lib/typescript/commonjs/theme/token-registry.d.ts.map +1 -0
- package/lib/typescript/commonjs/theme/types.d.ts +3 -0
- package/lib/typescript/commonjs/theme/types.d.ts.map +1 -1
- package/lib/typescript/module/theme/apply-dark-class.d.ts +5 -10
- package/lib/typescript/module/theme/apply-dark-class.d.ts.map +1 -1
- package/lib/typescript/module/theme/build-theme.d.ts +1 -1
- package/lib/typescript/module/theme/build-theme.d.ts.map +1 -1
- package/lib/typescript/module/theme/color-presets.d.ts +9 -9
- package/lib/typescript/module/theme/color-scope/index.web.d.ts.map +1 -1
- package/lib/typescript/module/theme/color-scope/style-builder.d.ts +5 -2
- package/lib/typescript/module/theme/color-scope/style-builder.d.ts.map +1 -1
- package/lib/typescript/module/theme/color-space.d.ts +28 -0
- package/lib/typescript/module/theme/color-space.d.ts.map +1 -0
- package/lib/typescript/module/theme/index.d.ts +1 -2
- package/lib/typescript/module/theme/index.d.ts.map +1 -1
- package/lib/typescript/module/theme/native-root-vars.native.d.ts +25 -15
- package/lib/typescript/module/theme/native-root-vars.native.d.ts.map +1 -1
- package/lib/typescript/module/theme/preset-vars.d.ts +11 -74
- package/lib/typescript/module/theme/preset-vars.d.ts.map +1 -1
- package/lib/typescript/module/theme/token-registry.d.ts +53 -0
- package/lib/typescript/module/theme/token-registry.d.ts.map +1 -0
- package/lib/typescript/module/theme/types.d.ts +3 -0
- package/lib/typescript/module/theme/types.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/__tests__/BloomColorScope.test.tsx +5 -5
- package/src/__tests__/BloomThemeProvider.test.tsx +4 -3
- package/src/__tests__/apply-dark-class.test.ts +26 -21
- package/src/__tests__/native-root-vars.test.ts +8 -7
- package/src/__tests__/preset-vars.test.ts +31 -77
- package/src/__tests__/theme.test.ts +6 -6
- package/src/normalize-colors.d.ts +22 -0
- package/src/react-native-css.d.ts +3 -3
- package/src/theme/__tests__/__fixtures__/golden-resolved-tokens.json +574 -0
- package/src/theme/__tests__/__snapshots__/visual-gallery.test.tsx.snap +838 -0
- package/src/theme/__tests__/color-space.test.ts +28 -0
- package/src/theme/__tests__/golden-tokens.test.ts +33 -0
- package/src/theme/__tests__/runtime-contract.test.ts +49 -0
- package/src/theme/__tests__/token-registry.test.ts +30 -0
- package/src/theme/__tests__/visual-gallery.test.tsx +10 -0
- package/src/theme/apply-dark-class.ts +8 -17
- package/src/theme/build-theme.ts +39 -67
- package/src/theme/color-presets.ts +9 -9
- package/src/theme/color-scope/index.web.tsx +7 -14
- package/src/theme/color-scope/style-builder.ts +7 -4
- package/src/theme/color-space.ts +56 -0
- package/src/theme/index.ts +1 -6
- package/src/theme/native-root-vars.native.ts +28 -18
- package/src/theme/preset-vars.ts +17 -178
- package/src/theme/token-registry.ts +159 -0
- package/src/theme/types.ts +3 -0
|
@@ -6,17 +6,17 @@
|
|
|
6
6
|
* Keys carry a leading `--` for historical reasons (shadcn-style CSS variable
|
|
7
7
|
* names) — keep in mind the values are platform-agnostic **raw HSL triples**
|
|
8
8
|
* (e.g. `'185 100% 20%'` or `'185 100% 20% / 0.5'`), not CSS-resolved colors.
|
|
9
|
-
* The
|
|
10
|
-
*
|
|
11
|
-
*
|
|
12
|
-
*
|
|
13
|
-
*
|
|
14
|
-
*
|
|
15
|
-
*
|
|
9
|
+
* The single canonical resolver `getResolvedTokens` (in `token-registry.ts`)
|
|
10
|
+
* converts this raw map to sRGB `rgb(...)` for every runtime write — the same
|
|
11
|
+
* values drive BOTH layers:
|
|
12
|
+
* - the web layer: `getResolvedTokens`'s `rgb(...)` strings are written to
|
|
13
|
+
* `document.documentElement` / a `BloomColorScope` element, so `var(--x)` —
|
|
14
|
+
* the form Tailwind v4 `@theme inline` compiles its color utilities to —
|
|
15
|
+
* resolves to a valid color directly, and
|
|
16
16
|
* - the native layer (`buildTheme` resolves the raw triples into `hsl(...)`
|
|
17
17
|
* strings consumable by React Native styles; `native-root-vars.native.ts`
|
|
18
|
-
* writes the
|
|
19
|
-
*
|
|
18
|
+
* writes the same canonical `rgb(...)` values into react-native-css's
|
|
19
|
+
* `rootVariables` family).
|
|
20
20
|
*
|
|
21
21
|
* The `--` prefix is an implementation detail we will drop in a future major.
|
|
22
22
|
*/
|
|
@@ -3,25 +3,18 @@
|
|
|
3
3
|
import React, { Children, cloneElement, isValidElement, useContext, useMemo } from 'react';
|
|
4
4
|
import { BloomThemeContext } from "../BloomThemeProvider.js";
|
|
5
5
|
import { buildTheme } from "../build-theme.js";
|
|
6
|
-
import {
|
|
7
|
-
import { buildScopeVars } from "./style-builder.js";
|
|
6
|
+
import { getResolvedTokens } from "../token-registry.js";
|
|
8
7
|
|
|
9
8
|
/**
|
|
10
|
-
* `
|
|
11
|
-
*
|
|
12
|
-
* element's inline `style`,
|
|
13
|
-
* `var(--x)` directly
|
|
14
|
-
*
|
|
15
|
-
* non-color tokens pass through. See `toWebColorValue` in `../preset-vars`.
|
|
9
|
+
* `getResolvedTokens` returns every canonical token already resolved to an sRGB
|
|
10
|
+
* `rgb(...)` string — the SAME pipeline the document-root web writer and the
|
|
11
|
+
* native writer use. Scoped onto an element's inline `style`, Tailwind v4's
|
|
12
|
+
* compiled utilities read these as `var(--x)` directly, so each base token is a
|
|
13
|
+
* full CSS color with no per-value wrapping needed.
|
|
16
14
|
*/
|
|
17
15
|
import { Fragment as _Fragment, jsx as _jsx } from "react/jsx-runtime";
|
|
18
16
|
function buildWebScopeVars(colorPreset, mode) {
|
|
19
|
-
|
|
20
|
-
const out = {};
|
|
21
|
-
for (const [key, value] of Object.entries(raw)) {
|
|
22
|
-
out[key] = toWebColorValue(key, value);
|
|
23
|
-
}
|
|
24
|
-
return out;
|
|
17
|
+
return getResolvedTokens(colorPreset, mode);
|
|
25
18
|
}
|
|
26
19
|
|
|
27
20
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["React","Children","cloneElement","isValidElement","useContext","useMemo","BloomThemeContext","buildTheme","
|
|
1
|
+
{"version":3,"names":["React","Children","cloneElement","isValidElement","useContext","useMemo","BloomThemeContext","buildTheme","getResolvedTokens","Fragment","_Fragment","jsx","_jsx","buildWebScopeVars","colorPreset","mode","BloomColorScope","asChild","style","children","parent","Error","resolvedMode","theme","contextValue","varsStyle","content","child","only","childStyle","props","mergedStyle","Provider","value","useColorScopeStyle"],"sourceRoot":"../../../../src","sources":["theme/color-scope/index.web.tsx"],"mappings":"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","ignoreList":[]}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
|
|
3
3
|
import { Platform } from 'react-native';
|
|
4
|
-
import {
|
|
4
|
+
import { getResolvedTokens } from "../token-registry.js";
|
|
5
5
|
import { lazyRequire } from "../../utils/lazy-require.js";
|
|
6
6
|
|
|
7
7
|
/**
|
|
@@ -15,13 +15,14 @@ const getNativeWindVars = lazyRequire('nativewind');
|
|
|
15
15
|
|
|
16
16
|
/**
|
|
17
17
|
* Build the CSS custom-property map for a preset, ready to be applied to a
|
|
18
|
-
* subtree.
|
|
19
|
-
*
|
|
18
|
+
* subtree. Every token is resolved to an sRGB `rgb(...)` string via
|
|
19
|
+
* `getResolvedTokens` — the single canonical token pipeline shared by web and
|
|
20
|
+
* native — so Tailwind v4 `@theme` utilities (e.g. `bg-background`) and
|
|
21
|
+
* `color-mix`-based alpha utilities (`bg-primary/10`) both resolve against the
|
|
22
|
+
* same color values. Keys retain the leading `--`.
|
|
20
23
|
*/
|
|
21
24
|
export function buildScopeVars(colorPreset, mode) {
|
|
22
|
-
return
|
|
23
|
-
includeResolvedColorVars: true
|
|
24
|
-
});
|
|
25
|
+
return getResolvedTokens(colorPreset, mode);
|
|
25
26
|
}
|
|
26
27
|
|
|
27
28
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["Platform","
|
|
1
|
+
{"version":3,"names":["Platform","getResolvedTokens","lazyRequire","getNativeWindVars","buildScopeVars","colorPreset","mode","getVariableContextProvider","OS","module","VariableContextProvider","buildNativePresetStyle","undefined","vars"],"sourceRoot":"../../../../src","sources":["theme/color-scope/style-builder.ts"],"mappings":";;AACA,SAASA,QAAQ,QAAwC,cAAc;AAEvE,SAASC,iBAAiB,QAAQ,sBAAmB;AAErD,SAASC,WAAW,QAAQ,6BAA0B;;AAEtD;AACA;AACA;AACA;AACA;AACA;;AAWA,MAAMC,iBAAiB,GAAGD,WAAW,CAAuB,YAAY,CAAC;;AAEzE;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO,SAASE,cAAcA,CAC5BC,WAAyB,EACzBC,IAAsB,EACE;EACxB,OAAOL,iBAAiB,CAACI,WAAW,EAAEC,IAAI,CAAC;AAC7C;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO,SAASC,0BAA0BA,CAAA,EAA4C;EACpF,IAAIP,QAAQ,CAACQ,EAAE,KAAK,KAAK,EAAE,OAAO,IAAI;EACtC,MAAMC,MAAM,GAAGN,iBAAiB,CAAC,CAAC;EAClC,IAAI,CAACM,MAAM,IAAI,OAAOA,MAAM,CAACC,uBAAuB,KAAK,UAAU,EAAE,OAAO,IAAI;EAChF,OAAOD,MAAM,CAACC,uBAAuB;AACvC;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO,SAASC,sBAAsBA,CACpCN,WAAyB,EACzBC,IAAsB,EACA;EACtB,IAAIN,QAAQ,CAACQ,EAAE,KAAK,KAAK,EAAE,OAAOI,SAAS;EAC3C,MAAMH,MAAM,GAAGN,iBAAiB,CAAC,CAAC;EAClC,IAAI,CAACM,MAAM,IAAI,OAAOA,MAAM,CAACI,IAAI,KAAK,UAAU,EAAE,OAAOD,SAAS;EAClE,OAAOH,MAAM,CAACI,IAAI,CAACT,cAAc,CAACC,WAAW,EAAEC,IAAI,CAAC,CAAC;AACvD","ignoreList":[]}
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
// l 0..1, c 0..~0.4, h deg
|
|
4
|
+
// 0..255 integers
|
|
5
|
+
|
|
6
|
+
const clamp = (n, lo, hi) => Math.min(hi, Math.max(lo, n));
|
|
7
|
+
const srgbGamma = x => x <= 0.0031308 ? 12.92 * x : 1.055 * Math.pow(x, 1 / 2.4) - 0.055;
|
|
8
|
+
|
|
9
|
+
/** OKLCH → linear OKLab → linear sRGB → gamma sRGB → 0..255. Pure. */
|
|
10
|
+
export function oklchToSrgb({
|
|
11
|
+
l,
|
|
12
|
+
c,
|
|
13
|
+
h
|
|
14
|
+
}) {
|
|
15
|
+
const hr = h * Math.PI / 180;
|
|
16
|
+
const a = c * Math.cos(hr);
|
|
17
|
+
const b2 = c * Math.sin(hr);
|
|
18
|
+
const l_ = l + 0.3963377774 * a + 0.2158037573 * b2;
|
|
19
|
+
const m_ = l - 0.1055613458 * a - 0.0638541728 * b2;
|
|
20
|
+
const s_ = l - 0.0894841775 * a - 1.291485548 * b2;
|
|
21
|
+
const lc = l_ ** 3,
|
|
22
|
+
mc = m_ ** 3,
|
|
23
|
+
sc = s_ ** 3;
|
|
24
|
+
const lr = +4.0767416621 * lc - 3.3077115913 * mc + 0.2309699292 * sc;
|
|
25
|
+
const lg = -1.2684380046 * lc + 2.6097574011 * mc - 0.3413193965 * sc;
|
|
26
|
+
const lb = -0.0041960863 * lc - 0.7034186147 * mc + 1.707614701 * sc;
|
|
27
|
+
return {
|
|
28
|
+
r: Math.round(clamp(srgbGamma(lr), 0, 1) * 255),
|
|
29
|
+
g: Math.round(clamp(srgbGamma(lg), 0, 1) * 255),
|
|
30
|
+
b: Math.round(clamp(srgbGamma(lb), 0, 1) * 255)
|
|
31
|
+
};
|
|
32
|
+
}
|
|
33
|
+
export function srgbToRgbString({
|
|
34
|
+
r,
|
|
35
|
+
g,
|
|
36
|
+
b
|
|
37
|
+
}, alpha) {
|
|
38
|
+
return alpha === undefined || alpha >= 1 ? `rgb(${r} ${g} ${b})` : `rgb(${r} ${g} ${b} / ${alpha})`;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* Parse an `rgb(...)` / `rgba(...)` string into an {@link Rgb}.
|
|
43
|
+
*
|
|
44
|
+
* Contract: input MUST be an `rgb(...)` / `rgba(...)` string (e.g. a resolved
|
|
45
|
+
* token from `getResolvedTokens`). Both modern (`rgb(r g b)`) and legacy
|
|
46
|
+
* (`rgb(r, g, b)`) syntaxes are accepted. Anything else throws — this is a
|
|
47
|
+
* canonical-pipeline primitive and a non-rgb input signals a real bug at the
|
|
48
|
+
* call site, never a value to silently coerce to black.
|
|
49
|
+
*
|
|
50
|
+
* @throws {Error} if `s` is not an `rgb()` / `rgba()` string.
|
|
51
|
+
*/
|
|
52
|
+
export function parseRgbString(s) {
|
|
53
|
+
const inner = s.match(/rgba?\(([^)]+)\)/i)?.[1];
|
|
54
|
+
if (inner === undefined) {
|
|
55
|
+
throw new Error(`parseRgbString: expected an rgb() string, got: ${s}`);
|
|
56
|
+
}
|
|
57
|
+
const [r, g, b] = inner.split(/[ ,/]+/).map(n => parseInt(n, 10));
|
|
58
|
+
return {
|
|
59
|
+
r: r ?? 0,
|
|
60
|
+
g: g ?? 0,
|
|
61
|
+
b: b ?? 0
|
|
62
|
+
};
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
/** Cheap perceptual-ish distance in sRGB (sufficient for a ≤1 rounding gate). */
|
|
66
|
+
export function deltaE(a, b) {
|
|
67
|
+
return Math.sqrt((a.r - b.r) ** 2 + (a.g - b.g) ** 2 + (a.b - b.b) ** 2) / Math.sqrt(3);
|
|
68
|
+
}
|
|
69
|
+
//# sourceMappingURL=color-space.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":["clamp","n","lo","hi","Math","min","max","srgbGamma","x","pow","oklchToSrgb","l","c","h","hr","PI","a","cos","b2","sin","l_","m_","s_","lc","mc","sc","lr","lg","lb","r","round","g","b","srgbToRgbString","alpha","undefined","parseRgbString","s","inner","match","Error","split","map","parseInt","deltaE","sqrt"],"sourceRoot":"../../../src","sources":["theme/color-space.ts"],"mappings":"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","ignoreList":[]}
|
|
@@ -5,7 +5,7 @@ export { BloomColorScope, useColorScopeStyle } from './color-scope';
|
|
|
5
5
|
export { buildTheme, STATUS_COLORS } from "./build-theme.js";
|
|
6
6
|
export { useTheme, useThemeColor, useBloomTheme } from "./use-theme.js";
|
|
7
7
|
export { APP_COLOR_NAMES, PREMIUM_COLOR_NAMES, APP_COLOR_PRESETS, HEX_TO_APP_COLOR, hexToAppColorName } from "./color-presets.js";
|
|
8
|
-
export { getPresetVars, applyPresetVarsToDocument
|
|
8
|
+
export { getPresetVars, applyPresetVarsToDocument } from "./preset-vars.js";
|
|
9
9
|
export { applyDarkClass } from "./apply-dark-class.js";
|
|
10
10
|
export { setColorSchemeSafe } from "./set-color-scheme-safe.js";
|
|
11
11
|
export { initCssInteropDarkMode } from "./init-css-interop.js";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["BloomThemeProvider","BloomColorScope","useColorScopeStyle","buildTheme","STATUS_COLORS","useTheme","useThemeColor","useBloomTheme","APP_COLOR_NAMES","PREMIUM_COLOR_NAMES","APP_COLOR_PRESETS","HEX_TO_APP_COLOR","hexToAppColorName","getPresetVars","applyPresetVarsToDocument","
|
|
1
|
+
{"version":3,"names":["BloomThemeProvider","BloomColorScope","useColorScopeStyle","buildTheme","STATUS_COLORS","useTheme","useThemeColor","useBloomTheme","APP_COLOR_NAMES","PREMIUM_COLOR_NAMES","APP_COLOR_PRESETS","HEX_TO_APP_COLOR","hexToAppColorName","getPresetVars","applyPresetVarsToDocument","applyDarkClass","setColorSchemeSafe","initCssInteropDarkMode","webLocalStorage"],"sourceRoot":"../../../src","sources":["theme/index.ts"],"mappings":";;AAAA,SAASA,kBAAkB,QAAQ,yBAAsB;AAKzD,SAASC,eAAe,EAAEC,kBAAkB,QAAQ,eAAe;AAEnE,SAASC,UAAU,EAAEC,aAAa,QAAQ,kBAAe;AACzD,SAASC,QAAQ,EAAEC,aAAa,EAAEC,aAAa,QAAQ,gBAAa;AAGpE,SACEC,eAAe,EACfC,mBAAmB,EACnBC,iBAAiB,EACjBC,gBAAgB,EAChBC,iBAAiB,QACZ,oBAAiB;AACxB,SAASC,aAAa,EAAEC,yBAAyB,QAAQ,kBAAe;AACxE,SAASC,cAAc,QAAQ,uBAAoB;AACnD,SAASC,kBAAkB,QAAQ,4BAAyB;AAC5D,SAASC,sBAAsB,QAAQ,uBAAoB;AAE3D,SAASC,eAAe,QAAQ,kBAAe","ignoreList":[]}
|
|
@@ -17,7 +17,8 @@
|
|
|
17
17
|
// only thing that can type this import, and it MUST reach the consumer. The
|
|
18
18
|
// directive ships raw in `src/` (Bloom publishes `files: ["src", "lib"]`).
|
|
19
19
|
import { rootVariables } from 'react-native-css/native-internal';
|
|
20
|
-
import {
|
|
20
|
+
import { getResolvedTokens } from "./token-registry.js";
|
|
21
|
+
|
|
21
22
|
/**
|
|
22
23
|
* Publish the active color preset's CSS custom properties into react-native-css's
|
|
23
24
|
* GLOBAL root-variable family so they reach the ENTIRE native app tree — including
|
|
@@ -40,18 +41,28 @@ import { buildScopeVars } from "./color-scope/style-builder.js";
|
|
|
40
41
|
* `BloomThemeProvider`'s `VariableContextProvider` only feeds path #1, so the navigator
|
|
41
42
|
* host and every portal/modal — which render outside that subtree — never see the
|
|
42
43
|
* preset vars and fall through to `rootVariables`/`universalVariables`. By default those
|
|
43
|
-
* families hold only react-native-css's own `__rn-css-rem`/`__rn-css-color` entries
|
|
44
|
-
*
|
|
45
|
-
*
|
|
46
|
-
*
|
|
47
|
-
*
|
|
48
|
-
*
|
|
49
|
-
*
|
|
44
|
+
* families hold only react-native-css's own `__rn-css-rem`/`__rn-css-color` entries, so
|
|
45
|
+
* the whole tree below the navigator renders monochrome until the palette is injected at
|
|
46
|
+
* runtime. Writing the vars into `rootVariables` here is the exact same mechanism
|
|
47
|
+
* react-native-css uses for compiled `:root {}` / `@theme` vars (`StyleCollection.inject`
|
|
48
|
+
* does `rootVariables(name).set(valueArray)`), so portaled content resolves the palette
|
|
49
|
+
* identically regardless of React-tree position.
|
|
50
|
+
*
|
|
51
|
+
* Consumer contract (CRITICAL — single canonical color pipeline)
|
|
52
|
+
* -------------------------------------------------------------
|
|
53
|
+
* Each base `--x` token is now written as a FULL `rgb(...)` color (not a raw HSL
|
|
54
|
+
* triple). A consuming app's Tailwind `@theme` must therefore reference these
|
|
55
|
+
* base tokens DIRECTLY (its Tailwind color var equals `var(--x)`) and must NOT
|
|
56
|
+
* wrap them in `hsl(...)`. The legacy `hsl(var(--x))` indirection (which assumed
|
|
57
|
+
* a raw triple) would produce the invalid `hsl(rgb(...))` and must be removed in
|
|
58
|
+
* every consumer. Web and native now share this one contract.
|
|
50
59
|
*
|
|
51
|
-
*
|
|
52
|
-
*
|
|
53
|
-
*
|
|
54
|
-
*
|
|
60
|
+
* Every token is written as an sRGB `rgb(...)` string from the single canonical
|
|
61
|
+
* token pipeline (`getResolvedTokens`) — `primary: 'rgb(31 153 239)'` — the SAME
|
|
62
|
+
* values web writes to `document.documentElement`. sRGB is the space
|
|
63
|
+
* react-native-css's `color-mix` resolver registers, so `color-mix`-based alpha
|
|
64
|
+
* utilities (`bg-primary/10`) resolve on native; full (non-alpha) utilities
|
|
65
|
+
* resolve directly through bloom's `global.css` `var(--x)` indirection.
|
|
55
66
|
*
|
|
56
67
|
* Why a STATIC `import`, not a runtime `require` (critical)
|
|
57
68
|
* ---------------------------------------------------------
|
|
@@ -81,15 +92,15 @@ import { buildScopeVars } from "./color-scope/style-builder.js";
|
|
|
81
92
|
* `shared.rootVariables[name]`, and `@property --x` goes through
|
|
82
93
|
* `name.startsWith("--") ? name.slice(2) : name`. The lookup side matches: a `var(--x)`
|
|
83
94
|
* reference compiles to `[{}, "var", ident.slice(2)]`, so `varResolver` looks up the
|
|
84
|
-
* bare name. `
|
|
85
|
-
* writing each entry.
|
|
95
|
+
* bare name. `getResolvedTokens` returns keys WITH the `--` prefix, so we strip it
|
|
96
|
+
* before writing each entry.
|
|
86
97
|
*
|
|
87
98
|
* Value shape
|
|
88
99
|
* -----------
|
|
89
100
|
* Each entry is a `VariableValue[]` — an array of `[value, mediaCondition?]` tuples.
|
|
90
101
|
* Bloom's preset vars are unconditional, so each is a single-element `[[value]]`, e.g.
|
|
91
|
-
* `rootVariables('primary').set([['
|
|
92
|
-
* emits for unconditional `:root` vars.
|
|
102
|
+
* `rootVariables('primary').set([['rgb(31 153 239)']])`. This is the same shape the
|
|
103
|
+
* compiler emits for unconditional `:root` vars.
|
|
93
104
|
*
|
|
94
105
|
* This is native-only and additive: the `VariableContextProvider` wrapper stays (it is
|
|
95
106
|
* the correct, scoped mechanism for `BloomColorScope` subtree overrides and harmlessly
|
|
@@ -112,9 +123,9 @@ import { buildScopeVars } from "./color-scope/style-builder.js";
|
|
|
112
123
|
*/
|
|
113
124
|
export function applyNativeRootVars(colorPreset, mode) {
|
|
114
125
|
if (typeof rootVariables !== 'function') return;
|
|
115
|
-
const vars =
|
|
126
|
+
const vars = getResolvedTokens(colorPreset, mode);
|
|
116
127
|
for (const [key, value] of Object.entries(vars)) {
|
|
117
|
-
// The family is keyed by the bare name; `
|
|
128
|
+
// The family is keyed by the bare name; `getResolvedTokens` keys include `--`.
|
|
118
129
|
const name = key.startsWith('--') ? key.slice(2) : key;
|
|
119
130
|
rootVariables(name).set([[value]]);
|
|
120
131
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["rootVariables","
|
|
1
|
+
{"version":3,"names":["rootVariables","getResolvedTokens","applyNativeRootVars","colorPreset","mode","vars","key","value","Object","entries","name","startsWith","slice","set"],"sourceRoot":"../../../src","sources":["theme/native-root-vars.native.ts"],"mappings":";;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAASA,aAAa,QAAQ,kCAAkC;AAGhE,SAASC,iBAAiB,QAAQ,qBAAkB;;AAEpD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO,SAASC,mBAAmBA,CAACC,WAAyB,EAAEC,IAAsB,EAAQ;EAC3F,IAAI,OAAOJ,aAAa,KAAK,UAAU,EAAE;EAEzC,MAAMK,IAAI,GAAGJ,iBAAiB,CAACE,WAAW,EAAEC,IAAI,CAAC;EACjD,KAAK,MAAM,CAACE,GAAG,EAAEC,KAAK,CAAC,IAAIC,MAAM,CAACC,OAAO,CAACJ,IAAI,CAAC,EAAE;IAC/C;IACA,MAAMK,IAAI,GAAGJ,GAAG,CAACK,UAAU,CAAC,IAAI,CAAC,GAAGL,GAAG,CAACM,KAAK,CAAC,CAAC,CAAC,GAAGN,GAAG;IACtDN,aAAa,CAACU,IAAI,CAAC,CAACG,GAAG,CAAC,CAAC,CAACN,KAAK,CAAC,CAAC,CAAC;EACpC;AACF","ignoreList":[]}
|
|
@@ -2,6 +2,11 @@
|
|
|
2
2
|
|
|
3
3
|
import { Platform } from 'react-native';
|
|
4
4
|
import { APP_COLOR_PRESETS } from "./color-presets.js";
|
|
5
|
+
// Circular at the module graph level (`token-registry` imports `getPresetVars`
|
|
6
|
+
// from here), but safe: `getResolvedTokens` is only referenced inside the
|
|
7
|
+
// `applyPresetVarsToDocument` function body — i.e. at call time, after both
|
|
8
|
+
// modules have finished evaluating — never during module initialization.
|
|
9
|
+
import { getResolvedTokens } from "./token-registry.js";
|
|
5
10
|
function extractHue(hslVar) {
|
|
6
11
|
return parseInt(hslVar.split(' ')[0] ?? '0', 10);
|
|
7
12
|
}
|
|
@@ -9,139 +14,6 @@ function extractSat(hslVar) {
|
|
|
9
14
|
return parseInt(hslVar.split(' ')[1] ?? '0', 10);
|
|
10
15
|
}
|
|
11
16
|
|
|
12
|
-
/**
|
|
13
|
-
* Convert a shadcn-style HSL triple (`'H S% L%'`, optionally with an alpha tail
|
|
14
|
-
* `'H S% L% / A'`) into an sRGB `rgb(...)` string.
|
|
15
|
-
*
|
|
16
|
-
* Why rgb and not hsl (the native alpha-utility bug this fixes)
|
|
17
|
-
* -------------------------------------------------------------
|
|
18
|
-
* Tailwind v4 compiles an alpha-on-theme-color utility (`bg-primary/10`) into a
|
|
19
|
-
* `color-mix(... var(--color-primary) 10%, transparent)` declaration. On native,
|
|
20
|
-
* react-native-css resolves that `color-mix` at runtime via `colorjs.io/fn`, but
|
|
21
|
-
* its `color-mix` implementation registers ONLY the `sRGB`, `P3`, and `OKLab`
|
|
22
|
-
* color spaces — never `HSL`. So if `--color-primary` resolves to an `hsl(...)`
|
|
23
|
-
* string, `parse('hsl(...)')` throws, the mix is swallowed, and the utility
|
|
24
|
-
* silently produces no color. Emitting the resolved var as `rgb(...)` (a space
|
|
25
|
-
* colorjs.io always has registered) makes the alpha utilities resolve on native,
|
|
26
|
-
* matching web. Full (non-alpha) utilities already worked because React Native's
|
|
27
|
-
* native color parser handles `hsl()` directly; only `color-mix` was affected.
|
|
28
|
-
*
|
|
29
|
-
* Output is space-separated channels (`rgb(31 153 239)`), the modern CSS syntax
|
|
30
|
-
* parsed by both `colorjs.io/fn` (with only sRGB/P3/OKLab registered) and
|
|
31
|
-
* react-native-web / browsers. An alpha tail emits `rgb(r g b / a)`, likewise
|
|
32
|
-
* parsed by both.
|
|
33
|
-
*
|
|
34
|
-
* Pure function — standard HSL→sRGB conversion, channels rounded to integers.
|
|
35
|
-
* Tolerates a `deg` suffix on the hue and `%` suffixes on saturation/lightness.
|
|
36
|
-
*/
|
|
37
|
-
export function hslTripletToRgb(triplet) {
|
|
38
|
-
const [colorPart, alphaPart] = triplet.split('/').map(part => part.trim());
|
|
39
|
-
const channels = (colorPart ?? '').split(/\s+/).filter(Boolean);
|
|
40
|
-
const hue = parseFloat((channels[0] ?? '0').replace(/deg$/i, ''));
|
|
41
|
-
const sat = parseFloat((channels[1] ?? '0').replace('%', '')) / 100;
|
|
42
|
-
const light = parseFloat((channels[2] ?? '0').replace('%', '')) / 100;
|
|
43
|
-
const h = Number.isFinite(hue) ? hue : 0;
|
|
44
|
-
const s = Number.isFinite(sat) ? sat : 0;
|
|
45
|
-
const l = Number.isFinite(light) ? light : 0;
|
|
46
|
-
const chroma = (1 - Math.abs(2 * l - 1)) * s;
|
|
47
|
-
const huePrime = (h % 360 + 360) % 360 / 60;
|
|
48
|
-
const second = chroma * (1 - Math.abs(huePrime % 2 - 1));
|
|
49
|
-
let r = 0;
|
|
50
|
-
let g = 0;
|
|
51
|
-
let b = 0;
|
|
52
|
-
if (huePrime < 1) {
|
|
53
|
-
[r, g, b] = [chroma, second, 0];
|
|
54
|
-
} else if (huePrime < 2) {
|
|
55
|
-
[r, g, b] = [second, chroma, 0];
|
|
56
|
-
} else if (huePrime < 3) {
|
|
57
|
-
[r, g, b] = [0, chroma, second];
|
|
58
|
-
} else if (huePrime < 4) {
|
|
59
|
-
[r, g, b] = [0, second, chroma];
|
|
60
|
-
} else if (huePrime < 5) {
|
|
61
|
-
[r, g, b] = [second, 0, chroma];
|
|
62
|
-
} else {
|
|
63
|
-
[r, g, b] = [chroma, 0, second];
|
|
64
|
-
}
|
|
65
|
-
const match = l - chroma / 2;
|
|
66
|
-
const red = Math.round((r + match) * 255);
|
|
67
|
-
const green = Math.round((g + match) * 255);
|
|
68
|
-
const blue = Math.round((b + match) * 255);
|
|
69
|
-
if (alphaPart !== undefined && alphaPart !== '') {
|
|
70
|
-
const alpha = alphaPart.endsWith('%') ? parseFloat(alphaPart) / 100 : parseFloat(alphaPart);
|
|
71
|
-
const safeAlpha = Number.isFinite(alpha) ? alpha : 1;
|
|
72
|
-
return `rgb(${red} ${green} ${blue} / ${safeAlpha})`;
|
|
73
|
-
}
|
|
74
|
-
return `rgb(${red} ${green} ${blue})`;
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
/**
|
|
78
|
-
* Prefix that marks a Tailwind v4 resolved color var (`--color-primary`). These
|
|
79
|
-
* are already emitted as full `rgb(...)` colors by `getPresetVars` and must be
|
|
80
|
-
* written to web verbatim — wrapping them would corrupt the value.
|
|
81
|
-
*/
|
|
82
|
-
const RESOLVED_COLOR_VAR_PREFIX = '--color-';
|
|
83
|
-
|
|
84
|
-
/**
|
|
85
|
-
* Matches a shadcn-style raw HSL triple — `H S% L%`, optionally with an alpha
|
|
86
|
-
* tail `H S% L% / A`. The value starts with a digit (or a leading `-`) and
|
|
87
|
-
* carries at least one `%` (the saturation/lightness units), which together
|
|
88
|
-
* distinguish a bare triple from an already-resolved CSS color (`rgb(...)`,
|
|
89
|
-
* `hsl(...)`, `#fff`, named colors) or a unitless/length token (`--radius`).
|
|
90
|
-
* Mirrors the triple shape parsed by `hslTripletToRgb`.
|
|
91
|
-
*/
|
|
92
|
-
const RAW_HSL_TRIPLE = /^-?\d[\d.]*\s+[\d.]+%/;
|
|
93
|
-
|
|
94
|
-
/**
|
|
95
|
-
* Transform a single preset var into the value to write to a WEB element
|
|
96
|
-
* (`document.documentElement` or a `BloomColorScope` subtree element).
|
|
97
|
-
*
|
|
98
|
-
* The web apps (Vite + Tailwind v4 + shadcn) compile their `@theme inline`
|
|
99
|
-
* block so the color utilities reference the BASE token directly — e.g.
|
|
100
|
-
* `.bg-background { background-color: var(--background) }`. So on web the base
|
|
101
|
-
* `--x` tokens MUST resolve to a COMPLETE CSS color; a bare HSL triple
|
|
102
|
-
* (`185 50% 5%`) is invalid as a `background-color` value and renders
|
|
103
|
-
* transparent (the production incident this fixes). We therefore wrap raw
|
|
104
|
-
* triples in `hsl(...)`, preserving the exact preset color math (and any `/ A`
|
|
105
|
-
* alpha tail, valid in modern `hsl(H S% L% / A)` syntax) with zero rounding
|
|
106
|
-
* drift.
|
|
107
|
-
*
|
|
108
|
-
* Values that are already full colors pass through unchanged:
|
|
109
|
-
* - `--color-*` resolved vars (already `rgb(...)` from `getPresetVars`),
|
|
110
|
-
* - any value not shaped like a raw HSL triple (`--radius: 0.5rem`,
|
|
111
|
-
* pre-resolved `rgb(...)`/`hsl(...)`, etc.).
|
|
112
|
-
*
|
|
113
|
-
* NATIVE never calls this — `getPresetVars` returns raw triples verbatim and
|
|
114
|
-
* `native-root-vars.native.ts` writes them through bloom's `hsl(var(--x))`
|
|
115
|
-
* native `global.css` indirection. Pure function — no side effects — so it is
|
|
116
|
-
* unit-testable in isolation.
|
|
117
|
-
*/
|
|
118
|
-
export function toWebColorValue(key, value) {
|
|
119
|
-
if (key.startsWith(RESOLVED_COLOR_VAR_PREFIX)) return value;
|
|
120
|
-
if (!RAW_HSL_TRIPLE.test(value)) return value;
|
|
121
|
-
return `hsl(${value})`;
|
|
122
|
-
}
|
|
123
|
-
const RESOLVED_COLOR_MAP = {
|
|
124
|
-
'--background': '--color-background',
|
|
125
|
-
'--foreground': '--color-foreground',
|
|
126
|
-
'--primary': '--color-primary',
|
|
127
|
-
'--primary-foreground': '--color-primary-foreground',
|
|
128
|
-
'--secondary': '--color-secondary',
|
|
129
|
-
'--secondary-foreground': '--color-secondary-foreground',
|
|
130
|
-
'--muted': '--color-muted',
|
|
131
|
-
'--muted-foreground': '--color-muted-foreground',
|
|
132
|
-
'--accent': '--color-accent',
|
|
133
|
-
'--accent-foreground': '--color-accent-foreground',
|
|
134
|
-
'--destructive': '--color-destructive',
|
|
135
|
-
'--border': '--color-border',
|
|
136
|
-
'--input': '--color-input',
|
|
137
|
-
'--ring': '--color-ring',
|
|
138
|
-
'--popover': '--color-popover',
|
|
139
|
-
'--popover-foreground': '--color-popover-foreground',
|
|
140
|
-
'--surface': '--color-surface',
|
|
141
|
-
'--surface-foreground': '--color-surface-foreground',
|
|
142
|
-
'--card': '--color-card',
|
|
143
|
-
'--card-foreground': '--color-card-foreground'
|
|
144
|
-
};
|
|
145
17
|
/**
|
|
146
18
|
* Bloom's base preset tokens extended with the surface/card/chart/sidebar
|
|
147
19
|
* tokens that apps layer on top of the core shadcn palette. Synthesized from
|
|
@@ -149,8 +21,13 @@ const RESOLVED_COLOR_MAP = {
|
|
|
149
21
|
*
|
|
150
22
|
* This is the single source of truth for extended theming vars — consumer apps
|
|
151
23
|
* must not redefine these per-app.
|
|
24
|
+
*
|
|
25
|
+
* Values are platform-agnostic **raw HSL triples** (`'185 100% 20%'`, optionally
|
|
26
|
+
* with a `/ A` alpha tail). The single canonical resolver `getResolvedTokens`
|
|
27
|
+
* (in `token-registry.ts`) converts these to sRGB `rgb(...)` for BOTH web and
|
|
28
|
+
* native runtime writes — this function only produces the raw triple map.
|
|
152
29
|
*/
|
|
153
|
-
export function getPresetVars(colorName, mode
|
|
30
|
+
export function getPresetVars(colorName, mode) {
|
|
154
31
|
const preset = APP_COLOR_PRESETS[colorName];
|
|
155
32
|
const base = mode === 'light' ? preset.light : preset.dark;
|
|
156
33
|
const get = key => base[key] ?? '0 0% 0%';
|
|
@@ -180,15 +57,7 @@ export function getPresetVars(colorName, mode, options = {}) {
|
|
|
180
57
|
'--sidebar-border': get('--border'),
|
|
181
58
|
'--sidebar-ring': get('--ring')
|
|
182
59
|
};
|
|
183
|
-
|
|
184
|
-
const resolved = {
|
|
185
|
-
...extended
|
|
186
|
-
};
|
|
187
|
-
for (const [rawKey, colorKey] of Object.entries(RESOLVED_COLOR_MAP)) {
|
|
188
|
-
const value = extended[rawKey];
|
|
189
|
-
if (value) resolved[colorKey] = hslTripletToRgb(value);
|
|
190
|
-
}
|
|
191
|
-
return resolved;
|
|
60
|
+
return extended;
|
|
192
61
|
}
|
|
193
62
|
|
|
194
63
|
/**
|
|
@@ -197,17 +66,17 @@ export function getPresetVars(colorName, mode, options = {}) {
|
|
|
197
66
|
* call this only when an app needs the extended (card/chart/sidebar) tokens on
|
|
198
67
|
* the document root.
|
|
199
68
|
*
|
|
200
|
-
*
|
|
201
|
-
* `
|
|
202
|
-
*
|
|
203
|
-
*
|
|
69
|
+
* Tokens are resolved to sRGB `rgb(...)` via the single canonical
|
|
70
|
+
* `getResolvedTokens` pipeline, so `var(--x)` — the form Tailwind v4
|
|
71
|
+
* `@theme inline` compiles its color utilities to — resolves directly to a
|
|
72
|
+
* valid color on web.
|
|
204
73
|
*/
|
|
205
|
-
export function applyPresetVarsToDocument(colorName, mode
|
|
74
|
+
export function applyPresetVarsToDocument(colorName, mode) {
|
|
206
75
|
if (Platform.OS !== 'web' || typeof document === 'undefined') return;
|
|
207
|
-
const vars =
|
|
76
|
+
const vars = getResolvedTokens(colorName, mode);
|
|
208
77
|
const root = document.documentElement.style;
|
|
209
78
|
for (const [key, value] of Object.entries(vars)) {
|
|
210
|
-
root.setProperty(key,
|
|
79
|
+
root.setProperty(key, value);
|
|
211
80
|
}
|
|
212
81
|
}
|
|
213
82
|
//# sourceMappingURL=preset-vars.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["Platform","APP_COLOR_PRESETS","extractHue","hslVar","parseInt","split","extractSat","
|
|
1
|
+
{"version":3,"names":["Platform","APP_COLOR_PRESETS","getResolvedTokens","extractHue","hslVar","parseInt","split","extractSat","getPresetVars","colorName","mode","preset","base","light","dark","get","key","primary","foreground","hue","sat","Math","min","isDark","extended","applyPresetVarsToDocument","OS","document","vars","root","documentElement","style","value","Object","entries","setProperty"],"sourceRoot":"../../../src","sources":["theme/preset-vars.ts"],"mappings":";;AAAA,SAASA,QAAQ,QAAQ,cAAc;AACvC,SAASC,iBAAiB,QAA8C,oBAAiB;AACzF;AACA;AACA;AACA;AACA,SAASC,iBAAiB,QAAQ,qBAAkB;AAEpD,SAASC,UAAUA,CAACC,MAAc,EAAU;EAC1C,OAAOC,QAAQ,CAACD,MAAM,CAACE,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,GAAG,EAAE,EAAE,CAAC;AAClD;AAEA,SAASC,UAAUA,CAACH,MAAc,EAAU;EAC1C,OAAOC,QAAQ,CAACD,MAAM,CAACE,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,GAAG,EAAE,EAAE,CAAC;AAClD;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO,SAASE,aAAaA,CAC3BC,SAAuB,EACvBC,IAAsB,EACR;EACd,MAAMC,MAAM,GAAGV,iBAAiB,CAACQ,SAAS,CAAC;EAC3C,MAAMG,IAAI,GAAGF,IAAI,KAAK,OAAO,GAAGC,MAAM,CAACE,KAAK,GAAGF,MAAM,CAACG,IAAI;EAC1D,MAAMC,GAAG,GAAIC,GAAW,IAAaJ,IAAI,CAACI,GAAG,CAAC,IAAI,SAAS;EAC3D,MAAMC,OAAO,GAAGF,GAAG,CAAC,WAAW,CAAC;EAChC,MAAMG,UAAU,GAAGH,GAAG,CAAC,cAAc,CAAC;EACtC,MAAMI,GAAG,GAAGhB,UAAU,CAACc,OAAO,CAAC;EAC/B,MAAMG,GAAG,GAAGC,IAAI,CAACC,GAAG,CAACf,UAAU,CAACU,OAAO,CAAC,EAAE,EAAE,CAAC;EAC7C,MAAMM,MAAM,GAAGb,IAAI,KAAK,MAAM;EAE9B,MAAMc,QAAsB,GAAG;IAC7B,GAAGZ,IAAI;IACP;IACA;IACA;IACA,QAAQ,EAAEW,MAAM,GAAG,GAAGJ,GAAG,UAAU,GAAG,GAAGA,GAAG,UAAU;IACtD,mBAAmB,EAAED,UAAU;IAC/B,WAAW,EAAE,GAAGC,GAAG,IAAIC,GAAG,OAAO;IACjC,WAAW,EAAE,GAAGD,GAAG,IAAIC,GAAG,OAAO;IACjC,WAAW,EAAE,GAAGD,GAAG,IAAIC,GAAG,OAAO;IACjC,WAAW,EAAE,GAAGD,GAAG,IAAIC,GAAG,KAAKG,MAAM,GAAG,EAAE,GAAG,EAAE,GAAG;IAClD,WAAW,EAAE,GAAGJ,GAAG,IAAIC,GAAG,KAAKG,MAAM,GAAG,EAAE,GAAG,EAAE,GAAG;IAClD,gBAAgB,EAAEA,MAAM,GAAG,GAAGJ,GAAG,SAAS,GAAGJ,GAAG,CAAC,WAAW,CAAC;IAC7D,sBAAsB,EAAEG,UAAU;IAClC,mBAAmB,EAAED,OAAO;IAC5B,8BAA8B,EAAEF,GAAG,CAAC,sBAAsB,CAAC;IAC3D,kBAAkB,EAAEQ,MAAM,GAAGR,GAAG,CAAC,WAAW,CAAC,GAAGA,GAAG,CAAC,UAAU,CAAC;IAC/D,6BAA6B,EAAEQ,MAAM,GAAGL,UAAU,GAAGH,GAAG,CAAC,qBAAqB,CAAC;IAC/E,kBAAkB,EAAEA,GAAG,CAAC,UAAU,CAAC;IACnC,gBAAgB,EAAEA,GAAG,CAAC,QAAQ;EAChC,CAAC;EAED,OAAOS,QAAQ;AACjB;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO,SAASC,yBAAyBA,CACvChB,SAAuB,EACvBC,IAAsB,EAChB;EACN,IAAIV,QAAQ,CAAC0B,EAAE,KAAK,KAAK,IAAI,OAAOC,QAAQ,KAAK,WAAW,EAAE;EAE9D,MAAMC,IAAI,GAAG1B,iBAAiB,CAACO,SAAS,EAAEC,IAAI,CAAC;EAC/C,MAAMmB,IAAI,GAAGF,QAAQ,CAACG,eAAe,CAACC,KAAK;EAC3C,KAAK,MAAM,CAACf,GAAG,EAAEgB,KAAK,CAAC,IAAIC,MAAM,CAACC,OAAO,CAACN,IAAI,CAAC,EAAE;IAC/CC,IAAI,CAACM,WAAW,CAACnB,GAAG,EAAEgB,KAAK,CAAC;EAC9B;AACF","ignoreList":[]}
|