basalt-ui 1.31.0 → 1.32.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +34 -0
- package/MIGRATING.md +212 -20
- package/agent/rules/basalt-mantine.md +4 -4
- package/configs/oxlint-plugin.js +240 -59
- package/configs/oxlint-plugin.test.ts +329 -1
- package/dist/charts/kinds/BandStrip.d.ts.map +1 -1
- package/dist/charts/kinds/BandStrip.js +18 -66
- package/dist/charts/kinds/DualPanel.d.ts.map +1 -1
- package/dist/charts/kinds/DualPanel.js +5 -26
- package/dist/charts/kinds/MirroredBars.d.ts.map +1 -1
- package/dist/charts/kinds/MirroredBars.js +10 -68
- package/dist/charts/kinds/band-chrome.d.ts +31 -0
- package/dist/charts/kinds/band-chrome.d.ts.map +1 -0
- package/dist/charts/kinds/band-chrome.js +71 -0
- package/dist/charts/primitives/CartesianChart.d.ts.map +1 -1
- package/dist/charts/primitives/CartesianChart.js +49 -76
- package/dist/charts/primitives/ChartCard.d.ts.map +1 -1
- package/dist/charts/primitives/ChartCard.js +5 -23
- package/dist/charts/primitives/ChartFrame.d.ts.map +1 -1
- package/dist/charts/primitives/ChartFrame.js +23 -40
- package/dist/charts/primitives/ChartLegend.d.ts.map +1 -1
- package/dist/charts/primitives/ChartLegend.js +5 -133
- package/dist/charts/primitives/ChartTooltip.d.ts +5 -0
- package/dist/charts/primitives/ChartTooltip.d.ts.map +1 -1
- package/dist/charts/primitives/ChartTooltip.js +16 -1
- package/dist/charts/primitives/HoverOverlay.d.ts +24 -9
- package/dist/charts/primitives/HoverOverlay.d.ts.map +1 -1
- package/dist/charts/primitives/HoverOverlay.js +17 -1
- package/dist/charts/primitives/chart-card-context.d.ts +17 -13
- package/dist/charts/primitives/chart-card-context.d.ts.map +1 -1
- package/dist/charts/primitives/chart-card-context.js +10 -5
- package/dist/charts/primitives/chart-frame-layout.d.ts.map +1 -1
- package/dist/charts/primitives/chart-frame-layout.js +25 -31
- package/dist/charts/primitives/legend-disclosure.d.ts +27 -0
- package/dist/charts/primitives/legend-disclosure.d.ts.map +1 -0
- package/dist/charts/primitives/legend-disclosure.js +153 -0
- package/dist/controls/controls.module.css +5 -0
- package/dist/controls/sync-button.module.css +1 -0
- package/dist/dashboard/stat-group.module.css +19 -64
- package/dist/dashboard/widget-grid.module.css +11 -38
- package/dist/data/data-table-state.d.ts +83 -0
- package/dist/data/data-table-state.d.ts.map +1 -0
- package/dist/data/data-table-state.js +139 -0
- package/dist/data/data-table.d.ts +40 -2
- package/dist/data/data-table.d.ts.map +1 -1
- package/dist/data/data-table.js +179 -277
- package/dist/forms/form-layout.d.ts +6 -1
- package/dist/forms/form-layout.d.ts.map +1 -1
- package/dist/forms/form-layout.module.css +6 -13
- package/dist/guard/index.d.ts +2 -2
- package/dist/guard/index.d.ts.map +1 -1
- package/dist/guard/index.js +10 -14
- package/dist/notifications/center.d.ts.map +1 -1
- package/dist/provider/index.d.ts.map +1 -1
- package/dist/provider/index.js +12 -10
- package/dist/shell/aside-docking.d.ts +31 -0
- package/dist/shell/aside-docking.d.ts.map +1 -0
- package/dist/shell/aside-docking.js +19 -0
- package/dist/shell/index.d.ts +0 -11
- package/dist/shell/index.d.ts.map +1 -1
- package/dist/shell/index.js +13 -14
- package/dist/shell/page-bar.d.ts +24 -0
- package/dist/shell/page-bar.d.ts.map +1 -1
- package/dist/shell/use-breakpoint.d.ts +1 -1
- package/dist/theme/floating.module.css +1 -0
- package/dist/theme-lab/derive-controls.d.ts.map +1 -1
- package/dist/tokens/index.d.ts +2 -0
- package/dist/tokens/index.d.ts.map +1 -1
- package/dist/tokens/index.js +4 -0
- package/llms.txt +2 -2
- package/package.json +2 -1
- package/src/charts/kinds/BandStrip.tsx +18 -64
- package/src/charts/kinds/DualPanel.tsx +4 -24
- package/src/charts/kinds/MirroredBars.tsx +12 -66
- package/src/charts/kinds/band-chrome.tsx +91 -0
- package/src/charts/primitives/CartesianChart.tsx +79 -122
- package/src/charts/primitives/ChartCard.tsx +5 -27
- package/src/charts/primitives/ChartFrame.tsx +37 -76
- package/src/charts/primitives/ChartLegend.tsx +7 -154
- package/src/charts/primitives/ChartTooltip.tsx +16 -0
- package/src/charts/primitives/HoverOverlay.tsx +52 -21
- package/src/charts/primitives/chart-card-context.ts +25 -16
- package/src/charts/primitives/chart-frame-layout.ts +44 -56
- package/src/charts/primitives/legend-disclosure.tsx +177 -0
- package/src/controls/controls.module.css +5 -0
- package/src/controls/sync-button.module.css +1 -0
- package/src/dashboard/stat-group.module.css +19 -64
- package/src/dashboard/widget-grid.module.css +11 -38
- package/src/data/data-table-state.ts +218 -0
- package/src/data/data-table.tsx +134 -218
- package/src/forms/form-layout.module.css +6 -13
- package/src/forms/form-layout.tsx +6 -1
- package/src/guard/index.ts +38 -34
- package/src/notifications/center.tsx +3 -0
- package/src/provider/index.tsx +18 -17
- package/src/shell/aside-docking.ts +54 -0
- package/src/shell/index.tsx +15 -37
- package/src/shell/page-bar.tsx +24 -0
- package/src/shell/use-breakpoint.ts +2 -2
- package/src/theme/floating.module.css +1 -0
- package/src/theme-lab/derive-controls.tsx +2 -0
- package/src/tokens/index.ts +5 -0
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
* enabling every rule this file tests. `run` shells the workspace-root `node_modules/.bin/oxlint`
|
|
8
8
|
* binary and returns the parsed set of `basalt/<rule>` diagnostics it printed.
|
|
9
9
|
*/
|
|
10
|
-
import { afterEach, beforeEach, describe, expect, it } from 'bun:test'
|
|
10
|
+
import { afterEach, beforeAll, beforeEach, describe, expect, it } from 'bun:test'
|
|
11
11
|
import { mkdirSync, mkdtempSync, readFileSync, rmSync, writeFileSync } from 'node:fs'
|
|
12
12
|
import { tmpdir } from 'node:os'
|
|
13
13
|
import { dirname, resolve } from 'node:path'
|
|
@@ -19,15 +19,18 @@ import basaltPlugin, {
|
|
|
19
19
|
KNOWN_RULE_IDS,
|
|
20
20
|
PLUGIN_RULE_ADVISORY,
|
|
21
21
|
PLUGIN_RULE_GRACE,
|
|
22
|
+
RAW_BREAKPOINT_RECIPE,
|
|
22
23
|
RETIRED_RULE_IDS,
|
|
23
24
|
} from './oxlint-plugin.js'
|
|
24
25
|
import { CTL_THEME } from '../src/theme/ctl-theme'
|
|
25
26
|
import {
|
|
27
|
+
GRACE_PERIOD_KINDS,
|
|
26
28
|
GUARD_RULES,
|
|
27
29
|
PLUGIN_RULE_IDS,
|
|
28
30
|
WAIVER_ID_ALIASES as GUARD_WAIVER_ID_ALIASES,
|
|
29
31
|
} from '../src/guard/index.ts'
|
|
30
32
|
import { PLUGIN_RULE_ID_LIST, SURFACES } from '../src/surfaces.ts'
|
|
33
|
+
import { CONTAINER_CLASSES } from '../src/tokens/size-classes.ts'
|
|
31
34
|
|
|
32
35
|
const PLUGIN_PATH = resolve(import.meta.dirname, 'oxlint-plugin.js')
|
|
33
36
|
const OXLINT_BIN = resolve(import.meta.dirname, '..', '..', '..', 'node_modules', '.bin', 'oxlint')
|
|
@@ -97,12 +100,37 @@ function run(
|
|
|
97
100
|
writeFileSync(filePath, source)
|
|
98
101
|
const result = Bun.spawnSync([OXLINT_BIN, '-c', '.oxlintrc.json', filename], { cwd: dir })
|
|
99
102
|
const output = `${result.stdout}${result.stderr}`
|
|
103
|
+
// A plugin that fails to load must fail the run, not read as "no findings" — otherwise every
|
|
104
|
+
// `not.toContain` below is false-green.
|
|
105
|
+
if (/Failed to (?:load JS plugin|parse oxlint configuration)/.test(output))
|
|
106
|
+
throw new Error(`oxlint could not load the basalt plugin:\n${output}`)
|
|
100
107
|
const rules = new Set(
|
|
101
108
|
[...output.matchAll(/\(basalt\/([\w-]+)\)/g)].map((match) => match[1] as string),
|
|
102
109
|
)
|
|
103
110
|
return { code: result.exitCode ?? 0, rules, output }
|
|
104
111
|
}
|
|
105
112
|
|
|
113
|
+
// The sentinel: one fixture every working plugin reports. If it does not, the plugin is not loaded
|
|
114
|
+
// (or not registered under `basalt/`) and nothing else in this file means anything.
|
|
115
|
+
beforeAll(() => {
|
|
116
|
+
const sentinelDir = mkdtempSync(resolve(tmpdir(), 'basalt-oxlint-sentinel-'))
|
|
117
|
+
try {
|
|
118
|
+
writeFileSync(
|
|
119
|
+
resolve(sentinelDir, '.oxlintrc.json'),
|
|
120
|
+
JSON.stringify({ jsPlugins: [PLUGIN_PATH], rules: { 'basalt/no-raw-font-size': 'error' } }),
|
|
121
|
+
)
|
|
122
|
+
writeFileSync(resolve(sentinelDir, 'sentinel.tsx'), 'export const C = () => <Text fz={10} />\n')
|
|
123
|
+
const result = Bun.spawnSync([OXLINT_BIN, '-c', '.oxlintrc.json', 'sentinel.tsx'], {
|
|
124
|
+
cwd: sentinelDir,
|
|
125
|
+
})
|
|
126
|
+
const output = `${result.stdout}${result.stderr}`
|
|
127
|
+
if (!output.includes('(basalt/no-raw-font-size)'))
|
|
128
|
+
throw new Error(`basalt oxlint plugin did not load — sentinel rule never fired:\n${output}`)
|
|
129
|
+
} finally {
|
|
130
|
+
rmSync(sentinelDir, { recursive: true, force: true })
|
|
131
|
+
}
|
|
132
|
+
})
|
|
133
|
+
|
|
106
134
|
// ── no-raw-font-size ─────────────────────────────────────────────────────────
|
|
107
135
|
|
|
108
136
|
describe('basalt/no-raw-font-size', () => {
|
|
@@ -1332,6 +1360,42 @@ describe('assertGraceLedger', () => {
|
|
|
1332
1360
|
})
|
|
1333
1361
|
})
|
|
1334
1362
|
|
|
1363
|
+
// ── twin lanes: one law, two lanes, one promotion ─────────────────────────────
|
|
1364
|
+
// A guard kind and a plugin rule that enforce ONE law in two lanes (CSS/text vs. JSX AST) must
|
|
1365
|
+
// promote together — a consumer failing one spelling and warned on the other is the confusion the
|
|
1366
|
+
// pairing exists to prevent. `raw-media-query` split from `basalt/raw-breakpoint` exactly that way
|
|
1367
|
+
// (1.32.0 vs 1.33.0). Twins are DERIVED, not hand-listed, from the two places they are declared: a
|
|
1368
|
+
// `WAIVER_ID_ALIASES` pair, and a guard entry whose `why` calls itself the twin of `basalt/<id>`.
|
|
1369
|
+
|
|
1370
|
+
const pluginGrace = PLUGIN_RULE_GRACE as Record<string, GraceEntry>
|
|
1371
|
+
const guardGrace = GRACE_PERIOD_KINDS as Record<string, GraceEntry>
|
|
1372
|
+
|
|
1373
|
+
function twinLanes(): Array<[kind: string, rule: string]> {
|
|
1374
|
+
const pairs = new Map<string, string>()
|
|
1375
|
+
for (const [kind, aliases] of Object.entries(WAIVER_ID_ALIASES)) {
|
|
1376
|
+
for (const rule of aliases) if (kind in guardGrace || rule in pluginGrace) pairs.set(kind, rule)
|
|
1377
|
+
}
|
|
1378
|
+
for (const [kind, entry] of Object.entries(guardGrace)) {
|
|
1379
|
+
const match = /twin of the oxlint plugin's `basalt\/([a-z-]+)`/.exec(entry.why)
|
|
1380
|
+
if (match?.[1] !== undefined) pairs.set(kind, match[1])
|
|
1381
|
+
}
|
|
1382
|
+
return [...pairs].filter(([kind]) => kind in guardGrace)
|
|
1383
|
+
}
|
|
1384
|
+
|
|
1385
|
+
describe('twin lanes share one promotion', () => {
|
|
1386
|
+
it('derives the raw-media-query ↔ raw-breakpoint pair (the derivation is not silently empty)', () => {
|
|
1387
|
+
expect(twinLanes()).toContainEqual(['raw-media-query', 'raw-breakpoint'])
|
|
1388
|
+
})
|
|
1389
|
+
|
|
1390
|
+
it.each(twinLanes())('%s and basalt/%s are both in grace with the same promote', (kind, rule) => {
|
|
1391
|
+
expect([kind, rule, guardGrace[kind]?.promote]).toEqual([
|
|
1392
|
+
kind,
|
|
1393
|
+
rule,
|
|
1394
|
+
pluginGrace[rule]?.promote,
|
|
1395
|
+
])
|
|
1396
|
+
})
|
|
1397
|
+
})
|
|
1398
|
+
|
|
1335
1399
|
describe('PLUGIN_RULE_GRACE', () => {
|
|
1336
1400
|
const shipped = JSON.parse(readFileSync(resolve(import.meta.dirname, 'oxlint.json'), 'utf8')) as {
|
|
1337
1401
|
rules: Record<string, unknown>
|
|
@@ -3467,6 +3531,149 @@ describe('basalt/raw-breakpoint', () => {
|
|
|
3467
3531
|
expect(rules).not.toContain('raw-breakpoint')
|
|
3468
3532
|
})
|
|
3469
3533
|
|
|
3534
|
+
// The recipe's px keys are CONTAINER_CLASSES written out by hand in two places — the plugin
|
|
3535
|
+
// (plain JS, cannot import TS source) and MIGRATING's rule entry. Retuning a class must fail here.
|
|
3536
|
+
describe('recipe px literals ↔ CONTAINER_CLASSES', () => {
|
|
3537
|
+
const boundaries = new Set<number>(Object.values(CONTAINER_CLASSES).filter((px) => px > 0))
|
|
3538
|
+
const pxLiterals = (text: string) => [...text.matchAll(/(\d+)px/g)].map((m) => Number(m[1]))
|
|
3539
|
+
|
|
3540
|
+
it('every px key in the rule messages is a CONTAINER_CLASSES boundary', () => {
|
|
3541
|
+
const found = pxLiterals(RAW_BREAKPOINT_RECIPE as string)
|
|
3542
|
+
expect(found.length).toBeGreaterThan(0)
|
|
3543
|
+
for (const px of found) expect([px, boundaries.has(px)]).toEqual([px, true])
|
|
3544
|
+
})
|
|
3545
|
+
|
|
3546
|
+
it("every px value and the class table in MIGRATING's raw-breakpoint entry match", () => {
|
|
3547
|
+
const migrating = readFileSync(resolve(import.meta.dir, '../MIGRATING.md'), 'utf8')
|
|
3548
|
+
const start = migrating.indexOf('### `basalt/raw-breakpoint`')
|
|
3549
|
+
expect(start).toBeGreaterThan(-1)
|
|
3550
|
+
const end = migrating.indexOf('\n### ', start + 1)
|
|
3551
|
+
const section = migrating.slice(start, end === -1 ? undefined : end)
|
|
3552
|
+
for (const px of pxLiterals(section)) expect([px, boundaries.has(px)]).toEqual([px, true])
|
|
3553
|
+
const { compact, regular, wide } = CONTAINER_CLASSES
|
|
3554
|
+
expect(section).toContain(`compact ${compact} · regular ${regular} · wide ${wide}`)
|
|
3555
|
+
})
|
|
3556
|
+
})
|
|
3557
|
+
|
|
3558
|
+
// The sanctioned answer, read from @mantine/core 9.3 source: SimpleGrid type="container" writes
|
|
3559
|
+
// each key verbatim as `@container simple-grid (min-width: <key>)`, Grid type="container" only
|
|
3560
|
+
// goes container WITH a `breakpoints` map. Exempt exactly where Mantine resolves the object.
|
|
3561
|
+
describe('Mantine type="container" grids', () => {
|
|
3562
|
+
const grid = (jsx: string) =>
|
|
3563
|
+
run(`import { Grid, SimpleGrid } from '@mantine/core'\nexport const C = () => ${jsx}\n`)
|
|
3564
|
+
const CONTAINER_MESSAGE = /Theme breakpoint name under type="container"/
|
|
3565
|
+
|
|
3566
|
+
it('does NOT flag a px-keyed container SimpleGrid (the recipe)', () => {
|
|
3567
|
+
expect(
|
|
3568
|
+
grid(`<SimpleGrid type="container" cols={{ base: 1, '480px': 2, '800px': 3 }} />`).rules,
|
|
3569
|
+
).not.toContain('raw-breakpoint')
|
|
3570
|
+
})
|
|
3571
|
+
|
|
3572
|
+
it('does NOT flag a lone `base` under type="container"', () => {
|
|
3573
|
+
expect(grid(`<SimpleGrid type="container" cols={{ base: 2 }} />`).rules).not.toContain(
|
|
3574
|
+
'raw-breakpoint',
|
|
3575
|
+
)
|
|
3576
|
+
})
|
|
3577
|
+
|
|
3578
|
+
it('flags a theme-named key on a container SimpleGrid — Mantine emits a dead (min-width: sm)', () => {
|
|
3579
|
+
const { rules, output } = grid(`<SimpleGrid type="container" cols={{ base: 1, sm: 2 }} />`)
|
|
3580
|
+
expect(rules).toContain('raw-breakpoint')
|
|
3581
|
+
expect(CONTAINER_MESSAGE.test(output)).toBe(true)
|
|
3582
|
+
})
|
|
3583
|
+
|
|
3584
|
+
it('still flags type="media" (and a dynamic type) with the viewport message', () => {
|
|
3585
|
+
for (const type of [`"media"`, `{kind}`]) {
|
|
3586
|
+
const { rules, output } = grid(`<SimpleGrid type=${type} cols={{ base: 1, sm: 2 }} />`)
|
|
3587
|
+
expect(rules).toContain('raw-breakpoint')
|
|
3588
|
+
expect(CONTAINER_MESSAGE.test(output)).toBe(false)
|
|
3589
|
+
}
|
|
3590
|
+
})
|
|
3591
|
+
|
|
3592
|
+
it('does NOT flag Grid.Col spans under a container Grid with a breakpoints map', () => {
|
|
3593
|
+
const src =
|
|
3594
|
+
`<Grid type="container" breakpoints={{ xs: '240px', sm: '480px' }}>\n` +
|
|
3595
|
+
` {items.map((i) => <Grid.Col key={i} span={{ base: 12, sm: 6 }}>x</Grid.Col>)}\n` +
|
|
3596
|
+
`</Grid>`
|
|
3597
|
+
expect(grid(src).rules).not.toContain('raw-breakpoint')
|
|
3598
|
+
})
|
|
3599
|
+
|
|
3600
|
+
it('flags Grid.Col spans under a container Grid with NO breakpoints — Mantine falls back to media', () => {
|
|
3601
|
+
const { rules, output } = grid(
|
|
3602
|
+
`<Grid type="container"><Grid.Col span={{ base: 12, sm: 6 }}>x</Grid.Col></Grid>`,
|
|
3603
|
+
)
|
|
3604
|
+
expect(rules).toContain('raw-breakpoint')
|
|
3605
|
+
expect(CONTAINER_MESSAGE.test(output)).toBe(true)
|
|
3606
|
+
})
|
|
3607
|
+
|
|
3608
|
+
it('reports a const-extracted theme-keyed object on a container SimpleGrid — still a dead query', () => {
|
|
3609
|
+
const { rules, output } = run(
|
|
3610
|
+
`import { SimpleGrid } from '@mantine/core'\n` +
|
|
3611
|
+
`const cols = { base: 1, sm: 2 }\n` +
|
|
3612
|
+
`export const C = () => <SimpleGrid type="container" cols={cols} />\n`,
|
|
3613
|
+
)
|
|
3614
|
+
expect(rules).toContain('raw-breakpoint')
|
|
3615
|
+
expect(CONTAINER_MESSAGE.test(output)).toBe(true)
|
|
3616
|
+
})
|
|
3617
|
+
|
|
3618
|
+
// Grid goes container only on a truthy map, and an empty one emits no query — so the exemption
|
|
3619
|
+
// needs a map that statically resolves to a non-empty object, not the attribute's presence.
|
|
3620
|
+
it.each([
|
|
3621
|
+
['undefined', `breakpoints={undefined}`, ''],
|
|
3622
|
+
['an empty object', `breakpoints={{}}`, ''],
|
|
3623
|
+
['an unresolvable identifier', `breakpoints={imported}`, `import { imported } from './bp'\n`],
|
|
3624
|
+
])('flags Grid.Col spans under a container Grid whose breakpoints is %s', (_, bp, extra) => {
|
|
3625
|
+
const { rules, output } = run(
|
|
3626
|
+
`import { Grid } from '@mantine/core'\n${extra}` +
|
|
3627
|
+
`export const C = () => <Grid type="container" ${bp}><Grid.Col span={{ base: 12, sm: 6 }}>x</Grid.Col></Grid>\n`,
|
|
3628
|
+
)
|
|
3629
|
+
expect(rules).toContain('raw-breakpoint')
|
|
3630
|
+
expect(CONTAINER_MESSAGE.test(output)).toBe(true)
|
|
3631
|
+
})
|
|
3632
|
+
|
|
3633
|
+
it('does NOT flag Grid.Col spans under a container Grid whose breakpoints is a same-file const', () => {
|
|
3634
|
+
const { rules } = run(
|
|
3635
|
+
`import { Grid } from '@mantine/core'\n` +
|
|
3636
|
+
`const bp = { xs: '240px', sm: '480px', md: '800px', lg: '800px', xl: '800px' }\n` +
|
|
3637
|
+
`export const C = () => <Grid type="container" breakpoints={bp}><Grid.Col span={{ base: 12, sm: 6 }}>x</Grid.Col></Grid>\n`,
|
|
3638
|
+
)
|
|
3639
|
+
expect(rules).not.toContain('raw-breakpoint')
|
|
3640
|
+
})
|
|
3641
|
+
|
|
3642
|
+
// Only the grid-keyed props route through the container queries; Box style props on the same
|
|
3643
|
+
// element still compile to viewport @media, so they keep the ordinary viewport message.
|
|
3644
|
+
it.each([
|
|
3645
|
+
[
|
|
3646
|
+
'SimpleGrid p',
|
|
3647
|
+
`<SimpleGrid type="container" cols={{ base: 1, '480px': 2 }} p={{ base: 'xs', lg: 'md' }} />`,
|
|
3648
|
+
],
|
|
3649
|
+
[
|
|
3650
|
+
'Grid mt',
|
|
3651
|
+
`<Grid type="container" breakpoints={{ xs: '240px', sm: '480px', md: '800px', lg: '800px', xl: '800px' }} mt={{ base: 0, sm: 'md' }}>x</Grid>`,
|
|
3652
|
+
],
|
|
3653
|
+
[
|
|
3654
|
+
'Grid.Col mih',
|
|
3655
|
+
`<Grid type="container" breakpoints={{ xs: '240px', sm: '480px', md: '800px', lg: '800px', xl: '800px' }}><Grid.Col span={6} mih={{ base: 80, lg: 120 }}>x</Grid.Col></Grid>`,
|
|
3656
|
+
],
|
|
3657
|
+
])('flags a Box style prop on a container grid as viewport (%s)', (_, jsx) => {
|
|
3658
|
+
const { rules, output } = grid(jsx)
|
|
3659
|
+
expect(rules).toContain('raw-breakpoint')
|
|
3660
|
+
expect(CONTAINER_MESSAGE.test(output)).toBe(false)
|
|
3661
|
+
})
|
|
3662
|
+
|
|
3663
|
+
it('does NOT flag container-routed spacing props on a container grid', () => {
|
|
3664
|
+
const src =
|
|
3665
|
+
`<Grid type="container" breakpoints={{ xs: '240px', sm: '480px', md: '800px', lg: '800px', xl: '800px' }} gap={{ base: 'xs', sm: 'md' }}>` +
|
|
3666
|
+
`<Grid.Col span={{ base: 12, sm: 6 }} order={{ base: 2, sm: 1 }}>x</Grid.Col></Grid>`
|
|
3667
|
+
expect(grid(src).rules).not.toContain('raw-breakpoint')
|
|
3668
|
+
})
|
|
3669
|
+
|
|
3670
|
+
it('still flags Grid.Col spans under an ordinary Grid', () => {
|
|
3671
|
+
expect(
|
|
3672
|
+
grid(`<Grid><Grid.Col span={{ base: 12, sm: 6 }}>x</Grid.Col></Grid>`).rules,
|
|
3673
|
+
).toContain('raw-breakpoint')
|
|
3674
|
+
})
|
|
3675
|
+
})
|
|
3676
|
+
|
|
3470
3677
|
it('flags visibleFrom/hiddenFrom outside a shell home', () => {
|
|
3471
3678
|
const { rules } = run(
|
|
3472
3679
|
`import { Box } from '@mantine/core'\n` +
|
|
@@ -3541,6 +3748,127 @@ describe('basalt/raw-breakpoint', () => {
|
|
|
3541
3748
|
)
|
|
3542
3749
|
expect(rules).not.toContain('raw-breakpoint')
|
|
3543
3750
|
})
|
|
3751
|
+
|
|
3752
|
+
// rb r2 #11: the object sat inside a conditional, so the rule never saw it.
|
|
3753
|
+
it('flags a responsive object inside a conditional prop value (Grid.Col, no container)', () => {
|
|
3754
|
+
const { rules } = run(
|
|
3755
|
+
`import { Grid } from '@mantine/core'\n` +
|
|
3756
|
+
`export const C = ({ wide }: { wide: boolean }) => (\n` +
|
|
3757
|
+
` <Grid><Grid.Col span={wide ? { base: 12, md: 4 } : 12}>x</Grid.Col></Grid>\n)\n`,
|
|
3758
|
+
)
|
|
3759
|
+
expect(rules).toContain('raw-breakpoint')
|
|
3760
|
+
})
|
|
3761
|
+
|
|
3762
|
+
// Review r1: the unwrap ran before const resolution, so hoisting the conditional bypassed it.
|
|
3763
|
+
it('flags a conditional responsive object behind a same-file const', () => {
|
|
3764
|
+
const { rules } = run(
|
|
3765
|
+
`import { Grid } from '@mantine/core'\n` +
|
|
3766
|
+
`export const C = ({ wide }: { wide: boolean }) => {\n` +
|
|
3767
|
+
` const span = wide ? { base: 12, md: 4 } : 12\n` +
|
|
3768
|
+
` return <Grid><Grid.Col span={span}>x</Grid.Col></Grid>\n}\n`,
|
|
3769
|
+
)
|
|
3770
|
+
expect(rules).toContain('raw-breakpoint')
|
|
3771
|
+
})
|
|
3772
|
+
|
|
3773
|
+
it('flags through a const alias chain and survives an alias cycle', () => {
|
|
3774
|
+
const chained = run(
|
|
3775
|
+
`import { SimpleGrid } from '@mantine/core'\n` +
|
|
3776
|
+
`const base = { base: 1, sm: 2 }\nconst cols = base\n` +
|
|
3777
|
+
`export const C = () => <SimpleGrid cols={cols} />\n`,
|
|
3778
|
+
)
|
|
3779
|
+
expect(chained.rules).toContain('raw-breakpoint')
|
|
3780
|
+
const cyclic = run(
|
|
3781
|
+
`import { SimpleGrid } from '@mantine/core'\n` +
|
|
3782
|
+
`const a = b\nconst b = a\n` +
|
|
3783
|
+
`export const C = () => <SimpleGrid cols={a} />\n`,
|
|
3784
|
+
)
|
|
3785
|
+
expect(cyclic.rules).not.toContain('raw-breakpoint')
|
|
3786
|
+
})
|
|
3787
|
+
|
|
3788
|
+
it('flags a responsive object on either side of a logical prop value', () => {
|
|
3789
|
+
const { rules } = run(
|
|
3790
|
+
`import { SimpleGrid } from '@mantine/core'\n` +
|
|
3791
|
+
`export const C = ({ c }: { c?: number }) => <SimpleGrid cols={c ?? { base: 1, sm: 2 }} />\n`,
|
|
3792
|
+
)
|
|
3793
|
+
expect(rules).toContain('raw-breakpoint')
|
|
3794
|
+
})
|
|
3795
|
+
|
|
3796
|
+
// rb r2 #13: a base-only object is no breakpoint at all — the message says to write the value.
|
|
3797
|
+
it('tells a base-only responsive object to write the bare value', () => {
|
|
3798
|
+
const { rules, output } = run(
|
|
3799
|
+
`import { SimpleGrid } from '@mantine/core'\n` +
|
|
3800
|
+
`export const C = () => <SimpleGrid cols={{ base: 3 }} />\n`,
|
|
3801
|
+
)
|
|
3802
|
+
expect(rules).toContain('raw-breakpoint')
|
|
3803
|
+
expect(output).toContain('cols={3}')
|
|
3804
|
+
expect(output).not.toContain('keyed on theme breakpoints')
|
|
3805
|
+
})
|
|
3806
|
+
|
|
3807
|
+
it('gives the base-only message through a const-bound conditional too', () => {
|
|
3808
|
+
const { output } = run(
|
|
3809
|
+
`import { SimpleGrid } from '@mantine/core'\n` +
|
|
3810
|
+
`export const C = ({ d }: { d: boolean }) => {\n` +
|
|
3811
|
+
` const cols = d ? { base: 3 } : 2\n return <SimpleGrid cols={cols} />\n}\n`,
|
|
3812
|
+
)
|
|
3813
|
+
expect(output).toContain('cols={3}')
|
|
3814
|
+
expect(output).not.toContain('keyed on theme breakpoints')
|
|
3815
|
+
})
|
|
3816
|
+
|
|
3817
|
+
it('keeps the viewport message when any branch carries a real breakpoint', () => {
|
|
3818
|
+
const { output } = run(
|
|
3819
|
+
`import { SimpleGrid } from '@mantine/core'\n` +
|
|
3820
|
+
`export const C = ({ d }: { d: boolean }) => <SimpleGrid cols={d ? { base: 3 } : { base: 1, sm: 2 }} />\n`,
|
|
3821
|
+
)
|
|
3822
|
+
expect(output).toContain('keyed on theme breakpoints')
|
|
3823
|
+
})
|
|
3824
|
+
|
|
3825
|
+
// rb r2 #5.
|
|
3826
|
+
it('points a useMediaQuery read at the (pointer: coarse) CSS home', () => {
|
|
3827
|
+
const { output } = run(
|
|
3828
|
+
`import { useMediaQuery } from '@mantine/hooks'\n` +
|
|
3829
|
+
`export const useTouch = () => useMediaQuery('(hover: none)')\n`,
|
|
3830
|
+
)
|
|
3831
|
+
expect(output).toContain('@media (pointer: coarse)')
|
|
3832
|
+
})
|
|
3833
|
+
|
|
3834
|
+
// obsidian r2 #7: a test-setup polyfill lives in `tests/`, not in a `.test` file.
|
|
3835
|
+
it.each(['tests/setup/dom.ts', 'test/setup.ts', 'src/__tests__/setup.ts'])(
|
|
3836
|
+
'does NOT flag a matchMedia stub under %s',
|
|
3837
|
+
(filename) => {
|
|
3838
|
+
const { rules } = run(`window.matchMedia = () => ({ matches: false })\n`, filename)
|
|
3839
|
+
expect(rules).not.toContain('raw-breakpoint')
|
|
3840
|
+
},
|
|
3841
|
+
)
|
|
3842
|
+
|
|
3843
|
+
it('still flags a file whose name merely contains "test" outside a test dir', () => {
|
|
3844
|
+
const { rules } = run(`const mq = window.matchMedia('(max-width: 600px)')\n`, 'src/latest/a.ts')
|
|
3845
|
+
expect(rules).toContain('raw-breakpoint')
|
|
3846
|
+
})
|
|
3847
|
+
})
|
|
3848
|
+
|
|
3849
|
+
// ── control homes: text lane ≡ plugin ────────────────────────────────────────
|
|
3850
|
+
|
|
3851
|
+
// 1.32.1 (B2): the plugin homed FormRow/FormGroup while check-theme's `raw-selection-control` did
|
|
3852
|
+
// not, so a correctly migrated form reported in one lane only. Both lists are module-private (the
|
|
3853
|
+
// guard is dependency-free, the plugin cannot import TS), so this reads them out of the source.
|
|
3854
|
+
describe('control homes — lane parity', () => {
|
|
3855
|
+
const pluginSource = readFileSync(PLUGIN_PATH, 'utf8')
|
|
3856
|
+
const guardSource = readFileSync(resolve(import.meta.dirname, '../src/guard/index.ts'), 'utf8')
|
|
3857
|
+
|
|
3858
|
+
const pluginSet = (name: string): string[] => {
|
|
3859
|
+
const body = pluginSource.match(new RegExp(`const ${name} = new Set\\(\\[([^\\]]*)\\]`))?.[1]
|
|
3860
|
+
if (body === undefined) throw new Error(`${name} not found in oxlint-plugin.js`)
|
|
3861
|
+
return [...body.matchAll(/'([^']+)'/g)].map((m) => m[1] as string)
|
|
3862
|
+
}
|
|
3863
|
+
|
|
3864
|
+
it('check-theme CONTROL_HOST_TAG names exactly CONTROL_HOST_TAGS ∪ BASALT_HOST_TAGS', () => {
|
|
3865
|
+
const alternation = guardSource.match(/const CONTROL_HOST_TAG =\s*\/<\(\?:([^)]*)\)/)?.[1]
|
|
3866
|
+
if (alternation === undefined) throw new Error('CONTROL_HOST_TAG not found in guard/index.ts')
|
|
3867
|
+
const textLane = alternation.split('|').map((tag) => tag.replaceAll('\\.', '.'))
|
|
3868
|
+
const pluginLane = [...pluginSet('CONTROL_HOST_TAGS'), ...pluginSet('BASALT_HOST_TAGS')]
|
|
3869
|
+
expect(pluginLane).toContain('FormRow')
|
|
3870
|
+
expect(textLane.toSorted()).toEqual(pluginLane.toSorted())
|
|
3871
|
+
})
|
|
3544
3872
|
})
|
|
3545
3873
|
|
|
3546
3874
|
// ── the deprecation ledger (B4) ──────────────────────────────────────────────
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"BandStrip.d.ts","sourceRoot":"","sources":["../../../src/charts/kinds/BandStrip.tsx"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAA;AAErD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,cAAc,CAAA;AAC/C,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAA;AAEzD,OAAO,KAAK,EAAE,QAAQ,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAA;
|
|
1
|
+
{"version":3,"file":"BandStrip.d.ts","sourceRoot":"","sources":["../../../src/charts/kinds/BandStrip.tsx"],"names":[],"mappings":"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"}
|
|
@@ -4,18 +4,12 @@ import { memo, useMemo } from "react";
|
|
|
4
4
|
import { assertRequiredProps } from "../../common/validate.js";
|
|
5
5
|
import { VX, alpha } from "../../tokens/index.js";
|
|
6
6
|
import { useBandPlot } from "../hooks/useBandPlot.js";
|
|
7
|
-
import { AxisBottomDate } from "../primitives/Axes.js";
|
|
8
7
|
import { ChartFrame, resolveLegend } from "../primitives/ChartFrame.js";
|
|
9
|
-
import {
|
|
10
|
-
ChartTooltipFloat,
|
|
11
|
-
TooltipBody,
|
|
12
|
-
TooltipHeader,
|
|
13
|
-
TooltipRow
|
|
14
|
-
} from "../primitives/ChartTooltip.js";
|
|
8
|
+
import { TooltipRow } from "../primitives/ChartTooltip.js";
|
|
15
9
|
import { Crosshair } from "../primitives/Crosshair.js";
|
|
16
10
|
import { HatchPattern, hatchFill, hatchSizeFor } from "../primitives/HatchPattern.js";
|
|
17
|
-
import { HoverOverlay } from "../primitives/HoverOverlay.js";
|
|
18
11
|
import { fmtAxisDate } from "../utils/format.js";
|
|
12
|
+
import { BandAxisOverlay, BandTooltip, clampFraction } from "./band-chrome.js";
|
|
19
13
|
import { isDev } from "../../common/is-dev.js";
|
|
20
14
|
const DEFAULT_MARKER_INSET = 6;
|
|
21
15
|
const NO_READING = "\u2014";
|
|
@@ -85,7 +79,7 @@ function BandStripPlot(props) {
|
|
|
85
79
|
...marginOverride !== void 0 && { margin: marginOverride },
|
|
86
80
|
...tooltip !== void 0 && { tooltip }
|
|
87
81
|
});
|
|
88
|
-
const { bands, margin, plotWidth,
|
|
82
|
+
const { bands, margin, plotWidth, point, crosshairX, step, bandWidth } = band;
|
|
89
83
|
const stripHeight = Math.max(plot.height - margin.top - margin.bottom, 1);
|
|
90
84
|
const hatchId = `${chartId}-band-absent`;
|
|
91
85
|
if (absentState !== void 0 && !styleByKey.has(absentState)) {
|
|
@@ -171,8 +165,6 @@ function BandStripPlot(props) {
|
|
|
171
165
|
return out;
|
|
172
166
|
}, [bands, getBand, getX, styleByKey, hidden, bandWidth, step, stripHeight, hatchId, absentState]);
|
|
173
167
|
if (plotWidth <= 0 || bands.length === 0) return null;
|
|
174
|
-
const cfg = tooltip === false ? void 0 : tooltip;
|
|
175
|
-
const badge = cfg?.label === void 0 || point === null ? null : cfg.label(point);
|
|
176
168
|
const row = point === null ? null : deriveBandRow(getBand(point), styleByKey, hidden, point);
|
|
177
169
|
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
178
170
|
/* @__PURE__ */ jsxs(
|
|
@@ -196,71 +188,31 @@ function BandStripPlot(props) {
|
|
|
196
188
|
rects,
|
|
197
189
|
crosshairX !== null && /* @__PURE__ */ jsx(Crosshair, { x: crosshairX, top: 0, bottom: stripHeight }),
|
|
198
190
|
/* @__PURE__ */ jsx(
|
|
199
|
-
|
|
191
|
+
BandAxisOverlay,
|
|
200
192
|
{
|
|
201
|
-
|
|
202
|
-
scale,
|
|
203
|
-
tickValues: band.tickValues,
|
|
204
|
-
tickFormat: (v) => formatX(String(v)),
|
|
205
|
-
anchorTerminals: band.xAnchorTerminals,
|
|
206
|
-
...band.xWrapWidth !== void 0 && { wrapWidth: band.xWrapWidth }
|
|
207
|
-
}
|
|
208
|
-
),
|
|
209
|
-
/* @__PURE__ */ jsx(
|
|
210
|
-
HoverOverlay,
|
|
211
|
-
{
|
|
212
|
-
width: plotWidth,
|
|
193
|
+
band,
|
|
213
194
|
height: stripHeight,
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
onLeave: cursor.onPointerLeave,
|
|
218
|
-
onKeyDown: cursor.onKeyDown,
|
|
219
|
-
onBlur: cursor.onBlur,
|
|
220
|
-
valueMax: Math.max(bands.length - 1, 0),
|
|
221
|
-
...point !== null && {
|
|
222
|
-
valueNow: bands.indexOf(point),
|
|
223
|
-
valueText: formatX(getX(point))
|
|
224
|
-
},
|
|
225
|
-
...ariaLabel !== void 0 && { ariaLabel }
|
|
195
|
+
getX,
|
|
196
|
+
formatX,
|
|
197
|
+
ariaLabel
|
|
226
198
|
}
|
|
227
199
|
)
|
|
228
200
|
] })
|
|
229
201
|
]
|
|
230
202
|
}
|
|
231
203
|
),
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
),
|
|
243
|
-
/* @__PURE__ */ jsxs(TooltipBody, { children: [
|
|
244
|
-
cfg?.prependRows?.(point, { hidden }),
|
|
245
|
-
row !== null && /* @__PURE__ */ jsx(
|
|
246
|
-
TooltipRow,
|
|
247
|
-
{
|
|
248
|
-
color: row.color,
|
|
249
|
-
label: row.label,
|
|
250
|
-
value: row.value,
|
|
251
|
-
shape: row.shape,
|
|
252
|
-
dashed: row.dashed
|
|
253
|
-
}
|
|
254
|
-
),
|
|
255
|
-
cfg?.extraRows?.(point, { hidden })
|
|
256
|
-
] })
|
|
257
|
-
] })
|
|
204
|
+
/* @__PURE__ */ jsx(BandTooltip, { band, tooltip, getX, hidden, children: row !== null && /* @__PURE__ */ jsx(
|
|
205
|
+
TooltipRow,
|
|
206
|
+
{
|
|
207
|
+
color: row.color,
|
|
208
|
+
label: row.label,
|
|
209
|
+
value: row.value,
|
|
210
|
+
shape: row.shape,
|
|
211
|
+
dashed: row.dashed
|
|
212
|
+
}
|
|
213
|
+
) })
|
|
258
214
|
] });
|
|
259
215
|
}
|
|
260
|
-
function clampFraction(value) {
|
|
261
|
-
if (value === void 0 || !Number.isFinite(value)) return 0;
|
|
262
|
-
return Math.min(Math.max(value, 0), 1);
|
|
263
|
-
}
|
|
264
216
|
function deriveBandRow(span, styleByKey, hidden, datum) {
|
|
265
217
|
const style = styleByKey.get(span.state);
|
|
266
218
|
if (style === void 0) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"DualPanel.d.ts","sourceRoot":"","sources":["../../../src/charts/kinds/DualPanel.tsx"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAA;
|
|
1
|
+
{"version":3,"file":"DualPanel.d.ts","sourceRoot":"","sources":["../../../src/charts/kinds/DualPanel.tsx"],"names":[],"mappings":"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"}
|
|
@@ -11,11 +11,12 @@ import {
|
|
|
11
11
|
ChartTooltipFloat,
|
|
12
12
|
TooltipBody,
|
|
13
13
|
TooltipHeader,
|
|
14
|
-
TooltipRow
|
|
14
|
+
TooltipRow,
|
|
15
|
+
TooltipRows
|
|
15
16
|
} from "../primitives/ChartTooltip.js";
|
|
16
17
|
import { ChartFrame, resolveLegend } from "../primitives/ChartFrame.js";
|
|
17
18
|
import { Crosshair, SeriesDot } from "../primitives/Crosshair.js";
|
|
18
|
-
import { HoverOverlay } from "../primitives/HoverOverlay.js";
|
|
19
|
+
import { cursorSliderProps, HoverOverlay } from "../primitives/HoverOverlay.js";
|
|
19
20
|
import { ZoneRects } from "../primitives/ZoneRects.js";
|
|
20
21
|
import { useChartCursor } from "../hooks/useChartCursor.js";
|
|
21
22
|
import { autoMargin, probeAxisLabels } from "../layout/auto-margin.js";
|
|
@@ -365,18 +366,7 @@ function DualPanelPlot(props) {
|
|
|
365
366
|
{
|
|
366
367
|
width: xMax,
|
|
367
368
|
height: topH + PANE_GAP,
|
|
368
|
-
|
|
369
|
-
onDown: cursor.onPointerDown,
|
|
370
|
-
onUp: cursor.onPointerUp,
|
|
371
|
-
onLeave: cursor.onPointerLeave,
|
|
372
|
-
onKeyDown: cursor.onKeyDown,
|
|
373
|
-
onBlur: cursor.onBlur,
|
|
374
|
-
valueMax: Math.max(data.length - 1, 0),
|
|
375
|
-
...point !== null && {
|
|
376
|
-
valueNow: data.indexOf(point),
|
|
377
|
-
valueText: formatX(getX(point))
|
|
378
|
-
},
|
|
379
|
-
...ariaLabel !== void 0 && { ariaLabel }
|
|
369
|
+
...cursorSliderProps({ cursor, data, getX, formatX, ariaLabel })
|
|
380
370
|
}
|
|
381
371
|
)
|
|
382
372
|
] }),
|
|
@@ -454,18 +444,7 @@ function DualPanelPlot(props) {
|
|
|
454
444
|
}
|
|
455
445
|
),
|
|
456
446
|
/* @__PURE__ */ jsxs(TooltipBody, { children: [
|
|
457
|
-
deriveTooltipRows(visibleSeries, point, formatTop)
|
|
458
|
-
TooltipRow,
|
|
459
|
-
{
|
|
460
|
-
color: row.color,
|
|
461
|
-
label: row.label,
|
|
462
|
-
value: row.value,
|
|
463
|
-
shape: row.shape,
|
|
464
|
-
dashed: row.dashed,
|
|
465
|
-
...row.strokeWidth !== void 0 && { strokeWidth: row.strokeWidth }
|
|
466
|
-
},
|
|
467
|
-
row.key
|
|
468
|
-
)),
|
|
447
|
+
/* @__PURE__ */ jsx(TooltipRows, { rows: deriveTooltipRows(visibleSeries, point, formatTop) }),
|
|
469
448
|
barVisible && (() => {
|
|
470
449
|
const v = getBar(point);
|
|
471
450
|
if (v === null || v === void 0 || Number.isNaN(v)) return null;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"MirroredBars.d.ts","sourceRoot":"","sources":["../../../src/charts/kinds/MirroredBars.tsx"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAA;AAErD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,cAAc,CAAA;AAC/C,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAA;AAEzD,OAAO,KAAK,EAAE,QAAQ,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAA;AAIvE,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,0BAA0B,CAAA;
|
|
1
|
+
{"version":3,"file":"MirroredBars.d.ts","sourceRoot":"","sources":["../../../src/charts/kinds/MirroredBars.tsx"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAA;AAErD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,cAAc,CAAA;AAC/C,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAA;AAEzD,OAAO,KAAK,EAAE,QAAQ,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAA;AAIvE,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,0BAA0B,CAAA;AAIrE,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,4BAA4B,CAAA;AAE5D,OAAO,KAAK,EAAE,iBAAiB,EAAE,WAAW,EAAE,MAAM,WAAW,CAAA;AAI/D,gGAAgG;AAChG,MAAM,MAAM,eAAe,GAAG;IAC5B;mEAC+D;IAC/D,GAAG,EAAE,MAAM,CAAA;IACX;;;;;;;OAOG;IACH,GAAG,CAAC,EAAE,MAAM,GAAG,MAAM,CAAA;IACrB;sBACkB;IAClB,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,sDAAsD;IACtD,KAAK,CAAC,EAAE,MAAM,CAAA;IACd;oFACgF;IAChF,MAAM,EAAE,CAAC,CAAC,EAAE,MAAM,KAAK,MAAM,CAAA;CAC9B,CAAA;AAED,MAAM,MAAM,iBAAiB,CAAC,CAAC,IAAI,WAAW,GAAG;IAC/C,IAAI,EAAE,SAAS,CAAC,EAAE,CAAA;IAClB,OAAO,EAAE,MAAM,CAAA;IACf,sFAAsF;IACtF,IAAI,EAAE,CAAC,CAAC,EAAE,CAAC,KAAK,MAAM,CAAA;IACtB;;;;;OAKG;IACH,MAAM,EAAE,SAAS,WAAW,CAAC,CAAC,CAAC,EAAE,CAAA;IACjC,yCAAyC;IACzC,EAAE,EAAE,eAAe,CAAA;IACnB,yCAAyC;IACzC,IAAI,EAAE,eAAe,CAAA;IACrB;8FAC0F;IAC1F,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB;;;;;OAKG;IACH,iBAAiB,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,KAAK,MAAM,CAAA;IACpC;kCAC8B;IAC9B,aAAa,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,KAAK,MAAM,CAAA;IAChC;kGAC8F;IAC9F,MAAM,CAAC,EAAE,MAAM,GAAG,qBAAqB,CAAA;IACvC,IAAI,CAAC,EAAE,OAAO,CAAA;IACd,OAAO,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,MAAM,CAAA;IACjC,WAAW,CAAC,EAAE,CAAC,IAAI,EAAE,SAAS,MAAM,EAAE,EAAE,SAAS,EAAE,MAAM,KAAK,SAAS,MAAM,EAAE,CAAA;IAC/E,IAAI,CAAC,EAAE,QAAQ,CAAC,CAAC,CAAC,CAAA;IAClB,mEAAmE;IACnE,gBAAgB,CAAC,EAAE,gBAAgB,CAAA;IACnC,OAAO,CAAC,EAAE,iBAAiB,CAAC,CAAC,CAAC,GAAG,KAAK,CAAA;IACtC,MAAM,CAAC,EAAE,iBAAiB,GAAG,KAAK,CAAA;IAClC;gFAC4E;IAC5E,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,MAAM,CAAC,EAAE,OAAO,CAAC,WAAW,CAAC,CAAA;IAC7B,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,SAAS,CAAC,EAAE,OAAO,CAAA;IACnB;4FACwF;IACxF,KAAK,CAAC,EAAE,UAAU,CAAA;CACnB,CAAA;AA8BD;;;;;;;;;;;;;GAaG;AACH,iBAAS,iBAAiB,CAAC,CAAC,EAAE,KAAK,EAAE,iBAAiB,CAAC,CAAC,CAAC,+BAwBxD;AA+SD,eAAO,MAAM,YAAY,EAAuB,OAAO,iBAAiB,CAAA"}
|