@acronis-platform/ui-react 0.44.0 → 0.46.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.
@@ -1,48 +1,36 @@
1
- import { jsx as e, jsxs as o } from "react/jsx-runtime";
2
- import { ArrowDownIcon as a, ArrowUpIcon as d, ArrowsDownUpIcon as c, EyeCrossedIcon as l } from "@acronis-platform/icons-react/stroke-mono";
3
- import { cn as s } from "../../../lib/utils.js";
4
- import { DropdownMenu as p, DropdownMenuTrigger as g, DropdownMenuContent as m, DropdownMenuItem as n, DropdownMenuSeparator as f } from "../dropdown-menu/dropdown-menu.js";
5
- import { Button as u } from "../button/button.js";
6
- function I({
1
+ import { jsx as e, jsxs as n } from "react/jsx-runtime";
2
+ import { ArrowUpIcon as c, ArrowDownIcon as l, ArrowsDownUpIcon as v } from "@acronis-platform/icons-react/stroke-mono";
3
+ import { cn as a } from "../../../lib/utils.js";
4
+ function m({
7
5
  column: r,
8
- title: t,
9
- className: i
6
+ title: o,
7
+ className: t,
8
+ ...s
10
9
  }) {
11
- return r.getCanSort() ? /* @__PURE__ */ e("div", { className: s("flex items-center gap-2", i), children: /* @__PURE__ */ o(p, { children: [
12
- /* @__PURE__ */ o(
13
- g,
14
- {
15
- render: /* @__PURE__ */ e(
16
- u,
17
- {
18
- variant: "ghost",
19
- className: "-ml-2 h-8 gap-2 px-2 data-[popup-open]:bg-accent"
20
- }
21
- ),
22
- children: [
23
- /* @__PURE__ */ e("span", { children: t }),
24
- r.getIsSorted() === "desc" ? /* @__PURE__ */ e(a, {}) : r.getIsSorted() === "asc" ? /* @__PURE__ */ e(d, {}) : /* @__PURE__ */ e(c, {})
25
- ]
26
- }
27
- ),
28
- /* @__PURE__ */ o(m, { align: "start", children: [
29
- /* @__PURE__ */ o(n, { onClick: () => r.toggleSorting(!1), children: [
30
- /* @__PURE__ */ e(d, { className: "text-muted-foreground" }),
31
- "Asc"
32
- ] }),
33
- /* @__PURE__ */ o(n, { onClick: () => r.toggleSorting(!0), children: [
34
- /* @__PURE__ */ e(a, { className: "text-muted-foreground" }),
35
- "Desc"
36
- ] }),
37
- /* @__PURE__ */ e(f, {}),
38
- /* @__PURE__ */ o(n, { onClick: () => r.toggleVisibility(!1), children: [
39
- /* @__PURE__ */ e(l, { className: "text-muted-foreground" }),
40
- "Hide"
41
- ] })
42
- ] })
43
- ] }) }) : /* @__PURE__ */ e("div", { className: s(i), children: t });
10
+ if (!r.getCanSort())
11
+ return /* @__PURE__ */ e("div", { className: a(t), children: o });
12
+ const i = r.getIsSorted();
13
+ return /* @__PURE__ */ n(
14
+ "button",
15
+ {
16
+ type: "button",
17
+ onClick: () => r.toggleSorting(),
18
+ "aria-label": `Sort by ${o}`,
19
+ className: a(
20
+ // -ml-2 px-2 keeps the label flush at the cell padding while giving the
21
+ // toggle a comfortable click/hover target.
22
+ "-ml-2 inline-flex h-8 select-none items-center gap-2 rounded px-2 text-sm font-semibold transition-colors hover:bg-[var(--ui-table-header-cell-color-hover)] focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-[var(--ui-focus-primary)] [&_svg]:size-[var(--ui-table-header-sort-icon-size)] [&_svg]:shrink-0",
23
+ t
24
+ ),
25
+ ...s,
26
+ children: [
27
+ /* @__PURE__ */ e("span", { children: o }),
28
+ i === "asc" ? /* @__PURE__ */ e(c, { className: "text-[var(--ui-table-header-sort-icon-color-active)]" }) : i === "desc" ? /* @__PURE__ */ e(l, { className: "text-[var(--ui-table-header-sort-icon-color-active)]" }) : /* @__PURE__ */ e(v, { className: "text-[var(--ui-table-header-sort-icon-color-inactive)]" })
29
+ ]
30
+ }
31
+ );
44
32
  }
45
33
  export {
46
- I as DataTableColumnHeader
34
+ m as DataTableColumnHeader
47
35
  };
48
36
  //# sourceMappingURL=data-table-column-header.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"data-table-column-header.js","sources":["../../../../src/components/ui/data-table/data-table-column-header.tsx"],"sourcesContent":["import * as React from 'react';\nimport type { Column } from '@tanstack/react-table';\nimport {\n ArrowDownIcon,\n ArrowsDownUpIcon,\n ArrowUpIcon,\n EyeCrossedIcon,\n} from '@acronis-platform/icons-react/stroke-mono';\n\nimport { cn } from '@/lib/utils';\nimport { Button } from '../button';\nimport {\n DropdownMenu,\n DropdownMenuContent,\n DropdownMenuItem,\n DropdownMenuSeparator,\n DropdownMenuTrigger,\n} from '../dropdown-menu';\n\ninterface DataTableColumnHeaderProps<TData, TValue>\n extends React.HTMLAttributes<HTMLDivElement> {\n column: Column<TData, TValue>;\n title: string;\n}\n\nexport function DataTableColumnHeader<TData, TValue>({\n column,\n title,\n className,\n}: DataTableColumnHeaderProps<TData, TValue>) {\n if (!column.getCanSort()) {\n return <div className={cn(className)}>{title}</div>;\n }\n\n return (\n <div className={cn('flex items-center gap-2', className)}>\n <DropdownMenu>\n <DropdownMenuTrigger\n render={\n <Button\n variant=\"ghost\"\n // ui-react's ghost button has 0 horizontal padding, so add a small\n // padding for a comfortable click/hover target and negate it on the\n // left (-ml-2 px-2) so the label still sits flush at the cell's\n // padding edge aligned with the body cells below.\n className=\"-ml-2 h-8 gap-2 px-2 data-[popup-open]:bg-accent\"\n />\n }\n >\n <span>{title}</span>\n {column.getIsSorted() === 'desc' ? (\n <ArrowDownIcon />\n ) : column.getIsSorted() === 'asc' ? (\n <ArrowUpIcon />\n ) : (\n <ArrowsDownUpIcon />\n )}\n </DropdownMenuTrigger>\n <DropdownMenuContent align=\"start\">\n <DropdownMenuItem onClick={() => column.toggleSorting(false)}>\n <ArrowUpIcon className=\"text-muted-foreground\" />\n Asc\n </DropdownMenuItem>\n <DropdownMenuItem onClick={() => column.toggleSorting(true)}>\n <ArrowDownIcon className=\"text-muted-foreground\" />\n Desc\n </DropdownMenuItem>\n <DropdownMenuSeparator />\n <DropdownMenuItem onClick={() => column.toggleVisibility(false)}>\n <EyeCrossedIcon className=\"text-muted-foreground\" />\n Hide\n </DropdownMenuItem>\n </DropdownMenuContent>\n </DropdownMenu>\n </div>\n );\n}\n"],"names":["DataTableColumnHeader","column","title","className","jsx","cn","DropdownMenu","jsxs","DropdownMenuTrigger","Button","ArrowDownIcon","ArrowUpIcon","ArrowsDownUpIcon","DropdownMenuContent","DropdownMenuItem","DropdownMenuSeparator","EyeCrossedIcon"],"mappings":";;;;;AAyBO,SAASA,EAAqC;AAAA,EACnD,QAAAC;AAAA,EACA,OAAAC;AAAA,EACA,WAAAC;AACF,GAA8C;AAC5C,SAAKF,EAAO,eAKV,gBAAAG,EAAC,SAAI,WAAWC,EAAG,2BAA2BF,CAAS,GACrD,4BAACG,GAAA,EACC,UAAA;AAAA,IAAA,gBAAAC;AAAA,MAACC;AAAA,MAAA;AAAA,QACC,QACE,gBAAAJ;AAAA,UAACK;AAAA,UAAA;AAAA,YACC,SAAQ;AAAA,YAKR,WAAU;AAAA,UAAA;AAAA,QAAA;AAAA,QAId,UAAA;AAAA,UAAA,gBAAAL,EAAC,UAAM,UAAAF,EAAA,CAAM;AAAA,UACZD,EAAO,YAAA,MAAkB,2BACvBS,GAAA,CAAA,CAAc,IACbT,EAAO,YAAA,MAAkB,QAC3B,gBAAAG,EAACO,GAAA,CAAA,CAAY,sBAEZC,GAAA,CAAA,CAAiB;AAAA,QAAA;AAAA,MAAA;AAAA,IAAA;AAAA,IAGtB,gBAAAL,EAACM,GAAA,EAAoB,OAAM,SACzB,UAAA;AAAA,MAAA,gBAAAN,EAACO,KAAiB,SAAS,MAAMb,EAAO,cAAc,EAAK,GACzD,UAAA;AAAA,QAAA,gBAAAG,EAACO,GAAA,EAAY,WAAU,wBAAA,CAAwB;AAAA,QAAE;AAAA,MAAA,GAEnD;AAAA,wBACCG,GAAA,EAAiB,SAAS,MAAMb,EAAO,cAAc,EAAI,GACxD,UAAA;AAAA,QAAA,gBAAAG,EAACM,GAAA,EAAc,WAAU,wBAAA,CAAwB;AAAA,QAAE;AAAA,MAAA,GAErD;AAAA,wBACCK,GAAA,EAAsB;AAAA,wBACtBD,GAAA,EAAiB,SAAS,MAAMb,EAAO,iBAAiB,EAAK,GAC5D,UAAA;AAAA,QAAA,gBAAAG,EAACY,GAAA,EAAe,WAAU,wBAAA,CAAwB;AAAA,QAAE;AAAA,MAAA,EAAA,CAEtD;AAAA,IAAA,EAAA,CACF;AAAA,EAAA,EAAA,CACF,EAAA,CACF,sBA3CQ,OAAA,EAAI,WAAWX,EAAGF,CAAS,GAAI,UAAAD,GAAM;AA6CjD;"}
1
+ {"version":3,"file":"data-table-column-header.js","sources":["../../../../src/components/ui/data-table/data-table-column-header.tsx"],"sourcesContent":["import * as React from 'react';\nimport type { Column } from '@tanstack/react-table';\nimport {\n ArrowDownIcon,\n ArrowsDownUpIcon,\n ArrowUpIcon,\n} from '@acronis-platform/icons-react/stroke-mono';\n\nimport { cn } from '@/lib/utils';\n\ninterface DataTableColumnHeaderProps<TData, TValue>\n extends React.ButtonHTMLAttributes<HTMLButtonElement> {\n column: Column<TData, TValue>;\n title: string;\n}\n\n// Single-click sortable column header — matches the Table primitive's sortable\n// `TableHead`: one click toggles the sort (ascending → descending → unsorted) via\n// TanStack's `column.toggleSorting()`. The trailing icon shows the state with the\n// same `--ui-table-header-sort-icon-*` tokens — an up arrow (ascending) or down\n// arrow (descending) in the active blue, or the muted up/down arrows when\n// unsorted. (Column hiding lives in the toolbar's `DataTableViewOptions`, not a\n// per-header menu, so sorting is a single click.)\nexport function DataTableColumnHeader<TData, TValue>({\n column,\n title,\n className,\n ...props\n}: DataTableColumnHeaderProps<TData, TValue>) {\n if (!column.getCanSort()) {\n return <div className={cn(className)}>{title}</div>;\n }\n\n const sorted = column.getIsSorted();\n\n return (\n <button\n type=\"button\"\n onClick={() => column.toggleSorting()}\n aria-label={`Sort by ${title}`}\n className={cn(\n // -ml-2 px-2 keeps the label flush at the cell padding while giving the\n // toggle a comfortable click/hover target.\n '-ml-2 inline-flex h-8 select-none items-center gap-2 rounded px-2 text-sm font-semibold transition-colors hover:bg-[var(--ui-table-header-cell-color-hover)] focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-[var(--ui-focus-primary)] [&_svg]:size-[var(--ui-table-header-sort-icon-size)] [&_svg]:shrink-0',\n className\n )}\n {...props}\n >\n <span>{title}</span>\n {sorted === 'asc' ? (\n <ArrowUpIcon className=\"text-[var(--ui-table-header-sort-icon-color-active)]\" />\n ) : sorted === 'desc' ? (\n <ArrowDownIcon className=\"text-[var(--ui-table-header-sort-icon-color-active)]\" />\n ) : (\n <ArrowsDownUpIcon className=\"text-[var(--ui-table-header-sort-icon-color-inactive)]\" />\n )}\n </button>\n );\n}\n"],"names":["DataTableColumnHeader","column","title","className","props","cn","sorted","jsxs","jsx","ArrowUpIcon","ArrowDownIcon","ArrowsDownUpIcon"],"mappings":";;;AAuBO,SAASA,EAAqC;AAAA,EACnD,QAAAC;AAAA,EACA,OAAAC;AAAA,EACA,WAAAC;AAAA,EACA,GAAGC;AACL,GAA8C;AAC5C,MAAI,CAACH,EAAO;AACV,6BAAQ,OAAA,EAAI,WAAWI,EAAGF,CAAS,GAAI,UAAAD,GAAM;AAG/C,QAAMI,IAASL,EAAO,YAAA;AAEtB,SACE,gBAAAM;AAAA,IAAC;AAAA,IAAA;AAAA,MACC,MAAK;AAAA,MACL,SAAS,MAAMN,EAAO,cAAA;AAAA,MACtB,cAAY,WAAWC,CAAK;AAAA,MAC5B,WAAWG;AAAA;AAAA;AAAA,QAGT;AAAA,QACAF;AAAA,MAAA;AAAA,MAED,GAAGC;AAAA,MAEJ,UAAA;AAAA,QAAA,gBAAAI,EAAC,UAAM,UAAAN,EAAA,CAAM;AAAA,QACZI,MAAW,QACV,gBAAAE,EAACC,GAAA,EAAY,WAAU,wDAAuD,IAC5EH,MAAW,SACb,gBAAAE,EAACE,KAAc,WAAU,uDAAA,CAAuD,IAEhF,gBAAAF,EAACG,GAAA,EAAiB,WAAU,yDAAA,CAAyD;AAAA,MAAA;AAAA,IAAA;AAAA,EAAA;AAI7F;"}
@@ -0,0 +1,54 @@
1
+ import { jsx as t } from "react/jsx-runtime";
2
+ import * as r from "react";
3
+ import { cn as a } from "../../../lib/utils.js";
4
+ const o = r.forwardRef(({ className: s, ...e }, i) => /* @__PURE__ */ t("dl", { ref: i, className: a("w-full", s), ...e }));
5
+ o.displayName = "DescriptionList";
6
+ const c = r.forwardRef(({ className: s, ...e }, i) => /* @__PURE__ */ t(
7
+ "div",
8
+ {
9
+ ref: i,
10
+ className: a(
11
+ // `px-6` insets the content while the `border-t` divider stays full-bleed
12
+ // (the Figma card look). Override the padding via className when the
13
+ // surrounding container already pads (e.g. `-mx-6` inside a padded body).
14
+ "grid grid-cols-[var(--description-list-label,14rem)_minmax(0,1fr)] gap-x-4 border-t border-border px-6 py-3 text-sm leading-6",
15
+ s
16
+ ),
17
+ ...e
18
+ }
19
+ ));
20
+ c.displayName = "DescriptionListItem";
21
+ const n = r.forwardRef(({ className: s, ...e }, i) => /* @__PURE__ */ t("dt", { ref: i, className: a("text-foreground", s), ...e }));
22
+ n.displayName = "DescriptionListLabel";
23
+ const p = r.forwardRef(({ className: s, ...e }, i) => /* @__PURE__ */ t(
24
+ "dd",
25
+ {
26
+ ref: i,
27
+ className: a(
28
+ "flex min-w-0 items-start gap-2 text-foreground [&>svg]:mt-0.5 [&>svg]:size-4 [&>svg]:shrink-0",
29
+ s
30
+ ),
31
+ ...e
32
+ }
33
+ ));
34
+ p.displayName = "DescriptionListValue";
35
+ const d = r.forwardRef(({ className: s, ...e }, i) => /* @__PURE__ */ t("p", { ref: i, className: a("text-muted-foreground", s), ...e }));
36
+ d.displayName = "DescriptionListValueDescription";
37
+ const l = r.forwardRef(({ className: s, ...e }, i) => /* @__PURE__ */ t(
38
+ "div",
39
+ {
40
+ ref: i,
41
+ className: a("flex flex-wrap items-center gap-4", s),
42
+ ...e
43
+ }
44
+ ));
45
+ l.displayName = "DescriptionListActions";
46
+ export {
47
+ o as DescriptionList,
48
+ l as DescriptionListActions,
49
+ c as DescriptionListItem,
50
+ n as DescriptionListLabel,
51
+ p as DescriptionListValue,
52
+ d as DescriptionListValueDescription
53
+ };
54
+ //# sourceMappingURL=description-list.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"description-list.js","sources":["../../../../src/components/ui/description-list/description-list.tsx"],"sourcesContent":["import * as React from 'react';\n\nimport { cn } from '@/lib/utils';\n\n// A key/value data list — rows of `label → value`, where the value can be plain\n// text, a status (leading icon + value + a muted description), or action links.\n// Built from the Figma \"Service status\" design (Cyber-Compliance node\n// 3001-20448). Semantic HTML: a `<dl>` of `<div>`-grouped `<dt>`/`<dd>` rows.\n// No `--ui-description-list-*` tier — it composes the shared semantic tokens:\n// • label / value -> text-foreground (--ui-text-on-surface-primary)\n// • description -> text-muted-foreground (--ui-text-on-surface-secondary)\n// • row divider -> border-border (--ui-border-on-surface-border)\n// • status icon color -> caller-provided (--ui-text-on-status-*)\n// • action links -> compose the `Link` component\n// The 2-column row grid uses a fixed label column (overridable per item via\n// className / the `--description-list-label` custom property).\n\nconst DescriptionList = React.forwardRef<\n HTMLDListElement,\n React.HTMLAttributes<HTMLDListElement>\n>(({ className, ...props }, ref) => (\n <dl ref={ref} className={cn('w-full', className)} {...props} />\n));\nDescriptionList.displayName = 'DescriptionList';\n\nconst DescriptionListItem = React.forwardRef<\n HTMLDivElement,\n React.HTMLAttributes<HTMLDivElement>\n>(({ className, ...props }, ref) => (\n <div\n ref={ref}\n className={cn(\n // `px-6` insets the content while the `border-t` divider stays full-bleed\n // (the Figma card look). Override the padding via className when the\n // surrounding container already pads (e.g. `-mx-6` inside a padded body).\n 'grid grid-cols-[var(--description-list-label,14rem)_minmax(0,1fr)] gap-x-4 border-t border-border px-6 py-3 text-sm leading-6',\n className\n )}\n {...props}\n />\n));\nDescriptionListItem.displayName = 'DescriptionListItem';\n\nconst DescriptionListLabel = React.forwardRef<\n HTMLElement,\n React.HTMLAttributes<HTMLElement>\n>(({ className, ...props }, ref) => (\n <dt ref={ref} className={cn('text-foreground', className)} {...props} />\n));\nDescriptionListLabel.displayName = 'DescriptionListLabel';\n\nconst DescriptionListValue = React.forwardRef<\n HTMLElement,\n React.HTMLAttributes<HTMLElement>\n>(({ className, ...props }, ref) => (\n <dd\n ref={ref}\n className={cn(\n 'flex min-w-0 items-start gap-2 text-foreground [&>svg]:mt-0.5 [&>svg]:size-4 [&>svg]:shrink-0',\n className\n )}\n {...props}\n />\n));\nDescriptionListValue.displayName = 'DescriptionListValue';\n\nconst DescriptionListValueDescription = React.forwardRef<\n HTMLParagraphElement,\n React.HTMLAttributes<HTMLParagraphElement>\n>(({ className, ...props }, ref) => (\n <p ref={ref} className={cn('text-muted-foreground', className)} {...props} />\n));\nDescriptionListValueDescription.displayName = 'DescriptionListValueDescription';\n\nconst DescriptionListActions = React.forwardRef<\n HTMLDivElement,\n React.HTMLAttributes<HTMLDivElement>\n>(({ className, ...props }, ref) => (\n <div\n ref={ref}\n className={cn('flex flex-wrap items-center gap-4', className)}\n {...props}\n />\n));\nDescriptionListActions.displayName = 'DescriptionListActions';\n\nexport {\n DescriptionList,\n DescriptionListItem,\n DescriptionListLabel,\n DescriptionListValue,\n DescriptionListValueDescription,\n DescriptionListActions,\n};\n"],"names":["DescriptionList","React","className","props","ref","cn","DescriptionListItem","jsx","DescriptionListLabel","DescriptionListValue","DescriptionListValueDescription","DescriptionListActions"],"mappings":";;;AAiBA,MAAMA,IAAkBC,EAAM,WAG5B,CAAC,EAAE,WAAAC,GAAW,GAAGC,KAASC,wBACzB,MAAA,EAAG,KAAAA,GAAU,WAAWC,EAAG,UAAUH,CAAS,GAAI,GAAGC,GAAO,CAC9D;AACDH,EAAgB,cAAc;AAE9B,MAAMM,IAAsBL,EAAM,WAGhC,CAAC,EAAE,WAAAC,GAAW,GAAGC,EAAA,GAASC,MAC1B,gBAAAG;AAAA,EAAC;AAAA,EAAA;AAAA,IACC,KAAAH;AAAA,IACA,WAAWC;AAAA;AAAA;AAAA;AAAA,MAIT;AAAA,MACAH;AAAA,IAAA;AAAA,IAED,GAAGC;AAAA,EAAA;AACN,CACD;AACDG,EAAoB,cAAc;AAElC,MAAME,IAAuBP,EAAM,WAGjC,CAAC,EAAE,WAAAC,GAAW,GAAGC,KAASC,wBACzB,MAAA,EAAG,KAAAA,GAAU,WAAWC,EAAG,mBAAmBH,CAAS,GAAI,GAAGC,GAAO,CACvE;AACDK,EAAqB,cAAc;AAEnC,MAAMC,IAAuBR,EAAM,WAGjC,CAAC,EAAE,WAAAC,GAAW,GAAGC,EAAA,GAASC,MAC1B,gBAAAG;AAAA,EAAC;AAAA,EAAA;AAAA,IACC,KAAAH;AAAA,IACA,WAAWC;AAAA,MACT;AAAA,MACAH;AAAA,IAAA;AAAA,IAED,GAAGC;AAAA,EAAA;AACN,CACD;AACDM,EAAqB,cAAc;AAEnC,MAAMC,IAAkCT,EAAM,WAG5C,CAAC,EAAE,WAAAC,GAAW,GAAGC,KAASC,wBACzB,KAAA,EAAE,KAAAA,GAAU,WAAWC,EAAG,yBAAyBH,CAAS,GAAI,GAAGC,GAAO,CAC5E;AACDO,EAAgC,cAAc;AAE9C,MAAMC,IAAyBV,EAAM,WAGnC,CAAC,EAAE,WAAAC,GAAW,GAAGC,EAAA,GAASC,MAC1B,gBAAAG;AAAA,EAAC;AAAA,EAAA;AAAA,IACC,KAAAH;AAAA,IACA,WAAWC,EAAG,qCAAqCH,CAAS;AAAA,IAC3D,GAAGC;AAAA,EAAA;AACN,CACD;AACDQ,EAAuB,cAAc;"}
@@ -0,0 +1,115 @@
1
+ import { jsxs as x, jsx as e } from "react/jsx-runtime";
2
+ import * as I from "react";
3
+ import { Progress as M } from "@base-ui/react/progress";
4
+ import { CircleCheckIcon as R, TriangleWarningIcon as g, CircleTimesIcon as j } from "@acronis-platform/icons-react/stroke-mono";
5
+ import { cva as P } from "../../../node_modules/.pnpm/class-variance-authority@0.7.1/node_modules/class-variance-authority/dist/index.js";
6
+ import { cn as c } from "../../../lib/utils.js";
7
+ const S = {
8
+ tiny: { d: 16, stroke: 2, font: "text-[10px] leading-none" },
9
+ sm: { d: 24, stroke: 3, font: "text-[10px] leading-none" },
10
+ md: { d: 40, stroke: 4, font: "text-xs font-semibold" },
11
+ lg: { d: 64, stroke: 5, font: "text-sm font-semibold" }
12
+ }, T = {
13
+ brand: "stroke-[var(--ui-background-brand-secondary)]",
14
+ danger: "stroke-[var(--ui-text-on-status-danger)]",
15
+ critical: "stroke-[var(--ui-text-on-status-critical)]",
16
+ warning: "stroke-[var(--ui-text-on-status-warning)]",
17
+ success: "stroke-[var(--ui-text-on-status-success)]"
18
+ }, _ = {
19
+ danger: /* @__PURE__ */ e(j, { className: "text-[var(--ui-text-on-status-danger)]" }),
20
+ critical: /* @__PURE__ */ e(g, { className: "text-[var(--ui-text-on-status-critical)]" }),
21
+ warning: /* @__PURE__ */ e(g, { className: "text-[var(--ui-text-on-status-warning)]" }),
22
+ success: /* @__PURE__ */ e(R, { className: "text-[var(--ui-text-on-status-success)]" })
23
+ };
24
+ function O(s) {
25
+ return s >= 0.8 ? "success" : s >= 0.6 ? "warning" : s >= 0.4 ? "critical" : "danger";
26
+ }
27
+ const W = P(
28
+ "relative inline-flex shrink-0 items-center justify-center",
29
+ {
30
+ variants: {
31
+ size: { tiny: "", sm: "", md: "", lg: "" }
32
+ },
33
+ defaultVariants: { size: "sm" }
34
+ }
35
+ ), $ = I.forwardRef(
36
+ ({
37
+ className: s,
38
+ value: l = 0,
39
+ max: n = 100,
40
+ size: u = "sm",
41
+ status: h,
42
+ showValue: k = !1,
43
+ showIcon: v = !1,
44
+ children: p,
45
+ ...N
46
+ }, y) => {
47
+ const { d: t, stroke: o, font: C } = S[u], w = n > 0 ? n : 100, a = Math.min(1, Math.max(0, l / w)), d = h ?? O(a), i = (t - o) / 2, f = 2 * Math.PI * i, r = t / 2, b = v ? _[d] : void 0, m = p ?? b ?? (k ? `${Math.round(a * 100)}%` : null);
48
+ return /* @__PURE__ */ x(
49
+ M.Root,
50
+ {
51
+ ref: y,
52
+ value: l,
53
+ max: n,
54
+ className: c(W({ size: u }), s),
55
+ style: { width: t, height: t },
56
+ ...N,
57
+ children: [
58
+ /* @__PURE__ */ x(
59
+ "svg",
60
+ {
61
+ width: t,
62
+ height: t,
63
+ viewBox: `0 0 ${t} ${t}`,
64
+ className: "-rotate-90",
65
+ "aria-hidden": "true",
66
+ children: [
67
+ /* @__PURE__ */ e(
68
+ "circle",
69
+ {
70
+ className: "stroke-[var(--ui-border-on-surface-border)]",
71
+ fill: "none",
72
+ strokeWidth: o,
73
+ cx: r,
74
+ cy: r,
75
+ r: i
76
+ }
77
+ ),
78
+ /* @__PURE__ */ e(
79
+ "circle",
80
+ {
81
+ className: c(T[d], "transition-[stroke-dashoffset]"),
82
+ fill: "none",
83
+ strokeWidth: o,
84
+ strokeLinecap: "round",
85
+ cx: r,
86
+ cy: r,
87
+ r: i,
88
+ strokeDasharray: f,
89
+ strokeDashoffset: f * (1 - a)
90
+ }
91
+ )
92
+ ]
93
+ }
94
+ ),
95
+ m != null && /* @__PURE__ */ e(
96
+ "span",
97
+ {
98
+ className: c(
99
+ "absolute inset-0 flex items-center justify-center text-foreground [&_svg]:size-[60%]",
100
+ C
101
+ ),
102
+ children: m
103
+ }
104
+ )
105
+ ]
106
+ }
107
+ );
108
+ }
109
+ );
110
+ $.displayName = "ProgressCircle";
111
+ export {
112
+ $ as ProgressCircle,
113
+ W as progressCircleVariants
114
+ };
115
+ //# sourceMappingURL=progress-circle.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"progress-circle.js","sources":["../../../../src/components/ui/progress-circle/progress-circle.tsx"],"sourcesContent":["'use client';\n\nimport * as React from 'react';\nimport { Progress as ProgressPrimitive } from '@base-ui/react/progress';\nimport {\n CircleCheckIcon,\n CircleTimesIcon,\n TriangleWarningIcon,\n} from '@acronis-platform/icons-react/stroke-mono';\nimport { cva, type VariantProps } from 'class-variance-authority';\n\nimport { cn } from '@/lib/utils';\n\n// A circular (radial) progress indicator — an SVG ring whose arc fills with the\n// value and whose color tracks the level (danger → critical → warning →\n// success). Built from the Cyber-Compliance \"Compliance %\" design (node\n// 2396-186059) and the Vue kit's `AvProgressRadial`. The ring is wrapped in the\n// Base UI Progress primitive so it carries the proper `role=\"progressbar\"` +\n// `aria-valuenow/min/max`; the visuals are a hand-drawn SVG (Base UI's Track/\n// Indicator are linear-only). No `--ui-progress-circle-*` tier — the arc uses the\n// shared status colors (`--ui-text-on-status-*`), the track the border token, and\n// the center label the surface foreground.\n\n// `brand` is the neutral single-color mode (matches the linear Progress accent);\n// the others are score levels. With no `status`, the level is derived from the\n// value (like the Vue ProgressRadial).\nexport type ProgressCircleStatus =\n | 'brand'\n | 'danger'\n | 'critical'\n | 'warning'\n | 'success';\n\n// Size → [diameter px, stroke px, center font class]. The table cell uses the\n// smaller sizes; lg suits cards/widgets.\nconst SIZES = {\n tiny: { d: 16, stroke: 2, font: 'text-[10px] leading-none' },\n sm: { d: 24, stroke: 3, font: 'text-[10px] leading-none' },\n md: { d: 40, stroke: 4, font: 'text-xs font-semibold' },\n lg: { d: 64, stroke: 5, font: 'text-sm font-semibold' },\n} as const;\n\nexport type ProgressCircleSize = keyof typeof SIZES;\n\nconst ARC_COLOR: Record<ProgressCircleStatus, string> = {\n brand: 'stroke-[var(--ui-background-brand-secondary)]',\n danger: 'stroke-[var(--ui-text-on-status-danger)]',\n critical: 'stroke-[var(--ui-text-on-status-critical)]',\n warning: 'stroke-[var(--ui-text-on-status-warning)]',\n success: 'stroke-[var(--ui-text-on-status-success)]',\n};\n\n// `brand` has no score icon — only the level statuses do.\nconst ICON_BY_STATUS: Partial<Record<ProgressCircleStatus, React.ReactNode>> = {\n danger: <CircleTimesIcon className=\"text-[var(--ui-text-on-status-danger)]\" />,\n critical: (\n <TriangleWarningIcon className=\"text-[var(--ui-text-on-status-critical)]\" />\n ),\n warning: (\n <TriangleWarningIcon className=\"text-[var(--ui-text-on-status-warning)]\" />\n ),\n success: (\n <CircleCheckIcon className=\"text-[var(--ui-text-on-status-success)]\" />\n ),\n};\n\n// Default value → status thresholds (confirm exact breakpoints with design — the\n// Figma shows ~25% danger, 50% critical, 75% warning, 80%+ success).\nfunction statusForFraction(fraction: number): ProgressCircleStatus {\n if (fraction >= 0.8) return 'success';\n if (fraction >= 0.6) return 'warning';\n if (fraction >= 0.4) return 'critical';\n return 'danger';\n}\n\nconst progressCircleVariants = cva(\n 'relative inline-flex shrink-0 items-center justify-center',\n {\n variants: {\n size: { tiny: '', sm: '', md: '', lg: '' },\n },\n defaultVariants: { size: 'sm' },\n }\n);\n\nexport interface ProgressCircleProps\n extends Omit<React.HTMLAttributes<HTMLDivElement>, 'children'>,\n VariantProps<typeof progressCircleVariants> {\n /** Current progress; clamped to `[0, max]`. */\n value?: number;\n /** Value representing full completion. */\n max?: number;\n /** Ring diameter + stroke. Defaults to `sm`. */\n size?: ProgressCircleSize;\n /** Color level for the arc. Omit to derive from `value`/`max` by thresholds. */\n status?: ProgressCircleStatus;\n /** Show the rounded percentage in the center. */\n showValue?: boolean;\n /** Show a status icon in the center (takes priority over `showValue`). */\n showIcon?: boolean;\n /** Custom center content (takes priority over icon/value). */\n children?: React.ReactNode;\n}\n\nconst ProgressCircle = React.forwardRef<HTMLDivElement, ProgressCircleProps>(\n (\n {\n className,\n value = 0,\n max = 100,\n size = 'sm',\n status,\n showValue = false,\n showIcon = false,\n children,\n ...props\n },\n ref\n ) => {\n const { d, stroke, font } = SIZES[size];\n const safeMax = max > 0 ? max : 100;\n const fraction = Math.min(1, Math.max(0, value / safeMax));\n const level = status ?? statusForFraction(fraction);\n const radius = (d - stroke) / 2;\n const circumference = 2 * Math.PI * radius;\n const center = d / 2;\n const icon = showIcon ? ICON_BY_STATUS[level] : undefined;\n const centerContent =\n children ?? icon ?? (showValue ? `${Math.round(fraction * 100)}%` : null);\n\n return (\n <ProgressPrimitive.Root\n ref={ref}\n value={value}\n max={max}\n className={cn(progressCircleVariants({ size }), className)}\n style={{ width: d, height: d }}\n {...props}\n >\n <svg\n width={d}\n height={d}\n viewBox={`0 0 ${d} ${d}`}\n className=\"-rotate-90\"\n aria-hidden=\"true\"\n >\n <circle\n className=\"stroke-[var(--ui-border-on-surface-border)]\"\n fill=\"none\"\n strokeWidth={stroke}\n cx={center}\n cy={center}\n r={radius}\n />\n <circle\n className={cn(ARC_COLOR[level], 'transition-[stroke-dashoffset]')}\n fill=\"none\"\n strokeWidth={stroke}\n strokeLinecap=\"round\"\n cx={center}\n cy={center}\n r={radius}\n strokeDasharray={circumference}\n strokeDashoffset={circumference * (1 - fraction)}\n />\n </svg>\n {centerContent != null && (\n <span\n className={cn(\n 'absolute inset-0 flex items-center justify-center text-foreground [&_svg]:size-[60%]',\n font\n )}\n >\n {centerContent}\n </span>\n )}\n </ProgressPrimitive.Root>\n );\n }\n);\nProgressCircle.displayName = 'ProgressCircle';\n\nexport { ProgressCircle, progressCircleVariants };\n"],"names":["SIZES","ARC_COLOR","ICON_BY_STATUS","jsx","CircleTimesIcon","TriangleWarningIcon","CircleCheckIcon","statusForFraction","fraction","progressCircleVariants","cva","ProgressCircle","React","className","value","max","size","status","showValue","showIcon","children","props","ref","d","stroke","font","safeMax","level","radius","circumference","center","icon","centerContent","jsxs","ProgressPrimitive","cn"],"mappings":"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"}
@@ -0,0 +1,80 @@
1
+ import { jsxs as l, jsx as e, Fragment as S } from "react/jsx-runtime";
2
+ import { Sheet as g, SheetTrigger as D, SheetContent as x, SheetHeader as N, SheetTitle as E, SheetCloseButton as L, SheetBody as T, SheetFooter as b } from "./sheet.js";
3
+ import { Spinner as j } from "../spinner/spinner.js";
4
+ import { Empty as w, EmptyHeader as B, EmptyTitle as v, EmptyDescription as C } from "../empty/empty.js";
5
+ import { DescriptionList as F, DescriptionListItem as H, DescriptionListLabel as I, DescriptionListValue as V } from "../description-list/description-list.js";
6
+ function k({
7
+ contentState: t,
8
+ properties: i,
9
+ children: n,
10
+ emptyTitle: h,
11
+ emptyDescription: d,
12
+ errorTitle: m,
13
+ errorDescription: s
14
+ }) {
15
+ if (t === "loading")
16
+ return /* @__PURE__ */ e("div", { className: "flex h-40 items-center justify-center", children: /* @__PURE__ */ e(j, {}) });
17
+ if (t === "empty" || t === "error") {
18
+ const r = t === "error";
19
+ return /* @__PURE__ */ e(w, { children: /* @__PURE__ */ l(B, { children: [
20
+ /* @__PURE__ */ e(v, { children: r ? m ?? "Something went wrong" : h ?? "Nothing to show" }),
21
+ /* @__PURE__ */ e(C, { children: r ? s ?? "The details could not be loaded." : d ?? "There are no details to display yet." })
22
+ ] }) });
23
+ }
24
+ return n ? /* @__PURE__ */ e(S, { children: n }) : i != null && i.length ? /* @__PURE__ */ e(
25
+ F,
26
+ {
27
+ className: "-mx-6",
28
+ style: { "--description-list-label": "9rem" },
29
+ children: i.map((r, o) => /* @__PURE__ */ l(H, { children: [
30
+ /* @__PURE__ */ e(I, { className: "text-muted-foreground", children: r.label }),
31
+ /* @__PURE__ */ e(V, { className: "font-medium", children: r.value })
32
+ ] }, o))
33
+ }
34
+ ) : null;
35
+ }
36
+ function q({
37
+ open: t,
38
+ defaultOpen: i,
39
+ onOpenChange: n,
40
+ title: h,
41
+ side: d = "right",
42
+ contentState: m = "content",
43
+ properties: s,
44
+ children: r,
45
+ actions: o,
46
+ trigger: c,
47
+ emptyTitle: a,
48
+ emptyDescription: u,
49
+ errorTitle: f,
50
+ errorDescription: y,
51
+ portalContainer: p
52
+ }) {
53
+ return /* @__PURE__ */ l(g, { open: t, defaultOpen: i, onOpenChange: n, children: [
54
+ c ? /* @__PURE__ */ e(D, { render: c }) : null,
55
+ /* @__PURE__ */ l(x, { side: d, portalContainer: p, children: [
56
+ /* @__PURE__ */ l(N, { children: [
57
+ /* @__PURE__ */ e(E, { children: h }),
58
+ /* @__PURE__ */ e(L, {})
59
+ ] }),
60
+ /* @__PURE__ */ e(T, { children: /* @__PURE__ */ e(
61
+ k,
62
+ {
63
+ contentState: m,
64
+ properties: s,
65
+ emptyTitle: a,
66
+ emptyDescription: u,
67
+ errorTitle: f,
68
+ errorDescription: y,
69
+ children: r
70
+ }
71
+ ) }),
72
+ o ? /* @__PURE__ */ e(b, { children: o }) : null
73
+ ] })
74
+ ] });
75
+ }
76
+ q.displayName = "SheetDetails";
77
+ export {
78
+ q as SheetDetails
79
+ };
80
+ //# sourceMappingURL=sheet-details.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sheet-details.js","sources":["../../../../src/components/ui/sheet/sheet-details.tsx"],"sourcesContent":["import * as React from 'react';\n\nimport {\n DescriptionList,\n DescriptionListItem,\n DescriptionListLabel,\n DescriptionListValue,\n} from '../description-list';\nimport {\n Empty,\n EmptyDescription,\n EmptyHeader,\n EmptyTitle,\n} from '../empty';\nimport { Spinner } from '../spinner';\nimport {\n Sheet,\n SheetBody,\n SheetCloseButton,\n type SheetContentProps,\n SheetContent,\n SheetFooter,\n SheetHeader,\n SheetTitle,\n SheetTrigger,\n} from './sheet';\n\n// `SheetDetails` is the preset for the `sheet-detail-panel` usage pattern — the\n// \"easy path that IS the pattern\". It bakes a right-anchored Sheet's header\n// (title + close), a body that switches by `contentState`\n// (loading → Spinner, empty/error → Empty, else a key/value property list or\n// custom children), and an optional footer of actions — so consumers don't\n// re-assemble (or hand-roll) the recipe. For anything outside the recipe, compose\n// the `Sheet*` parts directly. (React composition of the Vue kit's `Details`.)\n\nexport interface SheetDetailsProperty {\n label: React.ReactNode;\n value: React.ReactNode;\n}\n\nexport type SheetDetailsContentState = 'content' | 'loading' | 'empty' | 'error';\n\nexport interface SheetDetailsProps {\n /** Controlled open state. Pair with `onOpenChange`. */\n open?: boolean;\n /** Initial open state when uncontrolled. */\n defaultOpen?: boolean;\n /** Fires when the sheet opens or closes. */\n onOpenChange?: (open: boolean, eventDetails: unknown) => void;\n /** Panel title (header). Also the accessible name. */\n title: React.ReactNode;\n /** Edge the panel anchors to. Defaults to `right`. */\n side?: SheetContentProps['side'];\n /** Which body view to show. Defaults to `content`. */\n contentState?: SheetDetailsContentState;\n /** Key/value rows rendered as the body in the `content` state (unless `children`). */\n properties?: SheetDetailsProperty[];\n /** Custom body for the `content` state — overrides `properties`. */\n children?: React.ReactNode;\n /** Footer action(s). Omit for no footer. */\n actions?: React.ReactNode;\n /** Optional trigger element (rendered via the Sheet trigger's `render`). */\n trigger?: React.ReactElement;\n /** Empty-state copy (`contentState=\"empty\"`). */\n emptyTitle?: React.ReactNode;\n emptyDescription?: React.ReactNode;\n /** Error-state copy (`contentState=\"error\"`). */\n errorTitle?: React.ReactNode;\n errorDescription?: React.ReactNode;\n /** Portal container (shadow-root mount for isolated previews). */\n portalContainer?: SheetContentProps['portalContainer'];\n}\n\nfunction SheetDetailsBody({\n contentState,\n properties,\n children,\n emptyTitle,\n emptyDescription,\n errorTitle,\n errorDescription,\n}: Pick<\n SheetDetailsProps,\n | 'contentState'\n | 'properties'\n | 'children'\n | 'emptyTitle'\n | 'emptyDescription'\n | 'errorTitle'\n | 'errorDescription'\n>) {\n if (contentState === 'loading') {\n return (\n <div className=\"flex h-40 items-center justify-center\">\n <Spinner />\n </div>\n );\n }\n if (contentState === 'empty' || contentState === 'error') {\n const isError = contentState === 'error';\n return (\n <Empty>\n <EmptyHeader>\n <EmptyTitle>\n {isError\n ? (errorTitle ?? 'Something went wrong')\n : (emptyTitle ?? 'Nothing to show')}\n </EmptyTitle>\n <EmptyDescription>\n {isError\n ? (errorDescription ?? 'The details could not be loaded.')\n : (emptyDescription ?? 'There are no details to display yet.')}\n </EmptyDescription>\n </EmptyHeader>\n </Empty>\n );\n }\n if (children) return <>{children}</>;\n if (properties?.length) {\n // Render through DescriptionList. `-mx-6` cancels the SheetBody padding so\n // the row dividers go full-bleed while the content stays aligned at the\n // panel's 24px inset; the label column is tightened for the narrow panel.\n return (\n <DescriptionList\n className=\"-mx-6\"\n style={{ '--description-list-label': '9rem' } as React.CSSProperties}\n >\n {properties.map((p, i) => (\n <DescriptionListItem key={i}>\n <DescriptionListLabel className=\"text-muted-foreground\">\n {p.label}\n </DescriptionListLabel>\n <DescriptionListValue className=\"font-medium\">\n {p.value}\n </DescriptionListValue>\n </DescriptionListItem>\n ))}\n </DescriptionList>\n );\n }\n return null;\n}\n\nfunction SheetDetails({\n open,\n defaultOpen,\n onOpenChange,\n title,\n side = 'right',\n contentState = 'content',\n properties,\n children,\n actions,\n trigger,\n emptyTitle,\n emptyDescription,\n errorTitle,\n errorDescription,\n portalContainer,\n}: SheetDetailsProps) {\n return (\n <Sheet open={open} defaultOpen={defaultOpen} onOpenChange={onOpenChange}>\n {trigger ? <SheetTrigger render={trigger} /> : null}\n <SheetContent side={side} portalContainer={portalContainer}>\n <SheetHeader>\n <SheetTitle>{title}</SheetTitle>\n <SheetCloseButton />\n </SheetHeader>\n <SheetBody>\n <SheetDetailsBody\n contentState={contentState}\n properties={properties}\n emptyTitle={emptyTitle}\n emptyDescription={emptyDescription}\n errorTitle={errorTitle}\n errorDescription={errorDescription}\n >\n {children}\n </SheetDetailsBody>\n </SheetBody>\n {actions ? <SheetFooter>{actions}</SheetFooter> : null}\n </SheetContent>\n </Sheet>\n );\n}\nSheetDetails.displayName = 'SheetDetails';\n\nexport { SheetDetails };\n"],"names":["SheetDetailsBody","contentState","properties","children","emptyTitle","emptyDescription","errorTitle","errorDescription","jsx","Spinner","isError","Empty","jsxs","EmptyHeader","EmptyTitle","EmptyDescription","Fragment","DescriptionList","p","i","DescriptionListItem","DescriptionListLabel","DescriptionListValue","SheetDetails","open","defaultOpen","onOpenChange","title","side","actions","trigger","portalContainer","Sheet","SheetTrigger","SheetContent","SheetHeader","SheetTitle","SheetCloseButton","SheetBody","SheetFooter"],"mappings":";;;;;AAyEA,SAASA,EAAiB;AAAA,EACxB,cAAAC;AAAA,EACA,YAAAC;AAAA,EACA,UAAAC;AAAA,EACA,YAAAC;AAAA,EACA,kBAAAC;AAAA,EACA,YAAAC;AAAA,EACA,kBAAAC;AACF,GASG;AACD,MAAIN,MAAiB;AACnB,6BACG,OAAA,EAAI,WAAU,yCACb,UAAA,gBAAAO,EAACC,KAAQ,GACX;AAGJ,MAAIR,MAAiB,WAAWA,MAAiB,SAAS;AACxD,UAAMS,IAAUT,MAAiB;AACjC,WACE,gBAAAO,EAACG,GAAA,EACC,UAAA,gBAAAC,EAACC,GAAA,EACC,UAAA;AAAA,MAAA,gBAAAL,EAACM,GAAA,EACE,UAAAJ,IACIJ,KAAc,yBACdF,KAAc,mBACrB;AAAA,wBACCW,GAAA,EACE,UAAAL,IACIH,KAAoB,qCACpBF,KAAoB,uCAAA,CAC3B;AAAA,IAAA,EAAA,CACF,EAAA,CACF;AAAA,EAEJ;AACA,SAAIF,IAAiB,gBAAAK,EAAAQ,GAAA,EAAG,UAAAb,EAAA,CAAS,IAC7BD,KAAA,QAAAA,EAAY,SAKZ,gBAAAM;AAAA,IAACS;AAAA,IAAA;AAAA,MACC,WAAU;AAAA,MACV,OAAO,EAAE,4BAA4B,OAAA;AAAA,MAEpC,YAAW,IAAI,CAACC,GAAGC,wBACjBC,GAAA,EACC,UAAA;AAAA,QAAA,gBAAAZ,EAACa,GAAA,EAAqB,WAAU,yBAC7B,UAAAH,EAAE,OACL;AAAA,QACA,gBAAAV,EAACc,GAAA,EAAqB,WAAU,eAC7B,YAAE,MAAA,CACL;AAAA,MAAA,EAAA,GANwBH,CAO1B,CACD;AAAA,IAAA;AAAA,EAAA,IAIA;AACT;AAEA,SAASI,EAAa;AAAA,EACpB,MAAAC;AAAA,EACA,aAAAC;AAAA,EACA,cAAAC;AAAA,EACA,OAAAC;AAAA,EACA,MAAAC,IAAO;AAAA,EACP,cAAA3B,IAAe;AAAA,EACf,YAAAC;AAAA,EACA,UAAAC;AAAA,EACA,SAAA0B;AAAA,EACA,SAAAC;AAAA,EACA,YAAA1B;AAAA,EACA,kBAAAC;AAAA,EACA,YAAAC;AAAA,EACA,kBAAAC;AAAA,EACA,iBAAAwB;AACF,GAAsB;AACpB,SACE,gBAAAnB,EAACoB,GAAA,EAAM,MAAAR,GAAY,aAAAC,GAA0B,cAAAC,GAC1C,UAAA;AAAA,IAAAI,IAAU,gBAAAtB,EAACyB,GAAA,EAAa,QAAQH,EAAA,CAAS,IAAK;AAAA,IAC/C,gBAAAlB,EAACsB,GAAA,EAAa,MAAAN,GAAY,iBAAAG,GACxB,UAAA;AAAA,MAAA,gBAAAnB,EAACuB,GAAA,EACC,UAAA;AAAA,QAAA,gBAAA3B,EAAC4B,KAAY,UAAAT,EAAA,CAAM;AAAA,0BAClBU,GAAA,CAAA,CAAiB;AAAA,MAAA,GACpB;AAAA,wBACCC,GAAA,EACC,UAAA,gBAAA9B;AAAA,QAACR;AAAA,QAAA;AAAA,UACC,cAAAC;AAAA,UACA,YAAAC;AAAA,UACA,YAAAE;AAAA,UACA,kBAAAC;AAAA,UACA,YAAAC;AAAA,UACA,kBAAAC;AAAA,UAEC,UAAAJ;AAAA,QAAA;AAAA,MAAA,GAEL;AAAA,MACC0B,IAAU,gBAAArB,EAAC+B,GAAA,EAAa,UAAAV,EAAA,CAAQ,IAAiB;AAAA,IAAA,EAAA,CACpD;AAAA,EAAA,GACF;AAEJ;AACAN,EAAa,cAAc;"}