synthesisui 0.16.307 → 0.16.308
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/commands/import.js +59 -2
- package/dist/doctor/components-scan.js +40 -19
- package/dist/doctor/export-census.js +111 -0
- package/dist/doctor/form-identity.js +75 -0
- package/dist/doctor/framework-palette.js +569 -0
- package/dist/doctor/style-ledger.js +27 -1
- package/dist/doctor/transcribe.js +24 -29
- package/dist/doctor/variant-read.js +13 -1
- package/dist/install-marks.js +22 -2
- package/dist/workspace-css.js +84 -0
- package/package.json +1 -1
package/dist/commands/import.js
CHANGED
|
@@ -19,7 +19,9 @@ import { keyframeOffsets, moduleImports, partialCandidates, readGlobalClasses, r
|
|
|
19
19
|
import { dataContract } from "../doctor/data-contract.js";
|
|
20
20
|
import { inherit, readDeclaredForms, } from "../doctor/declared-forms.js";
|
|
21
21
|
import { reconcile, scanDefinitions, } from "../doctor/definitions-scan.js";
|
|
22
|
+
import { accountExportsInto, emptyExportAccount, exportInvariantHolds, } from "../doctor/export-census.js";
|
|
22
23
|
import { fragmentsOfSource, fragmentsOfStylesheet, judgeFragments, } from "../doctor/fragments.js";
|
|
24
|
+
import { useFrameworkMajor } from "../doctor/framework-palette.js";
|
|
23
25
|
import { describeConvention, describeRemainder, detectConventions, } from "../doctor/idiom.js";
|
|
24
26
|
import { pageLaws } from "../doctor/page-laws.js";
|
|
25
27
|
import { callSiteNode, placeLayers, } from "../doctor/place-layers.js";
|
|
@@ -51,6 +53,7 @@ import { repoStateOf } from "../repo-state.js";
|
|
|
51
53
|
import { runtimeDeclaredVars, runtimeDeclaredVarsIn } from "../runtime-vars.js";
|
|
52
54
|
import { detectStack, resolveDeps, stackVersions } from "../stack.js";
|
|
53
55
|
import { wiredSlugs, wiringWarning } from "../wired-slugs.js";
|
|
56
|
+
import { harvestWorkspaceCss } from "../workspace-css.js";
|
|
54
57
|
import { placeInWorkspace } from "../workspace-place.js";
|
|
55
58
|
import { add } from "./add.js";
|
|
56
59
|
import { walk, walkAll } from "./doctor.js";
|
|
@@ -457,6 +460,16 @@ export async function takeCensus(root, opts) {
|
|
|
457
460
|
const fragments = [];
|
|
458
461
|
/** Arquivos de estilo que pertencem a componente admitido - o veredito do `css` sai daqui. */
|
|
459
462
|
const admittedStyles = new Set();
|
|
463
|
+
/** O denominador de exports antes do portão - ver `export-census.ts` (item 13). */
|
|
464
|
+
const exportAccount = emptyExportAccount();
|
|
465
|
+
/**
|
|
466
|
+
* A VERSÃO DO FRAMEWORK, ANTES DA VARREDURA - a paleta publicada muda de língua na maior
|
|
467
|
+
* (v4 é oklch, v3 é hex), e o resolvedor é chamado fundo demais para receber mais um
|
|
468
|
+
* parâmetro. Hoisted de depois da varredura, onde só os signals a usavam.
|
|
469
|
+
*/
|
|
470
|
+
const versions = await resolveDeps(root).catch(() => ({}));
|
|
471
|
+
useFrameworkMajor(Number.parseInt(/\d+/.exec(versions.tailwindcss ?? "")?.[0] ?? "", 10) ||
|
|
472
|
+
null);
|
|
460
473
|
/** What the gate turned away, with the reason. Never dropped in silence. */
|
|
461
474
|
const skips = [];
|
|
462
475
|
// Kept for the reference check below, which needs every file at once: a name
|
|
@@ -469,6 +482,16 @@ export async function takeCensus(root, opts) {
|
|
|
469
482
|
if (!declaredValues.has(m[1]))
|
|
470
483
|
declaredValues.set(m[1], m[2].trim());
|
|
471
484
|
}
|
|
485
|
+
/**
|
|
486
|
+
* O VOCABULÁRIO DO PACOTE AO LADO (item 19) - ver `workspace-css.ts`. Genérico por decisão do
|
|
487
|
+
* dono (25/08): qualquer pacote de WORKSPACE que o escopo importa, nunca `node_modules` e nunca
|
|
488
|
+
* um nome cravado. O escopo dele sempre vence (a trava é o `scopeDeclares`); no repositório
|
|
489
|
+
* real, 223 valores (37% do não-lido) vestiam variáveis declaradas um pacote ao lado.
|
|
490
|
+
*/
|
|
491
|
+
const workspace = await harvestWorkspaceCss(root, (name) => declaredValues.has(name)).catch(() => ({ packages: [], declared: new Map() }));
|
|
492
|
+
for (const [name, value] of workspace.declared) {
|
|
493
|
+
declaredValues.set(name, value);
|
|
494
|
+
}
|
|
472
495
|
/**
|
|
473
496
|
* AS REGRAS DE CLASSE DAS FOLHAS GLOBAIS - ver `readGlobalClasses`. Uma regra que um
|
|
474
497
|
* componente admitido veste é a receita dele; `claimed` guarda quais foram vestidas,
|
|
@@ -635,7 +658,14 @@ export async function takeCensus(root, opts) {
|
|
|
635
658
|
screensOf.set(m[1], at);
|
|
636
659
|
}
|
|
637
660
|
const found = [];
|
|
638
|
-
|
|
661
|
+
const defs = scanDefinitions(rel, src);
|
|
662
|
+
/**
|
|
663
|
+
* O DENOMINADOR ANTES DO PORTÃO - ver `export-census.ts` (item 13). Todo nome que o scan
|
|
664
|
+
* produziu TEM destino (admitido ou recusado); o contador mede o que sobra fora do funil.
|
|
665
|
+
*/
|
|
666
|
+
const openedNames = new Set(defs.map((d) => d.name));
|
|
667
|
+
accountExportsInto(exportAccount, rel, src, (n) => openedNames.has(n));
|
|
668
|
+
for (const d of defs) {
|
|
639
669
|
const verdict = gateComponent({
|
|
640
670
|
name: d.name,
|
|
641
671
|
file: rel,
|
|
@@ -1953,7 +1983,6 @@ export async function takeCensus(root, opts) {
|
|
|
1953
1983
|
* versão (medido 16/08). `resolveDeps` sobe até a raiz do workspace e anda para os irmãos que os
|
|
1954
1984
|
* `workspaces` declaram, que é onde recharts/chakra/mui realmente moram.
|
|
1955
1985
|
*/
|
|
1956
|
-
const versions = await resolveDeps(root).catch(() => ({}));
|
|
1957
1986
|
finishSignals(signals, importTally, versions);
|
|
1958
1987
|
// Every name their CSS defines, from the same harvest the token table came
|
|
1959
1988
|
// from - so a reference is judged against what actually exists, not against
|
|
@@ -1962,6 +1991,9 @@ export async function takeCensus(root, opts) {
|
|
|
1962
1991
|
for (const m of css.matchAll(/(--[a-zA-Z0-9_-]+)\s*:/g)) {
|
|
1963
1992
|
declaredNames.add(m[1]);
|
|
1964
1993
|
}
|
|
1994
|
+
/** O pacote ao lado também declara (item 19) - sem isto a ref dele viraria "quebrada". */
|
|
1995
|
+
for (const name of workspace.declared.keys())
|
|
1996
|
+
declaredNames.add(name);
|
|
1965
1997
|
/**
|
|
1966
1998
|
* E O QUE ELE DECLARA FORA DO CSS - ver `runtimeDeclaredVars`.
|
|
1967
1999
|
*
|
|
@@ -2294,6 +2326,31 @@ export async function takeCensus(root, opts) {
|
|
|
2294
2326
|
},
|
|
2295
2327
|
}
|
|
2296
2328
|
: {}),
|
|
2329
|
+
/**
|
|
2330
|
+
* O DENOMINADOR ANTES DO PORTÃO - ver `export-census.ts` (item 13). Com ele, "o portão pega
|
|
2331
|
+
* 100%" vira aritmética conferível: candidatos têm destino no gate, formas deliberadas têm
|
|
2332
|
+
* contagem, e o resíduo tem LINHA. Mesmo padrão do `values`: a soma que não fecha não é
|
|
2333
|
+
* emitida - censo sem o campo é mais honesto que campo errado.
|
|
2334
|
+
*/
|
|
2335
|
+
...(exportAccount.seen > 0 && exportInvariantHolds(exportAccount)
|
|
2336
|
+
? {
|
|
2337
|
+
exports: {
|
|
2338
|
+
seen: exportAccount.seen,
|
|
2339
|
+
byForm: exportAccount.byForm,
|
|
2340
|
+
...(exportAccount.unopened.length > 0
|
|
2341
|
+
? { unopened: exportAccount.unopened.slice(0, 512) }
|
|
2342
|
+
: {}),
|
|
2343
|
+
},
|
|
2344
|
+
}
|
|
2345
|
+
: {}),
|
|
2346
|
+
/**
|
|
2347
|
+
* DE ONDE VEIO O VOCABULÁRIO EMPRESTADO (item 19) - o pacote workspace e quantas variáveis
|
|
2348
|
+
* ele doou. Viaja para a tela poder dizer "estes nomes moram em `@acme/ui`" em vez de o
|
|
2349
|
+
* cliente procurar no escopo uma declaração que não está lá.
|
|
2350
|
+
*/
|
|
2351
|
+
...(workspace.packages.length > 0
|
|
2352
|
+
? { workspaceCss: { packages: workspace.packages } }
|
|
2353
|
+
: {}),
|
|
2297
2354
|
...(architectures.length > 0
|
|
2298
2355
|
? {
|
|
2299
2356
|
architectures: architectures.slice(0, 6).map((a) => ({
|
|
@@ -434,6 +434,43 @@ export function tallyToInventory(tally, max = 80) {
|
|
|
434
434
|
.sort((a, b) => b.files - a.files || b.count - a.count)
|
|
435
435
|
.slice(0, max);
|
|
436
436
|
}
|
|
437
|
+
/**
|
|
438
|
+
* OS PACOTES DO WORKSPACE, com nome E pasta - a metade que `internalSpecifiers` jogava fora.
|
|
439
|
+
*
|
|
440
|
+
* A mesma caminhada (até 4 níveis acima, grupos `packages`/`libs`/`apps`), extraída para UMA
|
|
441
|
+
* fonte: o item 19 precisa da PASTA de cada pacote para colher o CSS dele, e uma segunda cópia
|
|
442
|
+
* da regra de descoberta é como duas descobertas começam a discordar.
|
|
443
|
+
*/
|
|
444
|
+
export async function workspacePackages(root) {
|
|
445
|
+
const out = new Map();
|
|
446
|
+
for (let up = 0, dir = root; up < 4; up++) {
|
|
447
|
+
for (const group of ["packages", "libs", "apps"]) {
|
|
448
|
+
for (const e of await readdir(join(dir, group), {
|
|
449
|
+
withFileTypes: true,
|
|
450
|
+
}).catch(() => [])) {
|
|
451
|
+
if (!e.isDirectory())
|
|
452
|
+
continue;
|
|
453
|
+
const raw = await readFile(join(dir, group, e.name, "package.json"), "utf8").catch(() => null);
|
|
454
|
+
if (!raw)
|
|
455
|
+
continue;
|
|
456
|
+
try {
|
|
457
|
+
const name = JSON.parse(raw).name;
|
|
458
|
+
if (typeof name === "string" && name && !out.has(name)) {
|
|
459
|
+
out.set(name, join(dir, group, e.name));
|
|
460
|
+
}
|
|
461
|
+
}
|
|
462
|
+
catch {
|
|
463
|
+
// manifesto ilegível custa aquele pacote, nunca a descoberta
|
|
464
|
+
}
|
|
465
|
+
}
|
|
466
|
+
}
|
|
467
|
+
const parent = join(dir, "..");
|
|
468
|
+
if (parent === dir)
|
|
469
|
+
break;
|
|
470
|
+
dir = parent;
|
|
471
|
+
}
|
|
472
|
+
return [...out.entries()].map(([name, dir]) => ({ name, dir }));
|
|
473
|
+
}
|
|
437
474
|
/**
|
|
438
475
|
* Specifier prefixes this workspace owns: the aliases its tsconfig declares and
|
|
439
476
|
* the names of its sibling packages. Everything else that is not relative comes
|
|
@@ -459,29 +496,13 @@ export async function internalSpecifiers(root) {
|
|
|
459
496
|
// unreadable config costs the aliases, not the run
|
|
460
497
|
}
|
|
461
498
|
}
|
|
462
|
-
for (const group of ["packages", "libs", "apps"]) {
|
|
463
|
-
for (const e of await readdir(join(dir, group), {
|
|
464
|
-
withFileTypes: true,
|
|
465
|
-
}).catch(() => [])) {
|
|
466
|
-
if (!e.isDirectory())
|
|
467
|
-
continue;
|
|
468
|
-
const raw = await readFile(join(dir, group, e.name, "package.json"), "utf8").catch(() => null);
|
|
469
|
-
if (!raw)
|
|
470
|
-
continue;
|
|
471
|
-
try {
|
|
472
|
-
const name = JSON.parse(raw).name;
|
|
473
|
-
if (typeof name === "string" && name)
|
|
474
|
-
out.add(name);
|
|
475
|
-
}
|
|
476
|
-
catch {
|
|
477
|
-
// same
|
|
478
|
-
}
|
|
479
|
-
}
|
|
480
|
-
}
|
|
481
499
|
const parent = join(dir, "..");
|
|
482
500
|
if (parent === dir)
|
|
483
501
|
break;
|
|
484
502
|
dir = parent;
|
|
485
503
|
}
|
|
504
|
+
/** Os nomes dos irmãos vêm da MESMA descoberta que o item 19 usa - uma fonte, nunca duas. */
|
|
505
|
+
for (const pkg of await workspacePackages(root))
|
|
506
|
+
out.add(pkg.name);
|
|
486
507
|
return [...out];
|
|
487
508
|
}
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
/** `export function X` / `export const x =` / `export default class X` - o nome inline. */
|
|
2
|
+
const NAMED = /export\s+(?:default\s+)?(?:abstract\s+)?(?:async\s+)?(?:function\s*\*?|class|const|let|var|enum)\s+([A-Za-z_$][\w$]*)/g;
|
|
3
|
+
/** `export type X` / `export interface X` - vocabulário, não peça. */
|
|
4
|
+
const TYPE_EXPORT = /export\s+(?:type|interface)\s+[A-Za-z_$]/g;
|
|
5
|
+
/** `export { A, B } from "x"` e `export * from "x"` - repasse. */
|
|
6
|
+
const RE_EXPORT = /export\s*(?:\*|\{[^}]*\})\s*from\s*["']/g;
|
|
7
|
+
/** `export { A, B }` SEM from - nomes declarados neste arquivo, exportados em lista. */
|
|
8
|
+
const LIST_EXPORT = /export\s*\{([^}]*)\}(?!\s*from)/g;
|
|
9
|
+
/** `export default (…)=>` / `export default function (` / objeto/literal - sem nome legível. */
|
|
10
|
+
const ANONYMOUS_DEFAULT = /export\s+default\s+(?:(?:React\.)?(?:memo|forwardRef)\s*\(\s*)*(?:async\s+)?(?:\(|function\s*\(|\{|\[|`|['"\d])/g;
|
|
11
|
+
/** `export default Name;` - com nome; o funil decide se é definição ou repasse. */
|
|
12
|
+
const NAMED_DEFAULT = /export\s+default\s+(?:(?:React\.)?(?:memo|forwardRef)\s*\(\s*)*([A-Za-z_$][\w$]*)\s*[;)\n]/g;
|
|
13
|
+
/** O nome é construído NESTE arquivo? - a mesma pergunta do scanner de definições. */
|
|
14
|
+
function declaresName(source, name) {
|
|
15
|
+
const escaped = name.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
16
|
+
return new RegExp(`(?:^|\\n)\\s*(?:export\\s+)?(?:default\\s+)?(?:async\\s+)?(?:function|class|const|let|var)\\s+${escaped}\\b`).test(source);
|
|
17
|
+
}
|
|
18
|
+
const count = (account, form) => {
|
|
19
|
+
account.seen += 1;
|
|
20
|
+
account.byForm[form] = (account.byForm[form] ?? 0) + 1;
|
|
21
|
+
};
|
|
22
|
+
/**
|
|
23
|
+
* Conta os exports de UM arquivo de componente, contra o que o funil abriu dele.
|
|
24
|
+
*
|
|
25
|
+
* `opened` responde se um nome virou candidato (admitido OU recusado - os dois são destino).
|
|
26
|
+
* Muta `account` em vez de devolver, porque a soma do censo é a soma dos arquivos e um merge de
|
|
27
|
+
* records a cada arquivo é custo quadrático num monorepo de 966.
|
|
28
|
+
*/
|
|
29
|
+
export function accountExportsInto(account, file, source, opened) {
|
|
30
|
+
if (!/\.(tsx|jsx|vue|svelte)$/i.test(file))
|
|
31
|
+
return;
|
|
32
|
+
const push = (line) => {
|
|
33
|
+
/** Teto por censo, aplicado por quem monta - aqui só não duplica dentro do arquivo. */
|
|
34
|
+
if (!account.unopened.some((u) => u.file === line.file && u.name === line.name)) {
|
|
35
|
+
account.unopened.push(line);
|
|
36
|
+
}
|
|
37
|
+
};
|
|
38
|
+
NAMED.lastIndex = 0;
|
|
39
|
+
for (const m of source.matchAll(NAMED)) {
|
|
40
|
+
const name = m[1];
|
|
41
|
+
if (!/^[A-Z]/.test(name)) {
|
|
42
|
+
count(account, "helper");
|
|
43
|
+
continue;
|
|
44
|
+
}
|
|
45
|
+
if (opened(name)) {
|
|
46
|
+
count(account, "candidate");
|
|
47
|
+
continue;
|
|
48
|
+
}
|
|
49
|
+
count(account, "unopened");
|
|
50
|
+
push({ file, name, form: "unopened" });
|
|
51
|
+
}
|
|
52
|
+
TYPE_EXPORT.lastIndex = 0;
|
|
53
|
+
for (const _ of source.matchAll(TYPE_EXPORT))
|
|
54
|
+
count(account, "type");
|
|
55
|
+
RE_EXPORT.lastIndex = 0;
|
|
56
|
+
for (const _ of source.matchAll(RE_EXPORT))
|
|
57
|
+
count(account, "re-export");
|
|
58
|
+
LIST_EXPORT.lastIndex = 0;
|
|
59
|
+
for (const m of source.matchAll(LIST_EXPORT)) {
|
|
60
|
+
for (const raw of m[1].split(",")) {
|
|
61
|
+
/** `Card as default` conta pelo nome local; o scanner de definições já lê essa grafia. */
|
|
62
|
+
const name = raw
|
|
63
|
+
.trim()
|
|
64
|
+
.split(/\s+as\s+/)[0]
|
|
65
|
+
?.trim();
|
|
66
|
+
if (!name || !/^[A-Za-z_$]/.test(name))
|
|
67
|
+
continue;
|
|
68
|
+
if (!/^[A-Z]/.test(name)) {
|
|
69
|
+
count(account, "helper");
|
|
70
|
+
continue;
|
|
71
|
+
}
|
|
72
|
+
if (!declaresName(source, name)) {
|
|
73
|
+
count(account, "re-export");
|
|
74
|
+
continue;
|
|
75
|
+
}
|
|
76
|
+
if (opened(name)) {
|
|
77
|
+
count(account, "candidate");
|
|
78
|
+
continue;
|
|
79
|
+
}
|
|
80
|
+
count(account, "export-list");
|
|
81
|
+
push({ file, name, form: "export-list" });
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
ANONYMOUS_DEFAULT.lastIndex = 0;
|
|
85
|
+
for (const _ of source.matchAll(ANONYMOUS_DEFAULT)) {
|
|
86
|
+
count(account, "anonymous-default");
|
|
87
|
+
push({ file, form: "anonymous-default" });
|
|
88
|
+
}
|
|
89
|
+
NAMED_DEFAULT.lastIndex = 0;
|
|
90
|
+
for (const m of source.matchAll(NAMED_DEFAULT)) {
|
|
91
|
+
const name = m[1];
|
|
92
|
+
if (!declaresName(source, name)) {
|
|
93
|
+
count(account, "re-export");
|
|
94
|
+
continue;
|
|
95
|
+
}
|
|
96
|
+
/** Declarado aqui: ou o funil o abriu (candidato), ou é resíduo com linha. */
|
|
97
|
+
if (opened(name)) {
|
|
98
|
+
count(account, "candidate");
|
|
99
|
+
continue;
|
|
100
|
+
}
|
|
101
|
+
count(account, "unopened");
|
|
102
|
+
push({ file, name, form: "unopened" });
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
export function emptyExportAccount() {
|
|
106
|
+
return { seen: 0, byForm: {}, unopened: [] };
|
|
107
|
+
}
|
|
108
|
+
/** A invariante do denominador: toda contagem por forma soma o total visto. */
|
|
109
|
+
export function exportInvariantHolds(account) {
|
|
110
|
+
return (Object.values(account.byForm).reduce((a, b) => a + b, 0) === account.seen);
|
|
111
|
+
}
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A IDENTIDADE DA FORMA (item 12, 25/08) - a unidade de uma pergunta de self-healing.
|
|
3
|
+
*
|
|
4
|
+
* `FragmentShape` tem 7 valores e é grosso demais: o balde `css` lê 42% no frontend-hub e 0% no
|
|
5
|
+
* codelevel - o MESMO nome com leitores opostos. E texto distinto é fino demais: 10 825 usos do
|
|
6
|
+
* frontend-hub viram 140 textos, mas cada texto ainda é uma pergunta. A granularidade que decide
|
|
7
|
+
* é a FORMA - o texto com os valores abstraídos:
|
|
8
|
+
*
|
|
9
|
+
* body { -webkit-font-smoothing: antialiased } -> -webkit-font-smoothing: <keyword>
|
|
10
|
+
* background: linear-gradient(90deg, #a, #b) -> background: <gradient>
|
|
11
|
+
* hover:-translate-y-px · -translate-y-px -> -translate-y-px (uma forma)
|
|
12
|
+
* text-rose-700 · text-amber-300 -> text-<word>-<n> (uma forma)
|
|
13
|
+
*
|
|
14
|
+
* Medido no diagnóstico: 18 473 declarações das 706 folhas do app inteiro comprimem para 194
|
|
15
|
+
* formas - DEZENAS, não milhares. Uma resposta dele (D2) responde a FORMA, não o texto: quem
|
|
16
|
+
* ensina a ler `text-<word>-<n>` ensinou as centenas de uma vez.
|
|
17
|
+
*/
|
|
18
|
+
/** O tipo de UM valor de CSS, abstraído - a escada é determinística e a ordem importa. */
|
|
19
|
+
function kindOfValue(raw) {
|
|
20
|
+
const value = raw.trim();
|
|
21
|
+
if (/gradient\s*\(/i.test(value))
|
|
22
|
+
return "<gradient>";
|
|
23
|
+
if (/^var\(\s*--[\w-]+\s*\)$/i.test(value))
|
|
24
|
+
return "<var>";
|
|
25
|
+
if (/^#[0-9a-f]{3,8}$/i.test(value))
|
|
26
|
+
return "<color>";
|
|
27
|
+
if (/^(?:rgba?|hsla?|oklch|oklab|lab|lch|color|color-mix)\s*\(/i.test(value))
|
|
28
|
+
return "<color>";
|
|
29
|
+
if (/url\s*\(/i.test(value))
|
|
30
|
+
return "<url>";
|
|
31
|
+
if (/^calc\s*\(/i.test(value))
|
|
32
|
+
return "<calc>";
|
|
33
|
+
if (/^-?[\d.]+(?:px|rem|em|%|s|ms|vh|vw|vmin|vmax|fr|ch|ex|pt)$/i.test(value))
|
|
34
|
+
return "<length>";
|
|
35
|
+
if (/^-?[\d.]+$/.test(value))
|
|
36
|
+
return "<number>";
|
|
37
|
+
if (/^[a-z][a-z-]*$/i.test(value))
|
|
38
|
+
return "<keyword>";
|
|
39
|
+
/** Sombra, transição, pilha de fonte - vários valores numa declaração só. */
|
|
40
|
+
return "<composite>";
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* UM token utilitário, com os valores abstraídos: dígitos viram `<n>`, frações `<n>/<n>`,
|
|
44
|
+
* hex `<hex>`, valor arbitrário `[…]` - e os MODIFICADORES saem, porque `hover:-translate-y-px`
|
|
45
|
+
* e `-translate-y-px` são a mesma lacuna de leitura.
|
|
46
|
+
*/
|
|
47
|
+
function classForm(token) {
|
|
48
|
+
const utility = token.split(":").pop() ?? token;
|
|
49
|
+
return utility
|
|
50
|
+
.replace(/\[[^\]]*\]/g, "[…]")
|
|
51
|
+
.replace(/#[0-9a-f]{3,8}/gi, "<hex>")
|
|
52
|
+
.replace(/(\d+)\/(\d+)/g, "<n>/<n>")
|
|
53
|
+
.replace(/\/(\d+)/g, "/<n>")
|
|
54
|
+
.replace(/\d+(?:\.\d+)?/g, "<n>")
|
|
55
|
+
.replace(/(?<=-)[a-z]+(?=-<n>(?:\/<n>)?$)/, "<word>");
|
|
56
|
+
}
|
|
57
|
+
/** `sel { prop: value; … }` ou `prop: value` - a primeira declaração nomeia a forma. */
|
|
58
|
+
const DECLARATION = /(-{0,2}[a-zA-Z][\w-]*)\s*:\s*([^;{}]+)/;
|
|
59
|
+
/**
|
|
60
|
+
* A forma de UM fragmento não lido. Determinística, derivada só do texto - a mesma regra do
|
|
61
|
+
* backfill do D3: nada aqui é chute, e um texto que não abre vira a forma `<opaque>`, dita.
|
|
62
|
+
*/
|
|
63
|
+
export function formOf(shape, text) {
|
|
64
|
+
const clean = text.replace(/\s+/g, " ").trim();
|
|
65
|
+
if (shape === "class" || shape === "template") {
|
|
66
|
+
const forms = [
|
|
67
|
+
...new Set(clean.split(/\s+/).filter(Boolean).map(classForm)),
|
|
68
|
+
];
|
|
69
|
+
return forms.slice(0, 4).join(" ") || "<opaque>";
|
|
70
|
+
}
|
|
71
|
+
const declaration = DECLARATION.exec(clean);
|
|
72
|
+
if (!declaration)
|
|
73
|
+
return "<opaque>";
|
|
74
|
+
return `${declaration[1]}: ${kindOfValue(declaration[2])}`;
|
|
75
|
+
}
|
|
@@ -0,0 +1,569 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A TABELA DA PALETA DO FRAMEWORK (item 18, 25/08) - por VERSÃO MAIOR, porque as duas publicam
|
|
3
|
+
* valores diferentes: a v4 fala oklch e a v3 fala hex. Um único mapa daria a cor errada para
|
|
4
|
+
* metade dos clientes.
|
|
5
|
+
*
|
|
6
|
+
* OS VALORES SÃO EXTRAÍDOS, NUNCA DIGITADOS: a v4 saiu do `theme.css` do tailwindcss@4.2.1 e a
|
|
7
|
+
* v3 do `colors.js` do tailwindcss@3.4.17, os pacotes publicados - um dígito errado aqui é uma
|
|
8
|
+
* cor errada calada na tela de alguém. Se precisar regenerar, extraia de novo do pacote.
|
|
9
|
+
*
|
|
10
|
+
* POR QUE LER A PALETA NÃO É INVENTAR (a mesma tese da tabela zinc/blue que existia antes):
|
|
11
|
+
* `text-rose-700` no código dele é uma decisão dele sobre um valor PUBLICADO - ler a tabela é
|
|
12
|
+
* aritmética. O que o D1 exige é o carimbo: todo valor resolvido aqui sai com
|
|
13
|
+
* `from: "framework"`, então a métrica sabe que não é vocabulário DELE, o self-healing pode
|
|
14
|
+
* perguntar se ele quer nomear, e NADA disto vira token sozinho.
|
|
15
|
+
*
|
|
16
|
+
* Medido no diagnóstico: 127 valores (21%%) morriam sem esta tabela - 33%% do codelevel, 6%% do
|
|
17
|
+
* frontend-hub.
|
|
18
|
+
*/
|
|
19
|
+
const V4 = {
|
|
20
|
+
"red-50": "oklch(97.1% 0.013 17.38)",
|
|
21
|
+
"red-100": "oklch(93.6% 0.032 17.717)",
|
|
22
|
+
"red-200": "oklch(88.5% 0.062 18.334)",
|
|
23
|
+
"red-300": "oklch(80.8% 0.114 19.571)",
|
|
24
|
+
"red-400": "oklch(70.4% 0.191 22.216)",
|
|
25
|
+
"red-500": "oklch(63.7% 0.237 25.331)",
|
|
26
|
+
"red-600": "oklch(57.7% 0.245 27.325)",
|
|
27
|
+
"red-700": "oklch(50.5% 0.213 27.518)",
|
|
28
|
+
"red-800": "oklch(44.4% 0.177 26.899)",
|
|
29
|
+
"red-900": "oklch(39.6% 0.141 25.723)",
|
|
30
|
+
"red-950": "oklch(25.8% 0.092 26.042)",
|
|
31
|
+
"orange-50": "oklch(98% 0.016 73.684)",
|
|
32
|
+
"orange-100": "oklch(95.4% 0.038 75.164)",
|
|
33
|
+
"orange-200": "oklch(90.1% 0.076 70.697)",
|
|
34
|
+
"orange-300": "oklch(83.7% 0.128 66.29)",
|
|
35
|
+
"orange-400": "oklch(75% 0.183 55.934)",
|
|
36
|
+
"orange-500": "oklch(70.5% 0.213 47.604)",
|
|
37
|
+
"orange-600": "oklch(64.6% 0.222 41.116)",
|
|
38
|
+
"orange-700": "oklch(55.3% 0.195 38.402)",
|
|
39
|
+
"orange-800": "oklch(47% 0.157 37.304)",
|
|
40
|
+
"orange-900": "oklch(40.8% 0.123 38.172)",
|
|
41
|
+
"orange-950": "oklch(26.6% 0.079 36.259)",
|
|
42
|
+
"amber-50": "oklch(98.7% 0.022 95.277)",
|
|
43
|
+
"amber-100": "oklch(96.2% 0.059 95.617)",
|
|
44
|
+
"amber-200": "oklch(92.4% 0.12 95.746)",
|
|
45
|
+
"amber-300": "oklch(87.9% 0.169 91.605)",
|
|
46
|
+
"amber-400": "oklch(82.8% 0.189 84.429)",
|
|
47
|
+
"amber-500": "oklch(76.9% 0.188 70.08)",
|
|
48
|
+
"amber-600": "oklch(66.6% 0.179 58.318)",
|
|
49
|
+
"amber-700": "oklch(55.5% 0.163 48.998)",
|
|
50
|
+
"amber-800": "oklch(47.3% 0.137 46.201)",
|
|
51
|
+
"amber-900": "oklch(41.4% 0.112 45.904)",
|
|
52
|
+
"amber-950": "oklch(27.9% 0.077 45.635)",
|
|
53
|
+
"yellow-50": "oklch(98.7% 0.026 102.212)",
|
|
54
|
+
"yellow-100": "oklch(97.3% 0.071 103.193)",
|
|
55
|
+
"yellow-200": "oklch(94.5% 0.129 101.54)",
|
|
56
|
+
"yellow-300": "oklch(90.5% 0.182 98.111)",
|
|
57
|
+
"yellow-400": "oklch(85.2% 0.199 91.936)",
|
|
58
|
+
"yellow-500": "oklch(79.5% 0.184 86.047)",
|
|
59
|
+
"yellow-600": "oklch(68.1% 0.162 75.834)",
|
|
60
|
+
"yellow-700": "oklch(55.4% 0.135 66.442)",
|
|
61
|
+
"yellow-800": "oklch(47.6% 0.114 61.907)",
|
|
62
|
+
"yellow-900": "oklch(42.1% 0.095 57.708)",
|
|
63
|
+
"yellow-950": "oklch(28.6% 0.066 53.813)",
|
|
64
|
+
"lime-50": "oklch(98.6% 0.031 120.757)",
|
|
65
|
+
"lime-100": "oklch(96.7% 0.067 122.328)",
|
|
66
|
+
"lime-200": "oklch(93.8% 0.127 124.321)",
|
|
67
|
+
"lime-300": "oklch(89.7% 0.196 126.665)",
|
|
68
|
+
"lime-400": "oklch(84.1% 0.238 128.85)",
|
|
69
|
+
"lime-500": "oklch(76.8% 0.233 130.85)",
|
|
70
|
+
"lime-600": "oklch(64.8% 0.2 131.684)",
|
|
71
|
+
"lime-700": "oklch(53.2% 0.157 131.589)",
|
|
72
|
+
"lime-800": "oklch(45.3% 0.124 130.933)",
|
|
73
|
+
"lime-900": "oklch(40.5% 0.101 131.063)",
|
|
74
|
+
"lime-950": "oklch(27.4% 0.072 132.109)",
|
|
75
|
+
"green-50": "oklch(98.2% 0.018 155.826)",
|
|
76
|
+
"green-100": "oklch(96.2% 0.044 156.743)",
|
|
77
|
+
"green-200": "oklch(92.5% 0.084 155.995)",
|
|
78
|
+
"green-300": "oklch(87.1% 0.15 154.449)",
|
|
79
|
+
"green-400": "oklch(79.2% 0.209 151.711)",
|
|
80
|
+
"green-500": "oklch(72.3% 0.219 149.579)",
|
|
81
|
+
"green-600": "oklch(62.7% 0.194 149.214)",
|
|
82
|
+
"green-700": "oklch(52.7% 0.154 150.069)",
|
|
83
|
+
"green-800": "oklch(44.8% 0.119 151.328)",
|
|
84
|
+
"green-900": "oklch(39.3% 0.095 152.535)",
|
|
85
|
+
"green-950": "oklch(26.6% 0.065 152.934)",
|
|
86
|
+
"emerald-50": "oklch(97.9% 0.021 166.113)",
|
|
87
|
+
"emerald-100": "oklch(95% 0.052 163.051)",
|
|
88
|
+
"emerald-200": "oklch(90.5% 0.093 164.15)",
|
|
89
|
+
"emerald-300": "oklch(84.5% 0.143 164.978)",
|
|
90
|
+
"emerald-400": "oklch(76.5% 0.177 163.223)",
|
|
91
|
+
"emerald-500": "oklch(69.6% 0.17 162.48)",
|
|
92
|
+
"emerald-600": "oklch(59.6% 0.145 163.225)",
|
|
93
|
+
"emerald-700": "oklch(50.8% 0.118 165.612)",
|
|
94
|
+
"emerald-800": "oklch(43.2% 0.095 166.913)",
|
|
95
|
+
"emerald-900": "oklch(37.8% 0.077 168.94)",
|
|
96
|
+
"emerald-950": "oklch(26.2% 0.051 172.552)",
|
|
97
|
+
"teal-50": "oklch(98.4% 0.014 180.72)",
|
|
98
|
+
"teal-100": "oklch(95.3% 0.051 180.801)",
|
|
99
|
+
"teal-200": "oklch(91% 0.096 180.426)",
|
|
100
|
+
"teal-300": "oklch(85.5% 0.138 181.071)",
|
|
101
|
+
"teal-400": "oklch(77.7% 0.152 181.912)",
|
|
102
|
+
"teal-500": "oklch(70.4% 0.14 182.503)",
|
|
103
|
+
"teal-600": "oklch(60% 0.118 184.704)",
|
|
104
|
+
"teal-700": "oklch(51.1% 0.096 186.391)",
|
|
105
|
+
"teal-800": "oklch(43.7% 0.078 188.216)",
|
|
106
|
+
"teal-900": "oklch(38.6% 0.063 188.416)",
|
|
107
|
+
"teal-950": "oklch(27.7% 0.046 192.524)",
|
|
108
|
+
"cyan-50": "oklch(98.4% 0.019 200.873)",
|
|
109
|
+
"cyan-100": "oklch(95.6% 0.045 203.388)",
|
|
110
|
+
"cyan-200": "oklch(91.7% 0.08 205.041)",
|
|
111
|
+
"cyan-300": "oklch(86.5% 0.127 207.078)",
|
|
112
|
+
"cyan-400": "oklch(78.9% 0.154 211.53)",
|
|
113
|
+
"cyan-500": "oklch(71.5% 0.143 215.221)",
|
|
114
|
+
"cyan-600": "oklch(60.9% 0.126 221.723)",
|
|
115
|
+
"cyan-700": "oklch(52% 0.105 223.128)",
|
|
116
|
+
"cyan-800": "oklch(45% 0.085 224.283)",
|
|
117
|
+
"cyan-900": "oklch(39.8% 0.07 227.392)",
|
|
118
|
+
"cyan-950": "oklch(30.2% 0.056 229.695)",
|
|
119
|
+
"sky-50": "oklch(97.7% 0.013 236.62)",
|
|
120
|
+
"sky-100": "oklch(95.1% 0.026 236.824)",
|
|
121
|
+
"sky-200": "oklch(90.1% 0.058 230.902)",
|
|
122
|
+
"sky-300": "oklch(82.8% 0.111 230.318)",
|
|
123
|
+
"sky-400": "oklch(74.6% 0.16 232.661)",
|
|
124
|
+
"sky-500": "oklch(68.5% 0.169 237.323)",
|
|
125
|
+
"sky-600": "oklch(58.8% 0.158 241.966)",
|
|
126
|
+
"sky-700": "oklch(50% 0.134 242.749)",
|
|
127
|
+
"sky-800": "oklch(44.3% 0.11 240.79)",
|
|
128
|
+
"sky-900": "oklch(39.1% 0.09 240.876)",
|
|
129
|
+
"sky-950": "oklch(29.3% 0.066 243.157)",
|
|
130
|
+
"blue-50": "oklch(97% 0.014 254.604)",
|
|
131
|
+
"blue-100": "oklch(93.2% 0.032 255.585)",
|
|
132
|
+
"blue-200": "oklch(88.2% 0.059 254.128)",
|
|
133
|
+
"blue-300": "oklch(80.9% 0.105 251.813)",
|
|
134
|
+
"blue-400": "oklch(70.7% 0.165 254.624)",
|
|
135
|
+
"blue-500": "oklch(62.3% 0.214 259.815)",
|
|
136
|
+
"blue-600": "oklch(54.6% 0.245 262.881)",
|
|
137
|
+
"blue-700": "oklch(48.8% 0.243 264.376)",
|
|
138
|
+
"blue-800": "oklch(42.4% 0.199 265.638)",
|
|
139
|
+
"blue-900": "oklch(37.9% 0.146 265.522)",
|
|
140
|
+
"blue-950": "oklch(28.2% 0.091 267.935)",
|
|
141
|
+
"indigo-50": "oklch(96.2% 0.018 272.314)",
|
|
142
|
+
"indigo-100": "oklch(93% 0.034 272.788)",
|
|
143
|
+
"indigo-200": "oklch(87% 0.065 274.039)",
|
|
144
|
+
"indigo-300": "oklch(78.5% 0.115 274.713)",
|
|
145
|
+
"indigo-400": "oklch(67.3% 0.182 276.935)",
|
|
146
|
+
"indigo-500": "oklch(58.5% 0.233 277.117)",
|
|
147
|
+
"indigo-600": "oklch(51.1% 0.262 276.966)",
|
|
148
|
+
"indigo-700": "oklch(45.7% 0.24 277.023)",
|
|
149
|
+
"indigo-800": "oklch(39.8% 0.195 277.366)",
|
|
150
|
+
"indigo-900": "oklch(35.9% 0.144 278.697)",
|
|
151
|
+
"indigo-950": "oklch(25.7% 0.09 281.288)",
|
|
152
|
+
"violet-50": "oklch(96.9% 0.016 293.756)",
|
|
153
|
+
"violet-100": "oklch(94.3% 0.029 294.588)",
|
|
154
|
+
"violet-200": "oklch(89.4% 0.057 293.283)",
|
|
155
|
+
"violet-300": "oklch(81.1% 0.111 293.571)",
|
|
156
|
+
"violet-400": "oklch(70.2% 0.183 293.541)",
|
|
157
|
+
"violet-500": "oklch(60.6% 0.25 292.717)",
|
|
158
|
+
"violet-600": "oklch(54.1% 0.281 293.009)",
|
|
159
|
+
"violet-700": "oklch(49.1% 0.27 292.581)",
|
|
160
|
+
"violet-800": "oklch(43.2% 0.232 292.759)",
|
|
161
|
+
"violet-900": "oklch(38% 0.189 293.745)",
|
|
162
|
+
"violet-950": "oklch(28.3% 0.141 291.089)",
|
|
163
|
+
"purple-50": "oklch(97.7% 0.014 308.299)",
|
|
164
|
+
"purple-100": "oklch(94.6% 0.033 307.174)",
|
|
165
|
+
"purple-200": "oklch(90.2% 0.063 306.703)",
|
|
166
|
+
"purple-300": "oklch(82.7% 0.119 306.383)",
|
|
167
|
+
"purple-400": "oklch(71.4% 0.203 305.504)",
|
|
168
|
+
"purple-500": "oklch(62.7% 0.265 303.9)",
|
|
169
|
+
"purple-600": "oklch(55.8% 0.288 302.321)",
|
|
170
|
+
"purple-700": "oklch(49.6% 0.265 301.924)",
|
|
171
|
+
"purple-800": "oklch(43.8% 0.218 303.724)",
|
|
172
|
+
"purple-900": "oklch(38.1% 0.176 304.987)",
|
|
173
|
+
"purple-950": "oklch(29.1% 0.149 302.717)",
|
|
174
|
+
"fuchsia-50": "oklch(97.7% 0.017 320.058)",
|
|
175
|
+
"fuchsia-100": "oklch(95.2% 0.037 318.852)",
|
|
176
|
+
"fuchsia-200": "oklch(90.3% 0.076 319.62)",
|
|
177
|
+
"fuchsia-300": "oklch(83.3% 0.145 321.434)",
|
|
178
|
+
"fuchsia-400": "oklch(74% 0.238 322.16)",
|
|
179
|
+
"fuchsia-500": "oklch(66.7% 0.295 322.15)",
|
|
180
|
+
"fuchsia-600": "oklch(59.1% 0.293 322.896)",
|
|
181
|
+
"fuchsia-700": "oklch(51.8% 0.253 323.949)",
|
|
182
|
+
"fuchsia-800": "oklch(45.2% 0.211 324.591)",
|
|
183
|
+
"fuchsia-900": "oklch(40.1% 0.17 325.612)",
|
|
184
|
+
"fuchsia-950": "oklch(29.3% 0.136 325.661)",
|
|
185
|
+
"pink-50": "oklch(97.1% 0.014 343.198)",
|
|
186
|
+
"pink-100": "oklch(94.8% 0.028 342.258)",
|
|
187
|
+
"pink-200": "oklch(89.9% 0.061 343.231)",
|
|
188
|
+
"pink-300": "oklch(82.3% 0.12 346.018)",
|
|
189
|
+
"pink-400": "oklch(71.8% 0.202 349.761)",
|
|
190
|
+
"pink-500": "oklch(65.6% 0.241 354.308)",
|
|
191
|
+
"pink-600": "oklch(59.2% 0.249 0.584)",
|
|
192
|
+
"pink-700": "oklch(52.5% 0.223 3.958)",
|
|
193
|
+
"pink-800": "oklch(45.9% 0.187 3.815)",
|
|
194
|
+
"pink-900": "oklch(40.8% 0.153 2.432)",
|
|
195
|
+
"pink-950": "oklch(28.4% 0.109 3.907)",
|
|
196
|
+
"rose-50": "oklch(96.9% 0.015 12.422)",
|
|
197
|
+
"rose-100": "oklch(94.1% 0.03 12.58)",
|
|
198
|
+
"rose-200": "oklch(89.2% 0.058 10.001)",
|
|
199
|
+
"rose-300": "oklch(81% 0.117 11.638)",
|
|
200
|
+
"rose-400": "oklch(71.2% 0.194 13.428)",
|
|
201
|
+
"rose-500": "oklch(64.5% 0.246 16.439)",
|
|
202
|
+
"rose-600": "oklch(58.6% 0.253 17.585)",
|
|
203
|
+
"rose-700": "oklch(51.4% 0.222 16.935)",
|
|
204
|
+
"rose-800": "oklch(45.5% 0.188 13.697)",
|
|
205
|
+
"rose-900": "oklch(41% 0.159 10.272)",
|
|
206
|
+
"rose-950": "oklch(27.1% 0.105 12.094)",
|
|
207
|
+
"slate-50": "oklch(98.4% 0.003 247.858)",
|
|
208
|
+
"slate-100": "oklch(96.8% 0.007 247.896)",
|
|
209
|
+
"slate-200": "oklch(92.9% 0.013 255.508)",
|
|
210
|
+
"slate-300": "oklch(86.9% 0.022 252.894)",
|
|
211
|
+
"slate-400": "oklch(70.4% 0.04 256.788)",
|
|
212
|
+
"slate-500": "oklch(55.4% 0.046 257.417)",
|
|
213
|
+
"slate-600": "oklch(44.6% 0.043 257.281)",
|
|
214
|
+
"slate-700": "oklch(37.2% 0.044 257.287)",
|
|
215
|
+
"slate-800": "oklch(27.9% 0.041 260.031)",
|
|
216
|
+
"slate-900": "oklch(20.8% 0.042 265.755)",
|
|
217
|
+
"slate-950": "oklch(12.9% 0.042 264.695)",
|
|
218
|
+
"gray-50": "oklch(98.5% 0.002 247.839)",
|
|
219
|
+
"gray-100": "oklch(96.7% 0.003 264.542)",
|
|
220
|
+
"gray-200": "oklch(92.8% 0.006 264.531)",
|
|
221
|
+
"gray-300": "oklch(87.2% 0.01 258.338)",
|
|
222
|
+
"gray-400": "oklch(70.7% 0.022 261.325)",
|
|
223
|
+
"gray-500": "oklch(55.1% 0.027 264.364)",
|
|
224
|
+
"gray-600": "oklch(44.6% 0.03 256.802)",
|
|
225
|
+
"gray-700": "oklch(37.3% 0.034 259.733)",
|
|
226
|
+
"gray-800": "oklch(27.8% 0.033 256.848)",
|
|
227
|
+
"gray-900": "oklch(21% 0.034 264.665)",
|
|
228
|
+
"gray-950": "oklch(13% 0.028 261.692)",
|
|
229
|
+
"zinc-50": "oklch(98.5% 0 0)",
|
|
230
|
+
"zinc-100": "oklch(96.7% 0.001 286.375)",
|
|
231
|
+
"zinc-200": "oklch(92% 0.004 286.32)",
|
|
232
|
+
"zinc-300": "oklch(87.1% 0.006 286.286)",
|
|
233
|
+
"zinc-400": "oklch(70.5% 0.015 286.067)",
|
|
234
|
+
"zinc-500": "oklch(55.2% 0.016 285.938)",
|
|
235
|
+
"zinc-600": "oklch(44.2% 0.017 285.786)",
|
|
236
|
+
"zinc-700": "oklch(37% 0.013 285.805)",
|
|
237
|
+
"zinc-800": "oklch(27.4% 0.006 286.033)",
|
|
238
|
+
"zinc-900": "oklch(21% 0.006 285.885)",
|
|
239
|
+
"zinc-950": "oklch(14.1% 0.005 285.823)",
|
|
240
|
+
"neutral-50": "oklch(98.5% 0 0)",
|
|
241
|
+
"neutral-100": "oklch(97% 0 0)",
|
|
242
|
+
"neutral-200": "oklch(92.2% 0 0)",
|
|
243
|
+
"neutral-300": "oklch(87% 0 0)",
|
|
244
|
+
"neutral-400": "oklch(70.8% 0 0)",
|
|
245
|
+
"neutral-500": "oklch(55.6% 0 0)",
|
|
246
|
+
"neutral-600": "oklch(43.9% 0 0)",
|
|
247
|
+
"neutral-700": "oklch(37.1% 0 0)",
|
|
248
|
+
"neutral-800": "oklch(26.9% 0 0)",
|
|
249
|
+
"neutral-900": "oklch(20.5% 0 0)",
|
|
250
|
+
"neutral-950": "oklch(14.5% 0 0)",
|
|
251
|
+
"stone-50": "oklch(98.5% 0.001 106.423)",
|
|
252
|
+
"stone-100": "oklch(97% 0.001 106.424)",
|
|
253
|
+
"stone-200": "oklch(92.3% 0.003 48.717)",
|
|
254
|
+
"stone-300": "oklch(86.9% 0.005 56.366)",
|
|
255
|
+
"stone-400": "oklch(70.9% 0.01 56.259)",
|
|
256
|
+
"stone-500": "oklch(55.3% 0.013 58.071)",
|
|
257
|
+
"stone-600": "oklch(44.4% 0.011 73.639)",
|
|
258
|
+
"stone-700": "oklch(37.4% 0.01 67.558)",
|
|
259
|
+
"stone-800": "oklch(26.8% 0.007 34.298)",
|
|
260
|
+
"stone-900": "oklch(21.6% 0.006 56.043)",
|
|
261
|
+
"stone-950": "oklch(14.7% 0.004 49.25)",
|
|
262
|
+
"mauve-50": "oklch(98.5% 0 0)",
|
|
263
|
+
"mauve-100": "oklch(96% 0.003 325.6)",
|
|
264
|
+
"mauve-200": "oklch(92.2% 0.005 325.62)",
|
|
265
|
+
"mauve-300": "oklch(86.5% 0.012 325.68)",
|
|
266
|
+
"mauve-400": "oklch(71.1% 0.019 323.02)",
|
|
267
|
+
"mauve-500": "oklch(54.2% 0.034 322.5)",
|
|
268
|
+
"mauve-600": "oklch(43.5% 0.029 321.78)",
|
|
269
|
+
"mauve-700": "oklch(36.4% 0.029 323.89)",
|
|
270
|
+
"mauve-800": "oklch(26.3% 0.024 320.12)",
|
|
271
|
+
"mauve-900": "oklch(21.2% 0.019 322.12)",
|
|
272
|
+
"mauve-950": "oklch(14.5% 0.008 326)",
|
|
273
|
+
"olive-50": "oklch(98.8% 0.003 106.5)",
|
|
274
|
+
"olive-100": "oklch(96.6% 0.005 106.5)",
|
|
275
|
+
"olive-200": "oklch(93% 0.007 106.5)",
|
|
276
|
+
"olive-300": "oklch(88% 0.011 106.6)",
|
|
277
|
+
"olive-400": "oklch(73.7% 0.021 106.9)",
|
|
278
|
+
"olive-500": "oklch(58% 0.031 107.3)",
|
|
279
|
+
"olive-600": "oklch(46.6% 0.025 107.3)",
|
|
280
|
+
"olive-700": "oklch(39.4% 0.023 107.4)",
|
|
281
|
+
"olive-800": "oklch(28.6% 0.016 107.4)",
|
|
282
|
+
"olive-900": "oklch(22.8% 0.013 107.4)",
|
|
283
|
+
"olive-950": "oklch(15.3% 0.006 107.1)",
|
|
284
|
+
"mist-50": "oklch(98.7% 0.002 197.1)",
|
|
285
|
+
"mist-100": "oklch(96.3% 0.002 197.1)",
|
|
286
|
+
"mist-200": "oklch(92.5% 0.005 214.3)",
|
|
287
|
+
"mist-300": "oklch(87.2% 0.007 219.6)",
|
|
288
|
+
"mist-400": "oklch(72.3% 0.014 214.4)",
|
|
289
|
+
"mist-500": "oklch(56% 0.021 213.5)",
|
|
290
|
+
"mist-600": "oklch(45% 0.017 213.2)",
|
|
291
|
+
"mist-700": "oklch(37.8% 0.015 216)",
|
|
292
|
+
"mist-800": "oklch(27.5% 0.011 216.9)",
|
|
293
|
+
"mist-900": "oklch(21.8% 0.008 223.9)",
|
|
294
|
+
"mist-950": "oklch(14.8% 0.004 228.8)",
|
|
295
|
+
"taupe-50": "oklch(98.6% 0.002 67.8)",
|
|
296
|
+
"taupe-100": "oklch(96% 0.002 17.2)",
|
|
297
|
+
"taupe-200": "oklch(92.2% 0.005 34.3)",
|
|
298
|
+
"taupe-300": "oklch(86.8% 0.007 39.5)",
|
|
299
|
+
"taupe-400": "oklch(71.4% 0.014 41.2)",
|
|
300
|
+
"taupe-500": "oklch(54.7% 0.021 43.1)",
|
|
301
|
+
"taupe-600": "oklch(43.8% 0.017 39.3)",
|
|
302
|
+
"taupe-700": "oklch(36.7% 0.016 35.7)",
|
|
303
|
+
"taupe-800": "oklch(26.8% 0.011 36.5)",
|
|
304
|
+
"taupe-900": "oklch(21.4% 0.009 43.1)",
|
|
305
|
+
"taupe-950": "oklch(14.7% 0.004 49.3)",
|
|
306
|
+
};
|
|
307
|
+
const V3 = {
|
|
308
|
+
"slate-50": "#f8fafc",
|
|
309
|
+
"slate-100": "#f1f5f9",
|
|
310
|
+
"slate-200": "#e2e8f0",
|
|
311
|
+
"slate-300": "#cbd5e1",
|
|
312
|
+
"slate-400": "#94a3b8",
|
|
313
|
+
"slate-500": "#64748b",
|
|
314
|
+
"slate-600": "#475569",
|
|
315
|
+
"slate-700": "#334155",
|
|
316
|
+
"slate-800": "#1e293b",
|
|
317
|
+
"slate-900": "#0f172a",
|
|
318
|
+
"slate-950": "#020617",
|
|
319
|
+
"gray-50": "#f9fafb",
|
|
320
|
+
"gray-100": "#f3f4f6",
|
|
321
|
+
"gray-200": "#e5e7eb",
|
|
322
|
+
"gray-300": "#d1d5db",
|
|
323
|
+
"gray-400": "#9ca3af",
|
|
324
|
+
"gray-500": "#6b7280",
|
|
325
|
+
"gray-600": "#4b5563",
|
|
326
|
+
"gray-700": "#374151",
|
|
327
|
+
"gray-800": "#1f2937",
|
|
328
|
+
"gray-900": "#111827",
|
|
329
|
+
"gray-950": "#030712",
|
|
330
|
+
"zinc-50": "#fafafa",
|
|
331
|
+
"zinc-100": "#f4f4f5",
|
|
332
|
+
"zinc-200": "#e4e4e7",
|
|
333
|
+
"zinc-300": "#d4d4d8",
|
|
334
|
+
"zinc-400": "#a1a1aa",
|
|
335
|
+
"zinc-500": "#71717a",
|
|
336
|
+
"zinc-600": "#52525b",
|
|
337
|
+
"zinc-700": "#3f3f46",
|
|
338
|
+
"zinc-800": "#27272a",
|
|
339
|
+
"zinc-900": "#18181b",
|
|
340
|
+
"zinc-950": "#09090b",
|
|
341
|
+
"neutral-50": "#fafafa",
|
|
342
|
+
"neutral-100": "#f5f5f5",
|
|
343
|
+
"neutral-200": "#e5e5e5",
|
|
344
|
+
"neutral-300": "#d4d4d4",
|
|
345
|
+
"neutral-400": "#a3a3a3",
|
|
346
|
+
"neutral-500": "#737373",
|
|
347
|
+
"neutral-600": "#525252",
|
|
348
|
+
"neutral-700": "#404040",
|
|
349
|
+
"neutral-800": "#262626",
|
|
350
|
+
"neutral-900": "#171717",
|
|
351
|
+
"neutral-950": "#0a0a0a",
|
|
352
|
+
"stone-50": "#fafaf9",
|
|
353
|
+
"stone-100": "#f5f5f4",
|
|
354
|
+
"stone-200": "#e7e5e4",
|
|
355
|
+
"stone-300": "#d6d3d1",
|
|
356
|
+
"stone-400": "#a8a29e",
|
|
357
|
+
"stone-500": "#78716c",
|
|
358
|
+
"stone-600": "#57534e",
|
|
359
|
+
"stone-700": "#44403c",
|
|
360
|
+
"stone-800": "#292524",
|
|
361
|
+
"stone-900": "#1c1917",
|
|
362
|
+
"stone-950": "#0c0a09",
|
|
363
|
+
"red-50": "#fef2f2",
|
|
364
|
+
"red-100": "#fee2e2",
|
|
365
|
+
"red-200": "#fecaca",
|
|
366
|
+
"red-300": "#fca5a5",
|
|
367
|
+
"red-400": "#f87171",
|
|
368
|
+
"red-500": "#ef4444",
|
|
369
|
+
"red-600": "#dc2626",
|
|
370
|
+
"red-700": "#b91c1c",
|
|
371
|
+
"red-800": "#991b1b",
|
|
372
|
+
"red-900": "#7f1d1d",
|
|
373
|
+
"red-950": "#450a0a",
|
|
374
|
+
"orange-50": "#fff7ed",
|
|
375
|
+
"orange-100": "#ffedd5",
|
|
376
|
+
"orange-200": "#fed7aa",
|
|
377
|
+
"orange-300": "#fdba74",
|
|
378
|
+
"orange-400": "#fb923c",
|
|
379
|
+
"orange-500": "#f97316",
|
|
380
|
+
"orange-600": "#ea580c",
|
|
381
|
+
"orange-700": "#c2410c",
|
|
382
|
+
"orange-800": "#9a3412",
|
|
383
|
+
"orange-900": "#7c2d12",
|
|
384
|
+
"orange-950": "#431407",
|
|
385
|
+
"amber-50": "#fffbeb",
|
|
386
|
+
"amber-100": "#fef3c7",
|
|
387
|
+
"amber-200": "#fde68a",
|
|
388
|
+
"amber-300": "#fcd34d",
|
|
389
|
+
"amber-400": "#fbbf24",
|
|
390
|
+
"amber-500": "#f59e0b",
|
|
391
|
+
"amber-600": "#d97706",
|
|
392
|
+
"amber-700": "#b45309",
|
|
393
|
+
"amber-800": "#92400e",
|
|
394
|
+
"amber-900": "#78350f",
|
|
395
|
+
"amber-950": "#451a03",
|
|
396
|
+
"yellow-50": "#fefce8",
|
|
397
|
+
"yellow-100": "#fef9c3",
|
|
398
|
+
"yellow-200": "#fef08a",
|
|
399
|
+
"yellow-300": "#fde047",
|
|
400
|
+
"yellow-400": "#facc15",
|
|
401
|
+
"yellow-500": "#eab308",
|
|
402
|
+
"yellow-600": "#ca8a04",
|
|
403
|
+
"yellow-700": "#a16207",
|
|
404
|
+
"yellow-800": "#854d0e",
|
|
405
|
+
"yellow-900": "#713f12",
|
|
406
|
+
"yellow-950": "#422006",
|
|
407
|
+
"lime-50": "#f7fee7",
|
|
408
|
+
"lime-100": "#ecfccb",
|
|
409
|
+
"lime-200": "#d9f99d",
|
|
410
|
+
"lime-300": "#bef264",
|
|
411
|
+
"lime-400": "#a3e635",
|
|
412
|
+
"lime-500": "#84cc16",
|
|
413
|
+
"lime-600": "#65a30d",
|
|
414
|
+
"lime-700": "#4d7c0f",
|
|
415
|
+
"lime-800": "#3f6212",
|
|
416
|
+
"lime-900": "#365314",
|
|
417
|
+
"lime-950": "#1a2e05",
|
|
418
|
+
"green-50": "#f0fdf4",
|
|
419
|
+
"green-100": "#dcfce7",
|
|
420
|
+
"green-200": "#bbf7d0",
|
|
421
|
+
"green-300": "#86efac",
|
|
422
|
+
"green-400": "#4ade80",
|
|
423
|
+
"green-500": "#22c55e",
|
|
424
|
+
"green-600": "#16a34a",
|
|
425
|
+
"green-700": "#15803d",
|
|
426
|
+
"green-800": "#166534",
|
|
427
|
+
"green-900": "#14532d",
|
|
428
|
+
"green-950": "#052e16",
|
|
429
|
+
"emerald-50": "#ecfdf5",
|
|
430
|
+
"emerald-100": "#d1fae5",
|
|
431
|
+
"emerald-200": "#a7f3d0",
|
|
432
|
+
"emerald-300": "#6ee7b7",
|
|
433
|
+
"emerald-400": "#34d399",
|
|
434
|
+
"emerald-500": "#10b981",
|
|
435
|
+
"emerald-600": "#059669",
|
|
436
|
+
"emerald-700": "#047857",
|
|
437
|
+
"emerald-800": "#065f46",
|
|
438
|
+
"emerald-900": "#064e3b",
|
|
439
|
+
"emerald-950": "#022c22",
|
|
440
|
+
"teal-50": "#f0fdfa",
|
|
441
|
+
"teal-100": "#ccfbf1",
|
|
442
|
+
"teal-200": "#99f6e4",
|
|
443
|
+
"teal-300": "#5eead4",
|
|
444
|
+
"teal-400": "#2dd4bf",
|
|
445
|
+
"teal-500": "#14b8a6",
|
|
446
|
+
"teal-600": "#0d9488",
|
|
447
|
+
"teal-700": "#0f766e",
|
|
448
|
+
"teal-800": "#115e59",
|
|
449
|
+
"teal-900": "#134e4a",
|
|
450
|
+
"teal-950": "#042f2e",
|
|
451
|
+
"cyan-50": "#ecfeff",
|
|
452
|
+
"cyan-100": "#cffafe",
|
|
453
|
+
"cyan-200": "#a5f3fc",
|
|
454
|
+
"cyan-300": "#67e8f9",
|
|
455
|
+
"cyan-400": "#22d3ee",
|
|
456
|
+
"cyan-500": "#06b6d4",
|
|
457
|
+
"cyan-600": "#0891b2",
|
|
458
|
+
"cyan-700": "#0e7490",
|
|
459
|
+
"cyan-800": "#155e75",
|
|
460
|
+
"cyan-900": "#164e63",
|
|
461
|
+
"cyan-950": "#083344",
|
|
462
|
+
"sky-50": "#f0f9ff",
|
|
463
|
+
"sky-100": "#e0f2fe",
|
|
464
|
+
"sky-200": "#bae6fd",
|
|
465
|
+
"sky-300": "#7dd3fc",
|
|
466
|
+
"sky-400": "#38bdf8",
|
|
467
|
+
"sky-500": "#0ea5e9",
|
|
468
|
+
"sky-600": "#0284c7",
|
|
469
|
+
"sky-700": "#0369a1",
|
|
470
|
+
"sky-800": "#075985",
|
|
471
|
+
"sky-900": "#0c4a6e",
|
|
472
|
+
"sky-950": "#082f49",
|
|
473
|
+
"blue-50": "#eff6ff",
|
|
474
|
+
"blue-100": "#dbeafe",
|
|
475
|
+
"blue-200": "#bfdbfe",
|
|
476
|
+
"blue-300": "#93c5fd",
|
|
477
|
+
"blue-400": "#60a5fa",
|
|
478
|
+
"blue-500": "#3b82f6",
|
|
479
|
+
"blue-600": "#2563eb",
|
|
480
|
+
"blue-700": "#1d4ed8",
|
|
481
|
+
"blue-800": "#1e40af",
|
|
482
|
+
"blue-900": "#1e3a8a",
|
|
483
|
+
"blue-950": "#172554",
|
|
484
|
+
"indigo-50": "#eef2ff",
|
|
485
|
+
"indigo-100": "#e0e7ff",
|
|
486
|
+
"indigo-200": "#c7d2fe",
|
|
487
|
+
"indigo-300": "#a5b4fc",
|
|
488
|
+
"indigo-400": "#818cf8",
|
|
489
|
+
"indigo-500": "#6366f1",
|
|
490
|
+
"indigo-600": "#4f46e5",
|
|
491
|
+
"indigo-700": "#4338ca",
|
|
492
|
+
"indigo-800": "#3730a3",
|
|
493
|
+
"indigo-900": "#312e81",
|
|
494
|
+
"indigo-950": "#1e1b4b",
|
|
495
|
+
"violet-50": "#f5f3ff",
|
|
496
|
+
"violet-100": "#ede9fe",
|
|
497
|
+
"violet-200": "#ddd6fe",
|
|
498
|
+
"violet-300": "#c4b5fd",
|
|
499
|
+
"violet-400": "#a78bfa",
|
|
500
|
+
"violet-500": "#8b5cf6",
|
|
501
|
+
"violet-600": "#7c3aed",
|
|
502
|
+
"violet-700": "#6d28d9",
|
|
503
|
+
"violet-800": "#5b21b6",
|
|
504
|
+
"violet-900": "#4c1d95",
|
|
505
|
+
"violet-950": "#2e1065",
|
|
506
|
+
"purple-50": "#faf5ff",
|
|
507
|
+
"purple-100": "#f3e8ff",
|
|
508
|
+
"purple-200": "#e9d5ff",
|
|
509
|
+
"purple-300": "#d8b4fe",
|
|
510
|
+
"purple-400": "#c084fc",
|
|
511
|
+
"purple-500": "#a855f7",
|
|
512
|
+
"purple-600": "#9333ea",
|
|
513
|
+
"purple-700": "#7e22ce",
|
|
514
|
+
"purple-800": "#6b21a8",
|
|
515
|
+
"purple-900": "#581c87",
|
|
516
|
+
"purple-950": "#3b0764",
|
|
517
|
+
"fuchsia-50": "#fdf4ff",
|
|
518
|
+
"fuchsia-100": "#fae8ff",
|
|
519
|
+
"fuchsia-200": "#f5d0fe",
|
|
520
|
+
"fuchsia-300": "#f0abfc",
|
|
521
|
+
"fuchsia-400": "#e879f9",
|
|
522
|
+
"fuchsia-500": "#d946ef",
|
|
523
|
+
"fuchsia-600": "#c026d3",
|
|
524
|
+
"fuchsia-700": "#a21caf",
|
|
525
|
+
"fuchsia-800": "#86198f",
|
|
526
|
+
"fuchsia-900": "#701a75",
|
|
527
|
+
"fuchsia-950": "#4a044e",
|
|
528
|
+
"pink-50": "#fdf2f8",
|
|
529
|
+
"pink-100": "#fce7f3",
|
|
530
|
+
"pink-200": "#fbcfe8",
|
|
531
|
+
"pink-300": "#f9a8d4",
|
|
532
|
+
"pink-400": "#f472b6",
|
|
533
|
+
"pink-500": "#ec4899",
|
|
534
|
+
"pink-600": "#db2777",
|
|
535
|
+
"pink-700": "#be185d",
|
|
536
|
+
"pink-800": "#9d174d",
|
|
537
|
+
"pink-900": "#831843",
|
|
538
|
+
"pink-950": "#500724",
|
|
539
|
+
"rose-50": "#fff1f2",
|
|
540
|
+
"rose-100": "#ffe4e6",
|
|
541
|
+
"rose-200": "#fecdd3",
|
|
542
|
+
"rose-300": "#fda4af",
|
|
543
|
+
"rose-400": "#fb7185",
|
|
544
|
+
"rose-500": "#f43f5e",
|
|
545
|
+
"rose-600": "#e11d48",
|
|
546
|
+
"rose-700": "#be123c",
|
|
547
|
+
"rose-800": "#9f1239",
|
|
548
|
+
"rose-900": "#881337",
|
|
549
|
+
"rose-950": "#4c0519",
|
|
550
|
+
};
|
|
551
|
+
/**
|
|
552
|
+
* A VERSÃO MAIOR DO PROJETO MEDIDO - módulo-estado, como `useLiveCatalogue`: o censo sabe a
|
|
553
|
+
* versão (`project.versions`) e o resolvedor é chamado fundo demais para receber mais um
|
|
554
|
+
* parâmetro em vinte call sites. Default v4, que é o que o npm entrega hoje; quem mede um projeto
|
|
555
|
+
* v3 chama o setter antes da varredura.
|
|
556
|
+
*/
|
|
557
|
+
let major = 4;
|
|
558
|
+
export function useFrameworkMajor(next) {
|
|
559
|
+
major = next != null && next >= 1 && next < 4 ? 3 : 4;
|
|
560
|
+
}
|
|
561
|
+
/** A cor publicada do framework para um nome de paleta - ou null, que é "não é da paleta". */
|
|
562
|
+
export function frameworkColour(name) {
|
|
563
|
+
return (major === 3 ? V3 : V4)[name] ?? null;
|
|
564
|
+
}
|
|
565
|
+
/** Uma declaração resolvida pela tabela carrega o carimbo do D1 - ver `Declaration.from`. */
|
|
566
|
+
export function frameworkDeclaration(property, name) {
|
|
567
|
+
const value = frameworkColour(name);
|
|
568
|
+
return value ? { property, value, from: "framework" } : null;
|
|
569
|
+
}
|
|
@@ -27,6 +27,7 @@
|
|
|
27
27
|
* calculada em runtime seria exatamente a mentira que esta esteira existe para não contar.
|
|
28
28
|
*/
|
|
29
29
|
import { READER } from "../reader-version.js";
|
|
30
|
+
import { formOf } from "./form-identity.js";
|
|
30
31
|
const SHAPES = [
|
|
31
32
|
"class",
|
|
32
33
|
"template",
|
|
@@ -144,6 +145,11 @@ const BECAUSE = {
|
|
|
144
145
|
* texto de um fragmento LIDO é descartado aqui de propósito - a interpretação dele já vive no
|
|
145
146
|
* look, e reter as duas cópias é o que dobraria o censo.
|
|
146
147
|
*/
|
|
148
|
+
/**
|
|
149
|
+
* TETO DE FORMAS POR GRUPO. Medido: as 706 folhas do app inteiro comprimem 18 473 declarações em
|
|
150
|
+
* 194 formas - 64 por grupo cobre as populações reais com folga e segura o patológico.
|
|
151
|
+
*/
|
|
152
|
+
const FORM_CAP = 64;
|
|
147
153
|
export function buildLedger(cli, seen,
|
|
148
154
|
/**
|
|
149
155
|
* OS NOMES QUE ELE DECLARA - para a contagem de `withTheirTokens`.
|
|
@@ -174,9 +180,16 @@ declared) {
|
|
|
174
180
|
unreadable: [],
|
|
175
181
|
seenFiles: new Set(),
|
|
176
182
|
withTheirTokens: 0,
|
|
183
|
+
formTally: new Map(),
|
|
177
184
|
};
|
|
178
185
|
group.uses += 1;
|
|
179
186
|
group.seenFiles.add(f.file);
|
|
187
|
+
/**
|
|
188
|
+
* A FORMA DO FRAGMENTO - a unidade da pergunta (item 12). Contada para TODO uso, não só o
|
|
189
|
+
* texto distinto: é o `uses` de cada forma que decide qual pergunta vale a pena fazer.
|
|
190
|
+
*/
|
|
191
|
+
const form = formOf(f.shape, f.text);
|
|
192
|
+
group.formTally.set(form, (group.formTally.get(form) ?? 0) + 1);
|
|
180
193
|
/**
|
|
181
194
|
* O VALOR É UM TOKEN DELE? A referência tem que apontar para algo DECLARADO - um
|
|
182
195
|
* `var(--nao-existe)` é descartado pelo browser, e ali não há token a reivindicar. Mesma regra do
|
|
@@ -233,11 +246,24 @@ declared) {
|
|
|
233
246
|
counted,
|
|
234
247
|
interpreted,
|
|
235
248
|
unread: [...groups.values()]
|
|
236
|
-
.map(({ seenFiles, withTheirTokens, ...group }) => ({
|
|
249
|
+
.map(({ seenFiles, withTheirTokens, formTally, ...group }) => ({
|
|
237
250
|
...group,
|
|
238
251
|
files: seenFiles.size,
|
|
239
252
|
/** Ausente quando é zero: um campo zerado em todo grupo é ruído em cada relatório. */
|
|
240
253
|
...(withTheirTokens && withTheirTokens > 0 ? { withTheirTokens } : {}),
|
|
254
|
+
/**
|
|
255
|
+
* AS FORMAS DESTE GRUPO, com os usos de cada uma - ver `form-identity.ts` (item 12).
|
|
256
|
+
* Ordenadas por uso: a primeira é a pergunta que mais vale a pena fazer. O teto corta o
|
|
257
|
+
* patológico, e `uses` do grupo continua contando tudo - o corte fica visível.
|
|
258
|
+
*/
|
|
259
|
+
...(formTally.size > 0
|
|
260
|
+
? {
|
|
261
|
+
forms: [...formTally.entries()]
|
|
262
|
+
.sort((a, b) => b[1] - a[1])
|
|
263
|
+
.slice(0, FORM_CAP)
|
|
264
|
+
.map(([form, uses]) => ({ form, uses })),
|
|
265
|
+
}
|
|
266
|
+
: {}),
|
|
241
267
|
}))
|
|
242
268
|
.sort((a, b) => b.uses - a.uses),
|
|
243
269
|
};
|
|
@@ -43,6 +43,7 @@
|
|
|
43
43
|
* data-[checked]:bg-ocean-50 → states.checked
|
|
44
44
|
*/
|
|
45
45
|
import { tokenRefFor } from "../token-ref.js";
|
|
46
|
+
import { frameworkDeclaration } from "./framework-palette.js";
|
|
46
47
|
/**
|
|
47
48
|
* Utility prefix → the property name THE DOCUMENT USES, which is camelCase.
|
|
48
49
|
*
|
|
@@ -291,33 +292,12 @@ const TAILWIND_COLOR = {
|
|
|
291
292
|
*/
|
|
292
293
|
current: "currentColor",
|
|
293
294
|
inherit: "inherit",
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
"zinc-400": "#a1a1aa",
|
|
301
|
-
"zinc-500": "#71717a",
|
|
302
|
-
"zinc-600": "#52525b",
|
|
303
|
-
"zinc-700": "#3f3f46",
|
|
304
|
-
"zinc-800": "#27272a",
|
|
305
|
-
"zinc-900": "#18181b",
|
|
306
|
-
"zinc-950": "#09090b",
|
|
307
|
-
"blue-400": "#60a5fa",
|
|
308
|
-
"blue-500": "#3b82f6",
|
|
309
|
-
"blue-600": "#2563eb",
|
|
310
|
-
"neutral-50": "#fafafa",
|
|
311
|
-
"neutral-100": "#f5f5f5",
|
|
312
|
-
"neutral-200": "#e5e5e5",
|
|
313
|
-
"neutral-300": "#d4d4d4",
|
|
314
|
-
"neutral-400": "#a3a3a3",
|
|
315
|
-
"neutral-500": "#737373",
|
|
316
|
-
"neutral-600": "#525252",
|
|
317
|
-
"neutral-700": "#404040",
|
|
318
|
-
"neutral-800": "#262626",
|
|
319
|
-
"neutral-900": "#171717",
|
|
320
|
-
"neutral-950": "#0a0a0a",
|
|
295
|
+
/**
|
|
296
|
+
* A PALETA saiu daqui em 25/08: zinc, blue e neutral (as entradas do test14) moravam nesta
|
|
297
|
+
* tabela com os hex da v3, cravados - e um projeto v4 recebia o hex antigo. A paleta inteira
|
|
298
|
+
* mora em `framework-palette.ts`, por versão maior e com o carimbo `from` que o D1 exige;
|
|
299
|
+
* aqui ficam só os KEYWORDS de CSS, que não são paleta e não têm versão.
|
|
300
|
+
*/
|
|
321
301
|
};
|
|
322
302
|
/**
|
|
323
303
|
* TYPOGRAPHY, and the reason it is here at all.
|
|
@@ -649,8 +629,12 @@ export function parseClass(cls) {
|
|
|
649
629
|
* `declared` maps a token NAME to its value, so a resolved colour can be
|
|
650
630
|
* reported in their vocabulary rather than as a hex we looked up.
|
|
651
631
|
*/
|
|
652
|
-
/**
|
|
653
|
-
|
|
632
|
+
/**
|
|
633
|
+
* A hex, a ref into their colour scale, OR a colour function - the shapes an alpha can wrap.
|
|
634
|
+
* As funções entraram com a paleta versionada (item 18): a v4 publica oklch, e sem elas
|
|
635
|
+
* `bg-emerald-500/10` resolvia a cor e PERDIA o alfa em silêncio - o scrim virava parede.
|
|
636
|
+
*/
|
|
637
|
+
const COLOUR_VALUE = /^(#[0-9a-f]{3,8}|\{color\.[^}]+\}|(?:oklch|oklab|rgba?|hsla?|lab|lch)\([^)]*\))$/i;
|
|
654
638
|
/**
|
|
655
639
|
* `#ffffff` + `50` → `color-mix(in srgb, #ffffff 50%, transparent)`.
|
|
656
640
|
*
|
|
@@ -922,6 +906,17 @@ function readUtilityCore(utility, declared) {
|
|
|
922
906
|
if (declared.has(own)) {
|
|
923
907
|
return { property: colorProp, value: refFor(rest), token: own };
|
|
924
908
|
}
|
|
909
|
+
/**
|
|
910
|
+
* A PALETA PUBLICADA DO FRAMEWORK, por versão maior e COM carimbo (item 18 + D1).
|
|
911
|
+
*
|
|
912
|
+
* Depois do token dele (o vocabulário dele sempre vence) e antes da tabela de keywords:
|
|
913
|
+
* `text-rose-700` é decisão dele sobre um valor que o Tailwind publica, e morria em silêncio
|
|
914
|
+
* - 127 valores no diagnóstico de 25/08. O `from: "framework"` é o que separa isto de
|
|
915
|
+
* inventar: a métrica sabe que não é vocabulário DELE e o self-healing pode perguntar.
|
|
916
|
+
*/
|
|
917
|
+
const published = frameworkDeclaration(colorProp, rest);
|
|
918
|
+
if (published)
|
|
919
|
+
return published;
|
|
925
920
|
const builtin = TAILWIND_COLOR[rest];
|
|
926
921
|
if (builtin)
|
|
927
922
|
return { property: colorProp, value: builtin };
|
|
@@ -31,7 +31,7 @@
|
|
|
31
31
|
* position in `layers`. They agree only if the reader inserts in the order it read.
|
|
32
32
|
*/
|
|
33
33
|
import { wearGlobal, withGlobal } from "../global-wear.js";
|
|
34
|
-
import { parseClass, transcribe } from "./transcribe.js";
|
|
34
|
+
import { parseClass, readUtility, transcribe, } from "./transcribe.js";
|
|
35
35
|
/**
|
|
36
36
|
* A Tailwind modifier, mapped to the condition it IS.
|
|
37
37
|
*
|
|
@@ -1272,11 +1272,23 @@ globals) {
|
|
|
1272
1272
|
...t.base,
|
|
1273
1273
|
...t.dark,
|
|
1274
1274
|
};
|
|
1275
|
+
/**
|
|
1276
|
+
* O HÍBRIDO DO D1, no nível da camada: `classes` é a grafia DELE, verbatim (a metade de
|
|
1277
|
+
* fidelidade - o codegen devolve o que ele escreveu); `from: "framework"` quando TODA
|
|
1278
|
+
* declaração resolvida veio da paleta publicada - numa camada mista o vocabulário dele
|
|
1279
|
+
* domina e o carimbo fica ausente, que é o caminho de sempre. Ver `framework-palette.ts`.
|
|
1280
|
+
*/
|
|
1281
|
+
const reads = bare
|
|
1282
|
+
.map((utility) => readUtility(utility, declared))
|
|
1283
|
+
.filter((d) => d != null);
|
|
1284
|
+
const fromFramework = reads.length > 0 && reads.every((d) => d.from === "framework");
|
|
1275
1285
|
return {
|
|
1276
1286
|
...(layer.when ? { when: layer.when } : {}),
|
|
1277
1287
|
...(layer.at ? { at: layer.at } : {}),
|
|
1278
1288
|
...(layer.onClasses ? { onClasses: layer.onClasses } : {}),
|
|
1279
1289
|
style,
|
|
1290
|
+
classes: layer.classes,
|
|
1291
|
+
...(fromFramework ? { from: "framework" } : {}),
|
|
1280
1292
|
};
|
|
1281
1293
|
})
|
|
1282
1294
|
.filter((layer) => Object.keys(layer.style).length > 0);
|
package/dist/install-marks.js
CHANGED
|
@@ -196,7 +196,13 @@ export const MATERIALISER_SINCE = "0.16.306";
|
|
|
196
196
|
* `var(--text-caption)` - um token de tipo numa posição de raio. Medido no repositório real: 290
|
|
197
197
|
* sugestões com a categoria trocada, 66 delas graváveis por um `--fix --write`.
|
|
198
198
|
*/
|
|
199
|
-
|
|
199
|
+
/**
|
|
200
|
+
* 0.16.250 -> 0.16.308 em 25/08: o julgamento que o hook roda passa pela paleta versionada do
|
|
201
|
+
* framework (item 18). Um hook pinado antes lê o mesmo arquivo com `text-rose-700` e conta
|
|
202
|
+
* "não lido" sobre um valor que o de hoje resolve - e o número é o que a pessoa lê para decidir
|
|
203
|
+
* se adotou. O `!` de important (0.16.306) já tinha mudado a mesma contagem.
|
|
204
|
+
*/
|
|
205
|
+
export const CHECKER_SINCE = "0.16.308";
|
|
200
206
|
/**
|
|
201
207
|
* A ÚLTIMA VERSÃO EM QUE OS LEITORES PASSARAM A PRODUZIR UM CENSO DIFERENTE.
|
|
202
208
|
*
|
|
@@ -298,7 +304,21 @@ export const CHECKER_SINCE = "0.16.250";
|
|
|
298
304
|
* Campo novo: um censo medido antes não o tem, e a tela de cobertura (D4: três colunas, estrutura
|
|
299
305
|
* visível fora da métrica) só pode ser honesta sobre quem remedir. É o que esta marca avisa.
|
|
300
306
|
*/
|
|
301
|
-
|
|
307
|
+
/**
|
|
308
|
+
* 0.16.307 -> 0.16.308 em 25/08 (mvp-1128), o lote 1 fechado + o começo do lote 2:
|
|
309
|
+
*
|
|
310
|
+
* item 13 o censo carrega `exports` - o denominador antes do portão, com o resíduo em linhas
|
|
311
|
+
* item 12 cada grupo não lido carrega `forms` - a unidade da pergunta de self-healing
|
|
312
|
+
* item 17 a camada vira o híbrido do D1: `classes` verbatim + `from` de procedência
|
|
313
|
+
* item 18 a paleta publicada do framework resolve por versão maior (v4 oklch, v3 hex), com
|
|
314
|
+
* carimbo - 127 valores (21%) deixam de morrer em silêncio
|
|
315
|
+
* item 19 o vocabulário do pacote workspace IMPORTADO pelo escopo entra na colheita (genérico,
|
|
316
|
+
* nunca node_modules; o escopo vence) - medido no repo real: @frontend-hub/ui doa 94
|
|
317
|
+
* variáveis, e os 223 valores (37%) que as vestiam passam a resolver como token DELE
|
|
318
|
+
*
|
|
319
|
+
* Um censo medido antes não tem nada disso; quem remede ganha os cinco.
|
|
320
|
+
*/
|
|
321
|
+
export const READER_SINCE = "0.16.308";
|
|
302
322
|
/**
|
|
303
323
|
* O QUE ESTÁ INSTALADO AQUI FICOU PARA TRÁS - e as DUAS condições que fazem isso ser verdade.
|
|
304
324
|
*
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
import { readFile } from "node:fs/promises";
|
|
2
|
+
import { sep } from "node:path";
|
|
3
|
+
import { walkAll } from "./commands/doctor.js";
|
|
4
|
+
import { workspacePackages } from "./doctor/components-scan.js";
|
|
5
|
+
/**
|
|
6
|
+
* O VOCABULÁRIO QUE MORA NO PACOTE AO LADO (item 19, 25/08).
|
|
7
|
+
*
|
|
8
|
+
* A regra do Tailwind v4: só `--color-*` cria utilitário de cor. Num monorepo, essas variáveis
|
|
9
|
+
* costumam morar no PACOTE de design system - e quando o escopo medido é o app, a colheita de CSS
|
|
10
|
+
* só via a pasta apontada: o app do repositório real veste `border-lightgray-200` 213 vezes, e o
|
|
11
|
+
* `--color-lightgray-200` que cria esse utilitário mora em `packages/ui/src/styles.css`, um pacote
|
|
12
|
+
* ao lado. Resultado medido: 223 valores (37% do não-lido) morriam com o nome declarado a vinte
|
|
13
|
+
* linhas de distância do alcance do leitor.
|
|
14
|
+
*
|
|
15
|
+
* A regra é GENÉRICA por decisão do dono (25/08): qualquer pacote de WORKSPACE que o escopo
|
|
16
|
+
* importa - nunca um nome cravado, e nunca `node_modules`: o CSS de terceiro de verdade continua
|
|
17
|
+
* fora e declarado (população zero medida até hoje; quando aparecer, mede-se lá).
|
|
18
|
+
*
|
|
19
|
+
* O ESCOPO DELE SEMPRE VENCE: uma variável declarada na pasta medida nunca é sobrescrita por uma
|
|
20
|
+
* do pacote irmão - quem está mais perto do componente é a decisão mais específica.
|
|
21
|
+
*/
|
|
22
|
+
/**
|
|
23
|
+
* `from "@acme/ui"` · `import("@acme/ui/x")` · `require("@acme/ui")` · `import "@acme/ui/css"` -
|
|
24
|
+
* o último é o side-effect import, e é EXATAMENTE como uma folha de tokens entra num app.
|
|
25
|
+
*/
|
|
26
|
+
const SPECIFIER = /(?:from\s*|import\s*\(?\s*|require\s*\(\s*)["']([^"'./][^"']*)["']/g;
|
|
27
|
+
const CUSTOM_PROPERTY = /(--[a-zA-Z0-9_-]+)\s*:\s*([^;}]+)/g;
|
|
28
|
+
const SKIP_DIR = /(^|[/\\])(node_modules|dist|build|\.next|\.git|coverage)([/\\]|$)/;
|
|
29
|
+
/**
|
|
30
|
+
* Colhe as custom properties dos pacotes workspace que o ESCOPO importa.
|
|
31
|
+
*
|
|
32
|
+
* O pré-passe de especificadores relê os fontes do escopo (o laço de componentes só roda DEPOIS,
|
|
33
|
+
* e é ele que consome o `declared` que esta colheita completa) - custo medido em IO de leitura
|
|
34
|
+
* pura, centenas de ms num monorepo de mil arquivos, pago uma vez por medição.
|
|
35
|
+
*/
|
|
36
|
+
export async function harvestWorkspaceCss(scopedRoot,
|
|
37
|
+
/** Nomes já declarados pelo escopo - a trava de "o escopo dele sempre vence". */
|
|
38
|
+
scopeDeclares) {
|
|
39
|
+
const imported = new Set();
|
|
40
|
+
for await (const file of walkAll([scopedRoot])) {
|
|
41
|
+
if (!/\.(tsx|jsx|ts|mjs|cjs|vue|svelte)$/i.test(file))
|
|
42
|
+
continue;
|
|
43
|
+
if (SKIP_DIR.test(file))
|
|
44
|
+
continue;
|
|
45
|
+
const source = await readFile(file, "utf8").catch(() => "");
|
|
46
|
+
SPECIFIER.lastIndex = 0;
|
|
47
|
+
for (const m of source.matchAll(SPECIFIER))
|
|
48
|
+
imported.add(m[1]);
|
|
49
|
+
}
|
|
50
|
+
if (imported.size === 0)
|
|
51
|
+
return { packages: [], declared: new Map() };
|
|
52
|
+
const declared = new Map();
|
|
53
|
+
const packages = [];
|
|
54
|
+
for (const pkg of await workspacePackages(scopedRoot)) {
|
|
55
|
+
/**
|
|
56
|
+
* IMPORTADO PELO ESCOPO - `@acme/ui` cobre `@acme/ui/tokens`. E nunca a própria pasta
|
|
57
|
+
* medida: o CSS dela já foi colhido pelo laço de sempre, e re-colher criaria a disputa
|
|
58
|
+
* que a trava abaixo existe para impedir.
|
|
59
|
+
*/
|
|
60
|
+
const used = [...imported].some((s) => s === pkg.name || s.startsWith(`${pkg.name}/`));
|
|
61
|
+
if (!used)
|
|
62
|
+
continue;
|
|
63
|
+
if (scopedRoot === pkg.dir ||
|
|
64
|
+
scopedRoot.startsWith(pkg.dir + sep) ||
|
|
65
|
+
pkg.dir.startsWith(scopedRoot + sep))
|
|
66
|
+
continue;
|
|
67
|
+
let vars = 0;
|
|
68
|
+
for await (const file of walkAll([pkg.dir])) {
|
|
69
|
+
if (!/\.(css|scss|sass|less)$/i.test(file) || SKIP_DIR.test(file))
|
|
70
|
+
continue;
|
|
71
|
+
const body = await readFile(file, "utf8").catch(() => "");
|
|
72
|
+
CUSTOM_PROPERTY.lastIndex = 0;
|
|
73
|
+
for (const m of body.matchAll(CUSTOM_PROPERTY)) {
|
|
74
|
+
if (scopeDeclares(m[1]) || declared.has(m[1]))
|
|
75
|
+
continue;
|
|
76
|
+
declared.set(m[1], m[2].trim());
|
|
77
|
+
vars += 1;
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
if (vars > 0)
|
|
81
|
+
packages.push({ name: pkg.name, vars });
|
|
82
|
+
}
|
|
83
|
+
return { packages, declared };
|
|
84
|
+
}
|
package/package.json
CHANGED