kanto-ds 1.6.1 → 1.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +52 -4
- package/dist/cdn/kanto.min.js +6619 -0
- package/dist/chunks/{floating-B33g-M_1.js → floating-C9RLa6cZ.js} +2 -2
- package/dist/chunks/floating-C9RLa6cZ.js.map +1 -0
- package/dist/components/forms/kt-date-input/kt-date-input.js +1 -1
- package/dist/components/forms/kt-date-picker/kt-date-picker.js +1 -1
- package/dist/components/forms/kt-input/kt-input.js +1 -1
- package/dist/components/forms/kt-input-menu/kt-input-menu.js +1 -1
- package/dist/components/forms/kt-multi-select/kt-multi-select.js +1 -1
- package/dist/components/forms/kt-select/kt-select.js +1 -1
- package/dist/components/overlays/kt-dropdown/kt-dropdown.js +1 -1
- package/dist/docs/kt-alert.md +52 -0
- package/dist/docs/kt-avatar.md +46 -0
- package/dist/docs/kt-badge.md +104 -0
- package/dist/docs/kt-breadcrumb.md +53 -0
- package/dist/docs/kt-button.md +72 -0
- package/dist/docs/kt-calendar.md +98 -0
- package/dist/docs/kt-card.md +93 -0
- package/dist/docs/kt-chart.md +230 -0
- package/dist/docs/kt-checkbox.md +65 -0
- package/dist/docs/kt-code.md +88 -0
- package/dist/docs/kt-collapsible.md +50 -0
- package/dist/docs/kt-confirm-dialog.md +52 -0
- package/dist/docs/kt-date-input.md +97 -0
- package/dist/docs/kt-date-picker.md +116 -0
- package/dist/docs/kt-drag-drop.md +85 -0
- package/dist/docs/kt-dropdown.md +65 -0
- package/dist/docs/kt-empty-state.md +36 -0
- package/dist/docs/kt-form.md +93 -0
- package/dist/docs/kt-header.md +100 -0
- package/dist/docs/kt-icon.md +68 -0
- package/dist/docs/kt-input-menu.md +90 -0
- package/dist/docs/kt-input.md +137 -0
- package/dist/docs/kt-kbd.md +44 -0
- package/dist/docs/kt-label-input.md +54 -0
- package/dist/docs/kt-meter.md +79 -0
- package/dist/docs/kt-modal.md +62 -0
- package/dist/docs/kt-multi-select.md +115 -0
- package/dist/docs/kt-page-header.md +53 -0
- package/dist/docs/kt-pagination.md +36 -0
- package/dist/docs/kt-progress-bar.md +66 -0
- package/dist/docs/kt-radio-group.md +73 -0
- package/dist/docs/kt-segmented-control.md +70 -0
- package/dist/docs/kt-select.md +80 -0
- package/dist/docs/kt-side-panel.md +59 -0
- package/dist/docs/kt-skeleton.md +46 -0
- package/dist/docs/kt-split-button.md +105 -0
- package/dist/docs/kt-stat.md +57 -0
- package/dist/docs/kt-sub-menu-navigation.md +118 -0
- package/dist/docs/kt-table.md +179 -0
- package/dist/docs/kt-tabs.md +87 -0
- package/dist/docs/kt-textarea.md +59 -0
- package/dist/docs/kt-time-input.md +88 -0
- package/dist/docs/kt-timeline.md +63 -0
- package/dist/docs/kt-toast-container.md +69 -0
- package/dist/docs/kt-toast.md +41 -0
- package/dist/docs/kt-toggle-button-group.md +67 -0
- package/dist/docs/kt-toggle-button.md +52 -0
- package/dist/docs/kt-toggle.md +47 -0
- package/dist/docs/kt-tooltip.md +68 -0
- package/dist/internal/floating.d.ts +4 -0
- package/dist/tokens/colors.css +5 -2
- package/dist/web-types.json +1 -1
- package/package.json +23 -5
- package/dist/chunks/floating-B33g-M_1.js.map +0 -1
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
# `<kt-toggle-button>`
|
|
2
|
+
|
|
3
|
+
A button that stays pressed.
|
|
4
|
+
|
|
5
|
+
```html
|
|
6
|
+
<kt-toggle-button icon="bold" label="Bold"></kt-toggle-button>
|
|
7
|
+
<kt-toggle-button variant="outline" value="draft">Draft</kt-toggle-button>
|
|
8
|
+
```
|
|
9
|
+
|
|
10
|
+
`aria-pressed`, not `aria-checked`: this is a control holding a state, not one
|
|
11
|
+
option among several. When they _are_ options among several and only one may be
|
|
12
|
+
active, reach for [`<kt-segmented-control>`](./kt-segmented-control.md)
|
|
13
|
+
or [`<kt-tabs>`](./kt-tabs.md) — they carry the right semantics and the
|
|
14
|
+
right keyboard model.
|
|
15
|
+
|
|
16
|
+
To draw several as one bar, wrap them in
|
|
17
|
+
[`<kt-toggle-button-group>`](./kt-toggle-button-group.md).
|
|
18
|
+
Inside a group the button becomes controlled: it stops flipping itself and stops
|
|
19
|
+
emitting, and the group drives it.
|
|
20
|
+
|
|
21
|
+
## Variants
|
|
22
|
+
|
|
23
|
+
| Variant | Resting |
|
|
24
|
+
| ----------- | ------------------------------------------ |
|
|
25
|
+
| `primary` | Raised surface; solid indigo when pressed |
|
|
26
|
+
| `secondary` | Flat; soft indigo tint when pressed |
|
|
27
|
+
| `outline` | Bordered, transparent; tinted when pressed |
|
|
28
|
+
|
|
29
|
+
## API
|
|
30
|
+
|
|
31
|
+
| Property | Attribute | Type | Default |
|
|
32
|
+
| -------------- | --------------- | --------------------------------------- | ----------- |
|
|
33
|
+
| `selected` | `selected` | `boolean` | `false` |
|
|
34
|
+
| `disabled` | `disabled` | `boolean` | `false` |
|
|
35
|
+
| `variant` | `variant` | `'primary' \| 'secondary' \| 'outline'` | `'primary'` |
|
|
36
|
+
| `size` | `size` | `'small' \| 'medium' \| 'large'` | `'medium'` |
|
|
37
|
+
| `value` | `value` | `string` | `''` |
|
|
38
|
+
| `icon` | `icon` | `string` | `''` |
|
|
39
|
+
| `iconPosition` | `icon-position` | `'left' \| 'right'` | `'left'` |
|
|
40
|
+
| `label` | `label` | `string` | `''` |
|
|
41
|
+
|
|
42
|
+
| Event | Detail |
|
|
43
|
+
| ----------- | ------------------------------------------------ |
|
|
44
|
+
| `kt-change` | `{ selected, value }` — not fired inside a group |
|
|
45
|
+
|
|
46
|
+
| Slot | Description |
|
|
47
|
+
| --------- | ---------------- |
|
|
48
|
+
| _default_ | The button label |
|
|
49
|
+
|
|
50
|
+
| Part | Description |
|
|
51
|
+
| -------- | --------------------- |
|
|
52
|
+
| `button` | The native `<button>` |
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
# `<kt-toggle>`
|
|
2
|
+
|
|
3
|
+
An on/off switch.
|
|
4
|
+
|
|
5
|
+
```html
|
|
6
|
+
<kt-toggle checked>Notifications</kt-toggle>
|
|
7
|
+
<kt-toggle size="small" label="Dark mode"></kt-toggle>
|
|
8
|
+
<kt-toggle disabled></kt-toggle>
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Sizing
|
|
12
|
+
|
|
13
|
+
The switch is derived from the field height rather than given fixed pixels:
|
|
14
|
+
the track is 1.8× `--switch-height`, and the thumb is inset by 12% of it. So a
|
|
15
|
+
toggle lines up with the inputs and buttons next to it, at every size and every
|
|
16
|
+
breakpoint, and overriding `--button-height` moves all of them together.
|
|
17
|
+
|
|
18
|
+
## Switch, not checkbox
|
|
19
|
+
|
|
20
|
+
`role="switch"` with `aria-checked`, which screen readers announce as "on"/"off"
|
|
21
|
+
rather than "checked". Use it for a setting that takes effect immediately. For
|
|
22
|
+
something that only applies when a form is submitted, a checkbox is the honest
|
|
23
|
+
control.
|
|
24
|
+
|
|
25
|
+
In a form, an unchecked toggle contributes **nothing** to the submission and a
|
|
26
|
+
checked one contributes its `value` — the same rule as a native checkbox.
|
|
27
|
+
|
|
28
|
+
## API
|
|
29
|
+
|
|
30
|
+
| Property | Attribute | Type | Default |
|
|
31
|
+
| ---------- | ---------- | -------------------------------- | ---------- |
|
|
32
|
+
| `checked` | `checked` | `boolean` | `false` |
|
|
33
|
+
| `disabled` | `disabled` | `boolean` | `false` |
|
|
34
|
+
| `size` | `size` | `'small' \| 'medium' \| 'large'` | `'medium'` |
|
|
35
|
+
| `name` | `name` | `string` | `''` |
|
|
36
|
+
| `value` | `value` | `string` | `'on'` |
|
|
37
|
+
| `label` | `label` | `string` | `''` |
|
|
38
|
+
|
|
39
|
+
| Event | Detail |
|
|
40
|
+
| ----------- | ---------------------- |
|
|
41
|
+
| `kt-change` | `{ checked: boolean }` |
|
|
42
|
+
|
|
43
|
+
| Part | Description |
|
|
44
|
+
| ------- | -------------------------- |
|
|
45
|
+
| `base` | The `role="switch"` button |
|
|
46
|
+
| `track` | The track |
|
|
47
|
+
| `thumb` | The sliding thumb |
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
# `<kt-tooltip>`
|
|
2
|
+
|
|
3
|
+
A short label that appears on hover or focus. Wrap what it describes:
|
|
4
|
+
|
|
5
|
+
```html
|
|
6
|
+
<kt-tooltip text="Refresh the data">
|
|
7
|
+
<kt-button icon="refresh-cw" label="Refresh"></kt-button>
|
|
8
|
+
</kt-tooltip>
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## A tooltip is a description, not a name
|
|
12
|
+
|
|
13
|
+
Note the `label` on the button above. A tooltip supplements a control; it must
|
|
14
|
+
never be the only thing naming it. A tooltip that has to be hovered to be read
|
|
15
|
+
leaves touch users and screen-reader users with an unlabelled button.
|
|
16
|
+
|
|
17
|
+
The rule: if the trigger has no visible text, it needs its own accessible name,
|
|
18
|
+
and the tooltip adds detail on top.
|
|
19
|
+
|
|
20
|
+
## How the description reaches the trigger
|
|
21
|
+
|
|
22
|
+
`aria-describedby` cannot cross a shadow boundary — an id inside this element's
|
|
23
|
+
shadow root is invisible to a trigger sitting in the light DOM.
|
|
24
|
+
|
|
25
|
+
So `<kt-tooltip>` also puts the text in a light-DOM node, addressed to a slot
|
|
26
|
+
that does not exist. That keeps it out of the rendered output while leaving it
|
|
27
|
+
referenceable: an explicit `aria-describedby` target is read even when it is not
|
|
28
|
+
displayed.
|
|
29
|
+
|
|
30
|
+
## Where the bubble goes
|
|
31
|
+
|
|
32
|
+
The bubble is a popover in the top layer, placed from the trigger in viewport
|
|
33
|
+
coordinates. No ancestor's `overflow: hidden` can clip it, and it takes no room
|
|
34
|
+
in the page.
|
|
35
|
+
|
|
36
|
+
`placement` is a preference. When that side has no room — `top` on an icon at
|
|
37
|
+
the top of the page — the bubble takes the opposite side, and it slides along
|
|
38
|
+
its side to stay inside the screen. Scrolling or resizing hides it, since a
|
|
39
|
+
bubble fixed to the viewport would drift away from its trigger.
|
|
40
|
+
|
|
41
|
+
## Holding it open
|
|
42
|
+
|
|
43
|
+
`open` shows the bubble whatever the pointer does. It is for a trigger that
|
|
44
|
+
cannot take focus itself: `<kt-input>` holds its error icon's tooltip open while
|
|
45
|
+
the field has focus, so a keyboard user sees the message a mouse user gets on
|
|
46
|
+
hover.
|
|
47
|
+
|
|
48
|
+
## Dismissal
|
|
49
|
+
|
|
50
|
+
Escape hides the tooltip while the trigger keeps focus, as WCAG 1.4.13 requires
|
|
51
|
+
of any content shown on hover or focus.
|
|
52
|
+
|
|
53
|
+
## API
|
|
54
|
+
|
|
55
|
+
| Property | Attribute | Type | Default |
|
|
56
|
+
| ----------- | ----------- | ---------------------------------------- | ------- |
|
|
57
|
+
| `text` | `text` | `string` | `''` |
|
|
58
|
+
| `placement` | `placement` | `'top' \| 'bottom' \| 'left' \| 'right'` | `'top'` |
|
|
59
|
+
| `disabled` | `disabled` | `boolean` | `false` |
|
|
60
|
+
| `open` | `open` | `boolean` | `false` |
|
|
61
|
+
|
|
62
|
+
| Slot | Description |
|
|
63
|
+
| --------- | ----------- |
|
|
64
|
+
| _default_ | The trigger |
|
|
65
|
+
|
|
66
|
+
| Part | Description |
|
|
67
|
+
| -------- | ------------------ |
|
|
68
|
+
| `bubble` | The tooltip bubble |
|
|
@@ -29,6 +29,10 @@ export interface FloatingOptions {
|
|
|
29
29
|
* animatable state its element gives it, so it can fade out after it leaves
|
|
30
30
|
* the top layer: `display` here only undoes the popover's `display: none`, and
|
|
31
31
|
* a panel's own `display` still wins.
|
|
32
|
+
*
|
|
33
|
+
* Until it is first placed it sits top left. With auto insets a closed panel
|
|
34
|
+
* sat where the flow put it — beside a right-hand trigger, past the edge of
|
|
35
|
+
* the page, which then scrolled sideways.
|
|
32
36
|
*/
|
|
33
37
|
export declare const floatingStyles: import("lit").CSSResult;
|
|
34
38
|
export declare class FloatingController implements ReactiveController {
|
package/dist/tokens/colors.css
CHANGED
|
@@ -56,9 +56,12 @@
|
|
|
56
56
|
--color-success-soft: rgba(53, 221, 131, 0.12);
|
|
57
57
|
|
|
58
58
|
/* === TEXT STEPS OF THE BRAND AND SEMANTIC COLOURS === */
|
|
59
|
+
/* Info and danger are a shade lighter than the rest need: an alert's action
|
|
60
|
+
button lays its tint on the alert's, and on a card that double tint is the
|
|
61
|
+
lightest ground these text steps meet. */
|
|
59
62
|
--color-primary-text: var(--accent-text-dark, #8e97ff);
|
|
60
|
-
--color-danger-text: #
|
|
61
|
-
--color-info-text: #
|
|
63
|
+
--color-danger-text: #ff7984;
|
|
64
|
+
--color-info-text: #43bbff;
|
|
62
65
|
--color-warning-text: #fca80d;
|
|
63
66
|
--color-success-text: #01df7e;
|
|
64
67
|
|
package/dist/web-types.json
CHANGED
package/package.json
CHANGED
|
@@ -1,14 +1,29 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "kanto-ds",
|
|
3
|
-
"version": "1.
|
|
4
|
-
"description": "
|
|
3
|
+
"version": "1.7.0",
|
|
4
|
+
"description": "Forty-nine accessible web components for dashboards, admin tools and forms — themeable in one line, in React, Vue, Angular, Svelte or plain HTML.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"design-system",
|
|
7
7
|
"web-components",
|
|
8
8
|
"custom-elements",
|
|
9
9
|
"lit",
|
|
10
10
|
"ui",
|
|
11
|
-
"
|
|
11
|
+
"ui-kit",
|
|
12
|
+
"components",
|
|
13
|
+
"dashboard",
|
|
14
|
+
"admin",
|
|
15
|
+
"forms",
|
|
16
|
+
"data-table",
|
|
17
|
+
"date-picker",
|
|
18
|
+
"react",
|
|
19
|
+
"vue",
|
|
20
|
+
"angular",
|
|
21
|
+
"svelte",
|
|
22
|
+
"accessible",
|
|
23
|
+
"a11y",
|
|
24
|
+
"theming",
|
|
25
|
+
"dark-theme",
|
|
26
|
+
"dark-mode"
|
|
12
27
|
],
|
|
13
28
|
"homepage": "https://kanto.arnaudmichel.fr",
|
|
14
29
|
"bugs": {
|
|
@@ -37,6 +52,8 @@
|
|
|
37
52
|
},
|
|
38
53
|
"main": "./dist/index.js",
|
|
39
54
|
"module": "./dist/index.js",
|
|
55
|
+
"unpkg": "./dist/cdn/kanto.min.js",
|
|
56
|
+
"jsdelivr": "./dist/cdn/kanto.min.js",
|
|
40
57
|
"types": "./dist/index.d.ts",
|
|
41
58
|
"customElements": "./dist/custom-elements.json",
|
|
42
59
|
"web-types": "./dist/web-types.json",
|
|
@@ -286,10 +303,11 @@
|
|
|
286
303
|
],
|
|
287
304
|
"scripts": {
|
|
288
305
|
"dev": "vite --config demo/vite.config.ts",
|
|
289
|
-
"build": "npm run build:js && npm run build:types && npm run build:static && npm run build:manifest",
|
|
306
|
+
"build": "npm run build:js && npm run build:cdn && npm run build:types && npm run build:static && npm run build:manifest",
|
|
307
|
+
"build:cdn": "node scripts/build-cdn.js",
|
|
290
308
|
"build:js": "vite build",
|
|
291
309
|
"build:types": "tsc -p tsconfig.build.json",
|
|
292
|
-
"build:static": "node scripts/copy-static.js",
|
|
310
|
+
"build:static": "node scripts/copy-static.js && node scripts/llms.js --docs",
|
|
293
311
|
"build:manifest": "cem analyze --config custom-elements-manifest.config.js",
|
|
294
312
|
"build:demo": "vite build --config demo/vite.config.ts",
|
|
295
313
|
"test": "vitest run",
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"floating-B33g-M_1.js","sources":["../../src/internal/floating.ts"],"sourcesContent":["import { css, type ReactiveController, type ReactiveControllerHost } from 'lit';\nimport { placeFloating, type Align, type Side } from './position.js';\n\n/**\n * A panel that opens from a trigger — a select's list, a date picker's\n * calendar, a menu — drawn in the top layer and placed from the trigger.\n *\n * A panel positioned inside its element was cut off by any ancestor with\n * `overflow: hidden`: a table cell, a side panel, an app's scrolling main\n * area. In the top layer, nothing clips it. It opens on the side asked for, or\n * the other one when that has no room, and follows the trigger as the page\n * scrolls.\n */\n\nexport interface FloatingOptions {\n /** The panel, which carries `popover=\"manual\"` and the `floating` class. */\n readonly panel: () => HTMLElement | null | undefined;\n /** What the panel opens from. */\n readonly anchor: () => Element | null | undefined;\n /** The side it prefers. */\n readonly side?: () => Side;\n /** Which edge of the anchor it lines up with; its start by default. */\n readonly align?: () => Align;\n /** Sizes the panel to the anchor's width — a list under its field. */\n readonly matchWidth?: boolean;\n /** Told the side it opened on, for the direction of its entrance. */\n readonly onPlace?: (side: Side) => void;\n}\n\n/**\n * The panel's own styles. Closed, it keeps the display and the hidden,\n * animatable state its element gives it, so it can fade out after it leaves\n * the top layer: `display` here only undoes the popover's `display: none`, and\n * a panel's own `display` still wins.\n */\nexport const floatingStyles = css`\n .floating {\n position: fixed;\n inset: auto;\n display: block;\n /* As wide as what it holds, wherever it is placed: a box sized from its\n position would change size when moved, and be moved again. */\n width: max-content;\n margin: 0;\n color: inherit;\n /* Set apart from the page by the theme: a lighter surface in the dark,\n an edge and a soft shadow in the light. */\n border: var(--border-width) solid var(--border-popover);\n box-shadow: var(--shadow-popover);\n }\n`;\n\nexport class FloatingController implements ReactiveController {\n private open = false;\n private frame = 0;\n /** Places the panel again when its size changes — content drawn after it opened. */\n private resizeObserver: ResizeObserver | undefined;\n\n constructor(\n host: ReactiveControllerHost,\n private readonly options: FloatingOptions,\n ) {\n host.addController(this);\n }\n\n /**\n * Call from the host's `updated()` with whether the panel is open. While it\n * is, every update re-places it: its content — a filtered list — can change\n * its size.\n */\n sync(open: boolean): void {\n // First, and whatever the panel: one rendered only while open is already\n // gone when it closes, and its listeners must go with it.\n if (open !== this.open) {\n this.open = open;\n const method = open ? 'addEventListener' : 'removeEventListener';\n window[method]('scroll', this.follow, { capture: true, passive: true });\n window[method]('resize', this.follow);\n }\n\n const panel = this.options.panel();\n // Where popovers are missing — a test DOM — the panel stays where it is.\n if (!panel || typeof panel.showPopover !== 'function') return;\n\n if (open) {\n if (!panel.matches(':popover-open')) panel.showPopover();\n this.place();\n // A panel measured at opening may grow once what it holds has drawn —\n // a calendar is an element of its own — and must be placed again.\n if (!this.resizeObserver && typeof ResizeObserver !== 'undefined') {\n this.resizeObserver = new ResizeObserver(this.follow);\n this.resizeObserver.observe(panel);\n }\n } else {\n this.unobserve();\n if (panel.matches(':popover-open')) panel.hidePopover();\n }\n }\n\n private unobserve(): void {\n this.resizeObserver?.disconnect();\n this.resizeObserver = undefined;\n }\n\n hostDisconnected(): void {\n this.sync(false);\n this.unobserve();\n cancelAnimationFrame(this.frame);\n }\n\n private follow = (): void => {\n cancelAnimationFrame(this.frame);\n this.frame = requestAnimationFrame(() => this.place());\n };\n\n private place(): void {\n const panel = this.options.panel();\n const anchor = this.options.anchor()?.getBoundingClientRect();\n if (!panel || !anchor) return;\n\n if (this.options.matchWidth) panel.style.width = `${anchor.width}px`;\n // Untransformed size: the entrance animation scales and slides the panel.\n const { x, y, placement } = placeFloating(\n anchor,\n { width: panel.offsetWidth, height: panel.offsetHeight },\n { width: window.innerWidth, height: window.innerHeight },\n this.options.side?.() ?? 'bottom',\n this.options.align?.() ?? 'start',\n );\n panel.style.left = `${x}px`;\n panel.style.top = `${y}px`;\n this.options.onPlace?.(placement);\n }\n}\n"],"names":["floatingStyles","css","FloatingController","host","options","open","method","panel","anchor","x","y","placement","placeFloating"],"mappings":";;AAmCO,MAAMA,IAAiBC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAiBvB,MAAMC,EAAiD;AAAA,EAM5D,YACEC,GACiBC,GACjB;AADiB,SAAA,UAAAA,GAPnB,KAAQ,OAAO,IACf,KAAQ,QAAQ,GAwDhB,KAAQ,SAAS,MAAY;AAC3B,2BAAqB,KAAK,KAAK,GAC/B,KAAK,QAAQ,sBAAsB,MAAM,KAAK,OAAO;AAAA,IACvD,GAnDED,EAAK,cAAc,IAAI;AAAA,EACzB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,KAAKE,GAAqB;AAGxB,QAAIA,MAAS,KAAK,MAAM;AACtB,WAAK,OAAOA;AACZ,YAAMC,IAASD,IAAO,qBAAqB;AAC3C,aAAOC,CAAM,EAAE,UAAU,KAAK,QAAQ,EAAE,SAAS,IAAM,SAAS,IAAM,GACtE,OAAOA,CAAM,EAAE,UAAU,KAAK,MAAM;AAAA,IACtC;AAEA,UAAMC,IAAQ,KAAK,QAAQ,MAAA;AAE3B,IAAI,CAACA,KAAS,OAAOA,EAAM,eAAgB,eAEvCF,KACGE,EAAM,QAAQ,eAAe,OAAS,YAAA,GAC3C,KAAK,MAAA,GAGD,CAAC,KAAK,kBAAkB,OAAO,iBAAmB,QACpD,KAAK,iBAAiB,IAAI,eAAe,KAAK,MAAM,GACpD,KAAK,eAAe,QAAQA,CAAK,OAGnC,KAAK,UAAA,GACDA,EAAM,QAAQ,eAAe,OAAS,YAAA;AAAA,EAE9C;AAAA,EAEQ,YAAkB;AACxB,SAAK,gBAAgB,WAAA,GACrB,KAAK,iBAAiB;AAAA,EACxB;AAAA,EAEA,mBAAyB;AACvB,SAAK,KAAK,EAAK,GACf,KAAK,UAAA,GACL,qBAAqB,KAAK,KAAK;AAAA,EACjC;AAAA,EAOQ,QAAc;AACpB,UAAMA,IAAQ,KAAK,QAAQ,MAAA,GACrBC,IAAS,KAAK,QAAQ,OAAA,GAAU,sBAAA;AACtC,QAAI,CAACD,KAAS,CAACC,EAAQ;AAEvB,IAAI,KAAK,QAAQ,eAAYD,EAAM,MAAM,QAAQ,GAAGC,EAAO,KAAK;AAEhE,UAAM,EAAE,GAAAC,GAAG,GAAAC,GAAG,WAAAC,EAAA,IAAcC;AAAA,MAC1BJ;AAAA,MACA,EAAE,OAAOD,EAAM,aAAa,QAAQA,EAAM,aAAA;AAAA,MAC1C,EAAE,OAAO,OAAO,YAAY,QAAQ,OAAO,YAAA;AAAA,MAC3C,KAAK,QAAQ,OAAA,KAAY;AAAA,MACzB,KAAK,QAAQ,aAAa;AAAA,IAAA;AAE5B,IAAAA,EAAM,MAAM,OAAO,GAAGE,CAAC,MACvBF,EAAM,MAAM,MAAM,GAAGG,CAAC,MACtB,KAAK,QAAQ,UAAUC,CAAS;AAAA,EAClC;AACF;"}
|