@clef-sh/ui 0.1.20 → 0.1.21
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/client/assets/index-DPWHjBbB.js +34 -0
- package/dist/client/assets/index-qsLTYpc9.css +2 -0
- package/dist/client/clef.svg +2 -0
- package/dist/client/index.html +3 -31
- package/dist/client-lib/components/Button.d.ts +1 -1
- package/dist/client-lib/components/Button.d.ts.map +1 -1
- package/dist/client-lib/components/CopyButton.d.ts.map +1 -1
- package/dist/client-lib/components/EnvBadge.d.ts.map +1 -1
- package/dist/client-lib/components/MatrixGrid.d.ts.map +1 -1
- package/dist/client-lib/components/Sidebar.d.ts +1 -1
- package/dist/client-lib/components/Sidebar.d.ts.map +1 -1
- package/dist/client-lib/components/StatusDot.d.ts.map +1 -1
- package/dist/client-lib/components/SyncPanel.d.ts.map +1 -1
- package/dist/client-lib/components/TopBar.d.ts +6 -0
- package/dist/client-lib/components/TopBar.d.ts.map +1 -1
- package/dist/client-lib/primitives/Badge.d.ts +11 -0
- package/dist/client-lib/primitives/Badge.d.ts.map +1 -0
- package/dist/client-lib/primitives/Card.d.ts +28 -0
- package/dist/client-lib/primitives/Card.d.ts.map +1 -0
- package/dist/client-lib/primitives/Dialog.d.ts +30 -0
- package/dist/client-lib/primitives/Dialog.d.ts.map +1 -0
- package/dist/client-lib/primitives/EmptyState.d.ts +10 -0
- package/dist/client-lib/primitives/EmptyState.d.ts.map +1 -0
- package/dist/client-lib/primitives/Field.d.ts +36 -0
- package/dist/client-lib/primitives/Field.d.ts.map +1 -0
- package/dist/client-lib/primitives/Input.d.ts +6 -0
- package/dist/client-lib/primitives/Input.d.ts.map +1 -0
- package/dist/client-lib/primitives/Stat.d.ts +11 -0
- package/dist/client-lib/primitives/Stat.d.ts.map +1 -0
- package/dist/client-lib/primitives/Table.d.ts +37 -0
- package/dist/client-lib/primitives/Table.d.ts.map +1 -0
- package/dist/client-lib/primitives/Tabs.d.ts +29 -0
- package/dist/client-lib/primitives/Tabs.d.ts.map +1 -0
- package/dist/client-lib/primitives/Toast.d.ts +16 -0
- package/dist/client-lib/primitives/Toast.d.ts.map +1 -0
- package/dist/client-lib/primitives/Toolbar.d.ts +29 -0
- package/dist/client-lib/primitives/Toolbar.d.ts.map +1 -0
- package/dist/client-lib/primitives/index.d.ts +23 -0
- package/dist/client-lib/primitives/index.d.ts.map +1 -0
- package/dist/client-lib/theme.d.ts +18 -41
- package/dist/client-lib/theme.d.ts.map +1 -1
- package/dist/server/api.d.ts.map +1 -1
- package/dist/server/api.js +215 -0
- package/dist/server/api.js.map +1 -1
- package/dist/server/envelope.d.ts +15 -0
- package/dist/server/envelope.d.ts.map +1 -0
- package/dist/server/envelope.js +310 -0
- package/dist/server/envelope.js.map +1 -0
- package/package.json +7 -2
- package/src/client/App.tsx +16 -41
- package/src/client/components/Button.tsx +13 -22
- package/src/client/components/CopyButton.tsx +5 -12
- package/src/client/components/EnvBadge.tsx +30 -15
- package/src/client/components/MatrixGrid.tsx +108 -252
- package/src/client/components/Sidebar.tsx +123 -199
- package/src/client/components/StatusDot.tsx +10 -15
- package/src/client/components/SyncPanel.tsx +14 -62
- package/src/client/components/TopBar.tsx +11 -36
- package/src/client/index.html +1 -30
- package/src/client/main.tsx +1 -0
- package/src/client/primitives/Badge.test.tsx +47 -0
- package/src/client/primitives/Badge.tsx +64 -0
- package/src/client/primitives/Card.test.tsx +50 -0
- package/src/client/primitives/Card.tsx +85 -0
- package/src/client/primitives/Dialog.test.tsx +55 -0
- package/src/client/primitives/Dialog.tsx +96 -0
- package/src/client/primitives/EmptyState.test.tsx +25 -0
- package/src/client/primitives/EmptyState.tsx +38 -0
- package/src/client/primitives/Field.test.tsx +46 -0
- package/src/client/primitives/Field.tsx +95 -0
- package/src/client/primitives/Input.tsx +26 -0
- package/src/client/primitives/Stat.test.tsx +32 -0
- package/src/client/primitives/Stat.tsx +52 -0
- package/src/client/primitives/Table.test.tsx +58 -0
- package/src/client/primitives/Table.tsx +113 -0
- package/src/client/primitives/Tabs.test.tsx +44 -0
- package/src/client/primitives/Tabs.tsx +100 -0
- package/src/client/primitives/Toast.test.tsx +77 -0
- package/src/client/primitives/Toast.tsx +89 -0
- package/src/client/primitives/Toolbar.test.tsx +50 -0
- package/src/client/primitives/Toolbar.tsx +86 -0
- package/src/client/primitives/index.ts +43 -0
- package/src/client/public/clef.svg +2 -0
- package/src/client/screens/BackendScreen.tsx +104 -363
- package/src/client/screens/DiffView.tsx +187 -378
- package/src/client/screens/EnvelopeScreen.test.tsx +542 -0
- package/src/client/screens/EnvelopeScreen.tsx +948 -0
- package/src/client/screens/GitLogView.tsx +48 -106
- package/src/client/screens/ImportScreen.tsx +105 -308
- package/src/client/screens/LintView.tsx +184 -379
- package/src/client/screens/ManifestScreen.tsx +283 -445
- package/src/client/screens/MatrixView.tsx +75 -91
- package/src/client/screens/NamespaceEditor.tsx +234 -609
- package/src/client/screens/PolicyView.tsx +183 -453
- package/src/client/screens/RecipientsScreen.tsx +71 -350
- package/src/client/screens/ResetScreen.tsx +67 -237
- package/src/client/screens/ScanScreen.tsx +85 -249
- package/src/client/screens/SchemaEditor.test.tsx +237 -0
- package/src/client/screens/SchemaEditor.tsx +435 -0
- package/src/client/screens/ServiceIdentitiesScreen.tsx +251 -788
- package/src/client/styles.css +77 -0
- package/src/client/theme.ts +27 -48
- package/dist/client/assets/index-Db6WgHgY.js +0 -38
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import { render, screen } from "@testing-library/react";
|
|
3
|
+
import "@testing-library/jest-dom";
|
|
4
|
+
import { Toolbar } from "./Toolbar";
|
|
5
|
+
|
|
6
|
+
describe("Toolbar", () => {
|
|
7
|
+
it("renders title, subtitle, and actions", () => {
|
|
8
|
+
render(
|
|
9
|
+
<Toolbar data-testid="toolbar">
|
|
10
|
+
<div>
|
|
11
|
+
<Toolbar.Title>Secret Matrix</Toolbar.Title>
|
|
12
|
+
<Toolbar.Subtitle>3 namespaces</Toolbar.Subtitle>
|
|
13
|
+
</div>
|
|
14
|
+
<Toolbar.Actions>
|
|
15
|
+
<button>Lint All</button>
|
|
16
|
+
</Toolbar.Actions>
|
|
17
|
+
</Toolbar>,
|
|
18
|
+
);
|
|
19
|
+
expect(screen.getByTestId("toolbar")).toBeInTheDocument();
|
|
20
|
+
expect(screen.getByRole("heading", { name: "Secret Matrix" })).toBeInTheDocument();
|
|
21
|
+
expect(screen.getByText("3 namespaces")).toBeInTheDocument();
|
|
22
|
+
expect(screen.getByRole("button", { name: "Lint All" })).toBeInTheDocument();
|
|
23
|
+
});
|
|
24
|
+
|
|
25
|
+
it("title uses upgraded type tier classes", () => {
|
|
26
|
+
render(
|
|
27
|
+
<Toolbar>
|
|
28
|
+
<Toolbar.Title>Hello</Toolbar.Title>
|
|
29
|
+
</Toolbar>,
|
|
30
|
+
);
|
|
31
|
+
const heading = screen.getByRole("heading", { name: "Hello" });
|
|
32
|
+
expect(heading.className).toContain("text-[20px]");
|
|
33
|
+
expect(heading.className).toContain("font-semibold");
|
|
34
|
+
expect(heading.className).toContain("text-bone");
|
|
35
|
+
});
|
|
36
|
+
|
|
37
|
+
it("actions wrapper applies flex gap classes", () => {
|
|
38
|
+
render(
|
|
39
|
+
<Toolbar>
|
|
40
|
+
<Toolbar.Actions data-testid="acts">
|
|
41
|
+
<button>a</button>
|
|
42
|
+
<button>b</button>
|
|
43
|
+
</Toolbar.Actions>
|
|
44
|
+
</Toolbar>,
|
|
45
|
+
);
|
|
46
|
+
const wrap = screen.getByTestId("acts");
|
|
47
|
+
expect(wrap.className).toContain("flex");
|
|
48
|
+
expect(wrap.className).toContain("gap-2");
|
|
49
|
+
});
|
|
50
|
+
});
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
|
|
3
|
+
function joinClasses(...parts: Array<string | false | null | undefined>): string {
|
|
4
|
+
return parts.filter(Boolean).join(" ");
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
export interface ToolbarProps extends React.HTMLAttributes<HTMLDivElement> {
|
|
8
|
+
className?: string;
|
|
9
|
+
children?: React.ReactNode;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
const ToolbarRoot = React.forwardRef<HTMLDivElement, ToolbarProps>(function Toolbar(
|
|
13
|
+
{ className, children, ...rest },
|
|
14
|
+
ref,
|
|
15
|
+
) {
|
|
16
|
+
return (
|
|
17
|
+
<div
|
|
18
|
+
ref={ref}
|
|
19
|
+
className={joinClasses(
|
|
20
|
+
"flex items-center justify-between px-7 py-5 border-b border-edge bg-ink-900",
|
|
21
|
+
className,
|
|
22
|
+
)}
|
|
23
|
+
{...rest}
|
|
24
|
+
>
|
|
25
|
+
{children}
|
|
26
|
+
</div>
|
|
27
|
+
);
|
|
28
|
+
});
|
|
29
|
+
|
|
30
|
+
export interface ToolbarTitleProps extends React.HTMLAttributes<HTMLHeadingElement> {
|
|
31
|
+
className?: string;
|
|
32
|
+
children?: React.ReactNode;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
function ToolbarTitle({ className, children, ...rest }: ToolbarTitleProps) {
|
|
36
|
+
return (
|
|
37
|
+
<h1
|
|
38
|
+
className={joinClasses(
|
|
39
|
+
"text-[20px] font-semibold text-bone tracking-[-0.015em] m-0",
|
|
40
|
+
className,
|
|
41
|
+
)}
|
|
42
|
+
{...rest}
|
|
43
|
+
>
|
|
44
|
+
{children}
|
|
45
|
+
</h1>
|
|
46
|
+
);
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
export interface ToolbarSubtitleProps extends React.HTMLAttributes<HTMLDivElement> {
|
|
50
|
+
className?: string;
|
|
51
|
+
children?: React.ReactNode;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
function ToolbarSubtitle({ className, children, ...rest }: ToolbarSubtitleProps) {
|
|
55
|
+
return (
|
|
56
|
+
<div className={joinClasses("font-mono text-[11px] text-ash-dim", className)} {...rest}>
|
|
57
|
+
{children}
|
|
58
|
+
</div>
|
|
59
|
+
);
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
export interface ToolbarActionsProps extends React.HTMLAttributes<HTMLDivElement> {
|
|
63
|
+
className?: string;
|
|
64
|
+
children?: React.ReactNode;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
function ToolbarActions({ className, children, ...rest }: ToolbarActionsProps) {
|
|
68
|
+
return (
|
|
69
|
+
<div className={joinClasses("flex gap-2", className)} {...rest}>
|
|
70
|
+
{children}
|
|
71
|
+
</div>
|
|
72
|
+
);
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
type ToolbarCompound = typeof ToolbarRoot & {
|
|
76
|
+
Title: typeof ToolbarTitle;
|
|
77
|
+
Subtitle: typeof ToolbarSubtitle;
|
|
78
|
+
Actions: typeof ToolbarActions;
|
|
79
|
+
};
|
|
80
|
+
|
|
81
|
+
const Toolbar = ToolbarRoot as ToolbarCompound;
|
|
82
|
+
Toolbar.Title = ToolbarTitle;
|
|
83
|
+
Toolbar.Subtitle = ToolbarSubtitle;
|
|
84
|
+
Toolbar.Actions = ToolbarActions;
|
|
85
|
+
|
|
86
|
+
export { Toolbar };
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
export { Card } from "./Card";
|
|
2
|
+
export type { CardProps, CardHeaderProps, CardBodyProps } from "./Card";
|
|
3
|
+
|
|
4
|
+
export { Toolbar } from "./Toolbar";
|
|
5
|
+
export type {
|
|
6
|
+
ToolbarProps,
|
|
7
|
+
ToolbarTitleProps,
|
|
8
|
+
ToolbarSubtitleProps,
|
|
9
|
+
ToolbarActionsProps,
|
|
10
|
+
} from "./Toolbar";
|
|
11
|
+
|
|
12
|
+
export { Stat } from "./Stat";
|
|
13
|
+
export type { StatProps, StatTone } from "./Stat";
|
|
14
|
+
|
|
15
|
+
export { Field } from "./Field";
|
|
16
|
+
export type { FieldProps, FieldLabelProps, FieldHintProps, FieldErrorProps } from "./Field";
|
|
17
|
+
|
|
18
|
+
export { Input, Textarea } from "./Input";
|
|
19
|
+
export type { InputProps, TextareaProps } from "./Input";
|
|
20
|
+
|
|
21
|
+
export { EmptyState } from "./EmptyState";
|
|
22
|
+
export type { EmptyStateProps } from "./EmptyState";
|
|
23
|
+
|
|
24
|
+
export { Table } from "./Table";
|
|
25
|
+
export type {
|
|
26
|
+
TableProps,
|
|
27
|
+
TableHeaderProps,
|
|
28
|
+
TableHeaderCellProps,
|
|
29
|
+
TableRowProps,
|
|
30
|
+
TableCellProps,
|
|
31
|
+
} from "./Table";
|
|
32
|
+
|
|
33
|
+
export { Tabs } from "./Tabs";
|
|
34
|
+
export type { TabsProps, TabsListProps, TabsTabProps, TabsPanelProps } from "./Tabs";
|
|
35
|
+
|
|
36
|
+
export { Dialog } from "./Dialog";
|
|
37
|
+
export type { DialogProps, DialogTitleProps, DialogBodyProps, DialogFooterProps } from "./Dialog";
|
|
38
|
+
|
|
39
|
+
export { ToastProvider, useToast } from "./Toast";
|
|
40
|
+
export type { ToastTone, ToastOptions, ToastProviderProps } from "./Toast";
|
|
41
|
+
|
|
42
|
+
export { Badge } from "./Badge";
|
|
43
|
+
export type { BadgeProps, BadgeTone, BadgeVariant } from "./Badge";
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
|
2
|
+
<svg xmlns="http://www.w3.org/2000/svg" style="background: transparent; background-color: transparent; color-scheme: light dark;" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" width="11px" height="30px" viewBox="0 0 11 30" content="<mxfile host="app.diagrams.net" agent="Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/145.0.0.0 Safari/537.36" version="29.6.1"> <diagram name="Page-1" id="wkVNsO5_5GyDIFuGEuFO"> <mxGraphModel dx="322" dy="155" grid="1" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="1" pageScale="1" pageWidth="850" pageHeight="1100" math="0" shadow="0"> <root> <mxCell id="0" /> <mxCell id="1" parent="0" /> <mxCell id="3N7BDEdEHleT6AeHqIXh-2" parent="1" style="shape=image;verticalLabelPosition=bottom;labelBackgroundColor=default;verticalAlign=top;aspect=fixed;imageAspect=0;editableCssRules=.*;image=data:image/svg+xml,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rIiB3aWR0aD0iMTUuMTg1NDg3NzQ3MTkyMzgzIiBzdHJva2U9IiNGMEE1MDAiIGZpbGw9IiNGMEE1MDAiIHZlcnNpb249IjEuMSIgaGVpZ2h0PSI0MC43NjgyMTEzNjQ3NDYwOTQiIHZpZXdCb3g9IjAuMDAwMDIyODg4MTgzNTkzNzUgLTAuMDAwNDAwMDY2Mzc1NzMyNDIxOSAxNS4xODU0ODc3NDcxOTIzODMgNDAuNzY4MjExMzY0NzQ2MDk0Ij4mI3hhOzxwYXRoIGQ9Im0xMi4wNDkgMy41Mjk2YzAuMzA1IDMuMTI2My0yLjAxOSA1LjY1NjMtNC4wNzcyIDcuNzAxNC0wLjkzNDkgMC44OTctMC4xNTUgMC4xNDgtMC42NDM3IDAuNTk0LTAuMTAyMi0wLjQ3OS0wLjI5ODYtMS43MzEtMC4yODAyLTIuMTEgMC4xMzA0LTIuNjkzOSAyLjMxOTgtNi41ODc1IDQuMjM4MS04LjAyMzYgMC4zMDkgMC41NzY3IDAuNTYzIDAuNjIzMSAwLjc2MyAxLjgzODJ6bTAuNjUxIDE2LjE0MmMtMS4yMzItMC45MDYtMi44NS0xLjE0NC00LjMzMzYtMC44ODUtMC4xOTEzLTEuMjU1LTAuMzgyNy0yLjUxLTAuNTc0LTMuNzY0IDIuMzUwNi0yLjMyOSA0LjkwNjYtNS4wMzIyIDUuMDQwNi04LjUzOTQgMC4wNTktMi4yMzItMC4yNzYtNC42NzE0LTEuNjc4LTYuNDgzNi0xLjcwMDQgMC4xMjgyMy0yLjg5OTUgMi4xNTYtMy44MDE5IDMuNDE2NS0xLjQ4ODkgMi42NzA1LTEuMTQxNCA1LjkxNjktMC41NyA4Ljc5NjUtMC44MDk0IDAuOTUyLTEuOTI5NiAxLjc0My0yLjcyNzQgMi43MzQtMi4zNTYxIDIuMzA4LTQuNDA4NSA1LjQzLTQuMDA0NiA4Ljg3OCAwLjE4MzMyIDMuMzM0IDIuNTg5NCA2LjQzNCA1Ljg3MDIgNy4yMjcgMS4yNDU3IDAuMzE1IDIuNTYzOSAwLjM0NiAzLjgyNDEgMC4wOTkgMC4yMTk5IDIuMjUgMS4wMjY2IDQuNjI5IDAuMDkyNSA2LjgxMy0wLjcwMDcgMS41OTgtMi43ODc1IDMuMDA0LTQuMzMyNSAyLjE5Mi0wLjU5OTQtMC4zMTYtMC4xMTM3LTAuMDUxLTAuNDc4LTAuMjUyIDEuMDY5OC0wLjI1NyAxLjk5OTYtMS4wMzYgMi4yNi0xLjU2NSAwLjgzNzgtMS40NjQtMC4zOTk4LTMuNjM5LTIuMTU1NC0zLjM1OC0yLjI2MiAwLjA0Ni0zLjE5MDQgMy4xNC0xLjczNTYgNC42ODUgMS4zNDY4IDEuNTIgMy44MzMgMS4zMTIgNS40MzAxIDAuMzE4IDEuODEyNS0xLjE4IDIuMDM5NS0zLjU0NCAxLjgzMjUtNS41NjItMC4wNy0wLjY3OC0wLjQwMy0yLjY3LTAuNDQ0LTMuMzg3IDAuNjk3LTAuMjQ5IDAuMjA5LTAuMDU5IDEuMTkzLTAuNDQ5IDIuNjYtMS4wNTMgNC4zNTctNC4yNTkgMy41OTQtNy4xMjItMC4zMTgtMS40NjktMS4wNDQtMi45MTQtMi4zMDItMy43OTJ6bTAuNTYxIDUuNzU3YzAuMjE0IDEuOTkxLTEuMDUzIDQuMzIxLTMuMDc5IDQuOTYtMC4xMzYtMC43OTUtMC4xNzItMS4wMTEtMC4yNjI2LTEuNDc1LTAuNDgyMi0yLjQ2LTAuNzQ0LTQuOTg3LTEuMTE2LTcuNDgxIDEuNjI0Ni0wLjE2OCAzLjQ1NzYgMC41NDMgNC4wMjI2IDIuMTg0IDAuMjQ0IDAuNTc3IDAuMzQzIDEuMTk3IDAuNDM1IDEuODEyem0tNS4xNDg2IDUuMTk2Yy0yLjU0NDEgMC4xNDEtNC45OTk1LTEuNTk1LTUuNjM0My00LjA4MS0wLjc0OS0yLjE1My0wLjUyODMtNC42MyAwLjgyMDctNi41MDQgMS4xMTUxLTEuNzAyIDIuNjA2NS0zLjEwNSA0LjAyODYtNC41NDMgMC4xODMgMS4xMjcgMC4zNjYgMi4yNTQgMC41NDkgMy4zODItMi45OTA2IDAuNzgyLTUuMDA0NiA0LjcyNS0zLjIxNSA3LjQ1MSAwLjUzMjQgMC43NjQgMS45NzY1IDIuMjIzIDIuNzY1NSAxLjYzNC0xLjEwMi0wLjY4My0yLjAwMzMtMS44NTktMS44MDk1LTMuMjI3LTAuMDgyMS0xLjI4MiAxLjM2OTktMi45MTEgMi42NTEzLTMuMTk4IDAuNDM4NCAyLjg2OSAwLjk0MTMgNi4wNzMgMS4zNzk3IDguOTQzLTAuNTA1NCAwLjEtMS4wMjExIDAuMTQzLTEuNTM2IDAuMTQzeiIvPiYjeGE7PC9zdmc+;" value="" vertex="1"> <mxGeometry height="30" width="10.98" x="450" y="220" as="geometry" /> </mxCell> </root> </mxGraphModel> </diagram> </mxfile> "><defs/><g><g data-cell-id="0"><g data-cell-id="1"><g data-cell-id="3N7BDEdEHleT6AeHqIXh-2"><g><image x="0" y="0" width="10.98" height="30" xlink:href="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rIiB3aWR0aD0iMTUuMTg1NDg3NzQ3MTkyMzgzIiBzdHJva2U9IiNGMEE1MDAiIGZpbGw9IiNGMEE1MDAiIHZlcnNpb249IjEuMSIgaGVpZ2h0PSI0MC43NjgyMTEzNjQ3NDYwOTQiIHZpZXdCb3g9IjAuMDAwMDIyODg4MTgzNTkzNzUgLTAuMDAwNDAwMDY2Mzc1NzMyNDIxOSAxNS4xODU0ODc3NDcxOTIzODMgNDAuNzY4MjExMzY0NzQ2MDk0Ij4mI3hhOzxwYXRoIGQ9Im0xMi4wNDkgMy41Mjk2YzAuMzA1IDMuMTI2My0yLjAxOSA1LjY1NjMtNC4wNzcyIDcuNzAxNC0wLjkzNDkgMC44OTctMC4xNTUgMC4xNDgtMC42NDM3IDAuNTk0LTAuMTAyMi0wLjQ3OS0wLjI5ODYtMS43MzEtMC4yODAyLTIuMTEgMC4xMzA0LTIuNjkzOSAyLjMxOTgtNi41ODc1IDQuMjM4MS04LjAyMzYgMC4zMDkgMC41NzY3IDAuNTYzIDAuNjIzMSAwLjc2MyAxLjgzODJ6bTAuNjUxIDE2LjE0MmMtMS4yMzItMC45MDYtMi44NS0xLjE0NC00LjMzMzYtMC44ODUtMC4xOTEzLTEuMjU1LTAuMzgyNy0yLjUxLTAuNTc0LTMuNzY0IDIuMzUwNi0yLjMyOSA0LjkwNjYtNS4wMzIyIDUuMDQwNi04LjUzOTQgMC4wNTktMi4yMzItMC4yNzYtNC42NzE0LTEuNjc4LTYuNDgzNi0xLjcwMDQgMC4xMjgyMy0yLjg5OTUgMi4xNTYtMy44MDE5IDMuNDE2NS0xLjQ4ODkgMi42NzA1LTEuMTQxNCA1LjkxNjktMC41NyA4Ljc5NjUtMC44MDk0IDAuOTUyLTEuOTI5NiAxLjc0My0yLjcyNzQgMi43MzQtMi4zNTYxIDIuMzA4LTQuNDA4NSA1LjQzLTQuMDA0NiA4Ljg3OCAwLjE4MzMyIDMuMzM0IDIuNTg5NCA2LjQzNCA1Ljg3MDIgNy4yMjcgMS4yNDU3IDAuMzE1IDIuNTYzOSAwLjM0NiAzLjgyNDEgMC4wOTkgMC4yMTk5IDIuMjUgMS4wMjY2IDQuNjI5IDAuMDkyNSA2LjgxMy0wLjcwMDcgMS41OTgtMi43ODc1IDMuMDA0LTQuMzMyNSAyLjE5Mi0wLjU5OTQtMC4zMTYtMC4xMTM3LTAuMDUxLTAuNDc4LTAuMjUyIDEuMDY5OC0wLjI1NyAxLjk5OTYtMS4wMzYgMi4yNi0xLjU2NSAwLjgzNzgtMS40NjQtMC4zOTk4LTMuNjM5LTIuMTU1NC0zLjM1OC0yLjI2MiAwLjA0Ni0zLjE5MDQgMy4xNC0xLjczNTYgNC42ODUgMS4zNDY4IDEuNTIgMy44MzMgMS4zMTIgNS40MzAxIDAuMzE4IDEuODEyNS0xLjE4IDIuMDM5NS0zLjU0NCAxLjgzMjUtNS41NjItMC4wNy0wLjY3OC0wLjQwMy0yLjY3LTAuNDQ0LTMuMzg3IDAuNjk3LTAuMjQ5IDAuMjA5LTAuMDU5IDEuMTkzLTAuNDQ5IDIuNjYtMS4wNTMgNC4zNTctNC4yNTkgMy41OTQtNy4xMjItMC4zMTgtMS40NjktMS4wNDQtMi45MTQtMi4zMDItMy43OTJ6bTAuNTYxIDUuNzU3YzAuMjE0IDEuOTkxLTEuMDUzIDQuMzIxLTMuMDc5IDQuOTYtMC4xMzYtMC43OTUtMC4xNzItMS4wMTEtMC4yNjI2LTEuNDc1LTAuNDgyMi0yLjQ2LTAuNzQ0LTQuOTg3LTEuMTE2LTcuNDgxIDEuNjI0Ni0wLjE2OCAzLjQ1NzYgMC41NDMgNC4wMjI2IDIuMTg0IDAuMjQ0IDAuNTc3IDAuMzQzIDEuMTk3IDAuNDM1IDEuODEyem0tNS4xNDg2IDUuMTk2Yy0yLjU0NDEgMC4xNDEtNC45OTk1LTEuNTk1LTUuNjM0My00LjA4MS0wLjc0OS0yLjE1My0wLjUyODMtNC42MyAwLjgyMDctNi41MDQgMS4xMTUxLTEuNzAyIDIuNjA2NS0zLjEwNSA0LjAyODYtNC41NDMgMC4xODMgMS4xMjcgMC4zNjYgMi4yNTQgMC41NDkgMy4zODItMi45OTA2IDAuNzgyLTUuMDA0NiA0LjcyNS0zLjIxNSA3LjQ1MSAwLjUzMjQgMC43NjQgMS45NzY1IDIuMjIzIDIuNzY1NSAxLjYzNC0xLjEwMi0wLjY4My0yLjAwMzMtMS44NTktMS44MDk1LTMuMjI3LTAuMDgyMS0xLjI4MiAxLjM2OTktMi45MTEgMi42NTEzLTMuMTk4IDAuNDM4NCAyLjg2OSAwLjk0MTMgNi4wNzMgMS4zNzk3IDguOTQzLTAuNTA1NCAwLjEtMS4wMjExIDAuMTQzLTEuNTM2IDAuMTQzeiIvPiYjeGE7PC9zdmc+" preserveAspectRatio="none"/></g></g></g></g></g></svg>
|