zudoku 0.3.0-dev.78 → 0.3.0-dev.79
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/lib/authentication/providers/openid.d.ts +1 -1
- package/dist/lib/authentication/providers/openid.js +1 -1
- package/dist/lib/authentication/providers/openid.js.map +1 -1
- package/dist/lib/plugins/openapi/index.js +3 -5
- package/dist/lib/plugins/openapi/index.js.map +1 -1
- package/dist/lib/plugins/openapi/playground/Playground.js +3 -3
- package/dist/lib/plugins/openapi/playground/Playground.js.map +1 -1
- package/dist/lib/plugins/openapi/playground/PlaygroundDialog.d.ts +2 -1
- package/dist/lib/plugins/openapi/playground/PlaygroundDialog.js.map +1 -1
- package/dist/lib/plugins/openapi/playground/ResponseTab.d.ts +4 -0
- package/dist/lib/plugins/openapi/playground/ResponseTab.js +40 -0
- package/dist/lib/plugins/openapi/playground/ResponseTab.js.map +1 -0
- package/dist/lib/ui/Button.d.ts +5 -1
- package/dist/lib/ui/Button.js +24 -1
- package/dist/lib/ui/Button.js.map +1 -1
- package/lib/{Combination-BIdpLnWg.js → Combination-CS4rK8IJ.js} +8 -8
- package/lib/Combination-CS4rK8IJ.js.map +1 -0
- package/lib/{Input-qyZciIJp.js → Input-GFpPXs5b.js} +2 -2
- package/lib/{Input-qyZciIJp.js.map → Input-GFpPXs5b.js.map} +1 -1
- package/lib/{OperationList-qfNEBPAx.js → OperationList-C-M33Hxu.js} +691 -720
- package/lib/OperationList-C-M33Hxu.js.map +1 -0
- package/lib/{Spinner-yPSFgoZ8.js → Spinner-oNQQyp-I.js} +2 -2
- package/lib/{Spinner-yPSFgoZ8.js.map → Spinner-oNQQyp-I.js.map} +1 -1
- package/lib/{index-BpO_SgPQ.js → index-D4bOMg7f.js} +3 -3
- package/lib/{index-BpO_SgPQ.js.map → index-D4bOMg7f.js.map} +1 -1
- package/lib/{index-DccqEFTy.js → index-Uqja2h2M.js} +264 -182
- package/lib/index-Uqja2h2M.js.map +1 -0
- package/lib/zudoku.auth-openid.js +1 -1
- package/lib/zudoku.auth-openid.js.map +1 -1
- package/lib/zudoku.components.js +3 -3
- package/lib/zudoku.plugin-api-keys.js +2 -2
- package/lib/zudoku.plugin-openapi.js +2 -2
- package/package.json +1 -1
- package/src/app/main.css +1 -1
- package/src/lib/authentication/providers/openid.tsx +1 -1
- package/src/lib/plugins/openapi/index.tsx +13 -7
- package/src/lib/plugins/openapi/playground/Playground.tsx +7 -11
- package/src/lib/plugins/openapi/playground/PlaygroundDialog.tsx +3 -1
- package/src/lib/plugins/openapi/playground/ResponseTab.tsx +76 -0
- package/src/lib/ui/Button.tsx +32 -2
- package/dist/lib/ui/button-variants.d.ts +0 -4
- package/dist/lib/ui/button-variants.js +0 -25
- package/dist/lib/ui/button-variants.js.map +0 -1
- package/lib/Combination-BIdpLnWg.js.map +0 -1
- package/lib/OperationList-qfNEBPAx.js.map +0 -1
- package/lib/index-DccqEFTy.js.map +0 -1
- package/src/lib/ui/button-variants.ts +0 -32
package/lib/zudoku.components.js
CHANGED
|
@@ -17,15 +17,15 @@ import { H as _t, a as Ge, M as ur, A as lr, u as dr } from "./AnchorLink-BZcpTw
|
|
|
17
17
|
import { d as hr, R as pr, N as $e, L as Ee } from "./index-Dt-pU7Vu.js";
|
|
18
18
|
import { E as Et, u as fr, S as mr, a as Se, R as gr } from "./SlotletProvider-D_Vz-7c_.js";
|
|
19
19
|
import { j as o, d as vr, u as J, a as xr, b as yr, O as St } from "./jsx-runtime-CJBdjYYx.js";
|
|
20
|
-
import { M as wr, c as Mr, a as jt, b as Nt, A as br, u as fe, h as Cr, d as y, e as Pr, F as Rr, D as _r, C as Er, P as ie, f as qe, g as Sr, i as Dt, R as jr, S as Nr, j as Dr, k as Ir, l as It, m as Ar, n as je, o as At, B as Be } from "./Combination-
|
|
20
|
+
import { M as wr, c as Mr, a as jt, b as Nt, A as br, u as fe, h as Cr, d as y, e as Pr, F as Rr, D as _r, C as Er, P as ie, f as qe, g as Sr, i as Dt, R as jr, S as Nr, j as Dr, k as Ir, l as It, m as Ar, n as je, o as At, B as Be } from "./Combination-CS4rK8IJ.js";
|
|
21
21
|
import { c as me, a as P, C as Or, b as Tr, u as kr, M as Fr, T as Lr, V as Kr, d as He, e as $r, f as Br } from "./Markdown-QsZ-PHET.js";
|
|
22
22
|
import * as u from "react";
|
|
23
23
|
import Qr, { StrictMode as Ot, createContext as Tt, Component as Ur, createElement as pt, isValidElement as Gr, memo as kt, useMemo as Le, useState as le, useContext as qr, useRef as ge, useEffect as W, Fragment as Hr, forwardRef as zr, Suspense as Vr } from "react";
|
|
24
24
|
import { g as ze } from "./_commonjsHelpers-BVfed4GL.js";
|
|
25
25
|
import { r as Yr } from "./router-BiRCp01d.js";
|
|
26
|
-
import { S as Qe, R as Ft, T as Lt, C as Kt } from "./index-
|
|
26
|
+
import { S as Qe, R as Ft, T as Lt, C as Kt } from "./index-D4bOMg7f.js";
|
|
27
27
|
import { S as $t, h as Bt, Q as Xr, n as j, m as ft, a as mt, b as Q, e as Wr, c as Jr, d as Zr, f as ea, o as gt, r as vt, g as ta, i as xt, p as yt, s as na, u as Ve, j as ra, D as aa, k as Ye, l as wt, q as Qt, t as oa, v as sa, w as ia } from "./DevPortalProvider-BTFqdAEL.js";
|
|
28
|
-
import { c as Ut, P as Ie, R as ca, I as ua, S as la } from "./Spinner-
|
|
28
|
+
import { c as Ut, P as Ie, R as ca, I as ua, S as la } from "./Spinner-oNQQyp-I.js";
|
|
29
29
|
/**
|
|
30
30
|
* @license lucide-react v0.378.0 - ISC
|
|
31
31
|
*
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { a as f, j as e, O as j } from "./jsx-runtime-CJBdjYYx.js";
|
|
2
2
|
import { u as g, a as x, R as v } from "./SlotletProvider-D_Vz-7c_.js";
|
|
3
|
-
import { u as w, a as h, I as k, S as b, b as K, c as N, d as A, e as E, f as p } from "./Input-
|
|
3
|
+
import { u as w, a as h, I as k, S as b, b as K, c as N, d as A, e as E, f as p } from "./Input-GFpPXs5b.js";
|
|
4
4
|
import { L as u } from "./index-Dt-pU7Vu.js";
|
|
5
5
|
import { u as m, x as S, y as I } from "./DevPortalProvider-BTFqdAEL.js";
|
|
6
|
-
import { B as o } from "./Combination-
|
|
6
|
+
import { B as o } from "./Combination-CS4rK8IJ.js";
|
|
7
7
|
import { D as P } from "./DeveloperHint-DQVwIery.js";
|
|
8
8
|
import { useState as C } from "react";
|
|
9
9
|
import { c as l, a as D } from "./Markdown-QsZ-PHET.js";
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import "./jsx-runtime-CJBdjYYx.js";
|
|
2
|
-
import { o as a } from "./index-
|
|
2
|
+
import { o as a } from "./index-Uqja2h2M.js";
|
|
3
3
|
import "./urql-DrBfkb92.js";
|
|
4
4
|
import "zudoku/openapi-worker";
|
|
5
5
|
import "./Markdown-QsZ-PHET.js";
|
|
6
|
-
import "./Combination-
|
|
6
|
+
import "./Combination-CS4rK8IJ.js";
|
|
7
7
|
import "./router-BiRCp01d.js";
|
|
8
8
|
export {
|
|
9
9
|
a as openApiPlugin
|
package/package.json
CHANGED
package/src/app/main.css
CHANGED
|
@@ -115,7 +115,7 @@
|
|
|
115
115
|
}
|
|
116
116
|
|
|
117
117
|
.prose.prose {
|
|
118
|
-
@apply prose-a:
|
|
118
|
+
@apply prose-a:underline-offset-4 hover:prose-a:text-primary;
|
|
119
119
|
@apply prose-blockquote:not-italic prose-blockquote:text-neutral-500/75 prose-blockquote:dark:text-neutral-400;
|
|
120
120
|
@apply prose-headings:prose-code:mx-2;
|
|
121
121
|
@apply prose-code:before:content-none prose-code:after:content-none;
|
|
@@ -17,8 +17,10 @@ import { ErrorPage } from "../../components/ErrorPage.js";
|
|
|
17
17
|
import { SyntaxHighlight } from "../../components/SyntaxHighlight.js";
|
|
18
18
|
import { Button } from "../../ui/Button.js";
|
|
19
19
|
import { OasPluginConfig } from "./interfaces.js";
|
|
20
|
-
import
|
|
21
|
-
|
|
20
|
+
import {
|
|
21
|
+
PlaygroundDialog,
|
|
22
|
+
type PlaygroundDialogProps,
|
|
23
|
+
} from "./playground/PlaygroundDialog.js";
|
|
22
24
|
|
|
23
25
|
const GetCategoriesQuery = graphql(`
|
|
24
26
|
query GetCategories($input: JSON!, $type: SchemaType!) {
|
|
@@ -86,15 +88,19 @@ export const openApiPlugin = (
|
|
|
86
88
|
}
|
|
87
89
|
},
|
|
88
90
|
getMdxComponents: () => ({
|
|
89
|
-
OpenPlaygroundButton: (props:
|
|
90
|
-
|
|
91
|
+
OpenPlaygroundButton: (props: PlaygroundDialogProps) => (
|
|
92
|
+
<div>
|
|
91
93
|
<PlaygroundDialog {...props}>
|
|
92
94
|
<Button className="gap-2 items-center" variant="outline">
|
|
93
|
-
|
|
95
|
+
{props.children ?? (
|
|
96
|
+
<>
|
|
97
|
+
Open in Playground <CirclePlayIcon size={16} />
|
|
98
|
+
</>
|
|
99
|
+
)}
|
|
94
100
|
</Button>
|
|
95
101
|
</PlaygroundDialog>
|
|
96
|
-
|
|
97
|
-
|
|
102
|
+
</div>
|
|
103
|
+
),
|
|
98
104
|
}),
|
|
99
105
|
getNavigation: async (path: string) => {
|
|
100
106
|
if (!matchPath({ path: basePath, end: false }, path)) {
|
|
@@ -10,7 +10,6 @@ import {
|
|
|
10
10
|
SelectValue,
|
|
11
11
|
} from "../../../components/Select.js";
|
|
12
12
|
import { Spinner } from "../../../components/Spinner.js";
|
|
13
|
-
import { SyntaxHighlight } from "../../../components/SyntaxHighlight.js";
|
|
14
13
|
import { Button } from "../../../ui/Button.js";
|
|
15
14
|
import { Card } from "../../../ui/Card.js";
|
|
16
15
|
import { Tabs, TabsContent, TabsList, TabsTrigger } from "../../../ui/Tabs.js";
|
|
@@ -20,6 +19,7 @@ import { createUrl } from "./createUrl.js";
|
|
|
20
19
|
import { Headers } from "./Headers.js";
|
|
21
20
|
import { PathParams } from "./PathParams.js";
|
|
22
21
|
import { QueryParams } from "./QueryParams.js";
|
|
22
|
+
import { ResponseTab } from "./ResponseTab.js";
|
|
23
23
|
|
|
24
24
|
export const NO_IDENTITY = "__none";
|
|
25
25
|
|
|
@@ -37,7 +37,7 @@ function mimeTypeToLanguage(mimeType: string) {
|
|
|
37
37
|
|
|
38
38
|
return Object.entries(mimeTypeMapping).find(([mime]) =>
|
|
39
39
|
mimeType.includes(mime),
|
|
40
|
-
)?.[
|
|
40
|
+
)?.[1];
|
|
41
41
|
}
|
|
42
42
|
|
|
43
43
|
const statusCodeMap: Record<number, string> = {
|
|
@@ -331,14 +331,10 @@ export const Playground = ({
|
|
|
331
331
|
</TabsList>
|
|
332
332
|
|
|
333
333
|
<TabsContent value="response">
|
|
334
|
-
<
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
className="overflow-x-auto "
|
|
339
|
-
code={queryMutation.data.body ?? JSON.stringify("")}
|
|
340
|
-
/>
|
|
341
|
-
</Card>
|
|
334
|
+
<ResponseTab
|
|
335
|
+
headers={queryMutation.data.headers}
|
|
336
|
+
body={queryMutation.data.body}
|
|
337
|
+
/>
|
|
342
338
|
</TabsContent>
|
|
343
339
|
<TabsContent value="headers">
|
|
344
340
|
<Card className="grid grid-cols-2 w-full gap-2.5 font-mono text-xs shadow-none p-4">
|
|
@@ -347,7 +343,7 @@ export const Playground = ({
|
|
|
347
343
|
{headerEntries.map(([key, value]) => (
|
|
348
344
|
<Fragment key={key}>
|
|
349
345
|
<div>{key}</div>
|
|
350
|
-
<div>{value}</div>
|
|
346
|
+
<div className="break-words">{value}</div>
|
|
351
347
|
</Fragment>
|
|
352
348
|
))}
|
|
353
349
|
</Card>
|
|
@@ -9,7 +9,9 @@ import {
|
|
|
9
9
|
} from "../../../components/Dialog.js";
|
|
10
10
|
import { Playground, type PlaygroundContentProps } from "./Playground.js";
|
|
11
11
|
|
|
12
|
-
|
|
12
|
+
export type PlaygroundDialogProps = PropsWithChildren<PlaygroundContentProps>;
|
|
13
|
+
|
|
14
|
+
const PlaygroundDialog = (props: PlaygroundDialogProps) => {
|
|
13
15
|
const [open, setOpen] = useState(false);
|
|
14
16
|
return (
|
|
15
17
|
<Dialog onOpenChange={(open) => setOpen(open)}>
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import { useState } from "react";
|
|
2
|
+
import { SyntaxHighlight } from "../../../components/SyntaxHighlight.js";
|
|
3
|
+
import { Card } from "../../../ui/Card.js";
|
|
4
|
+
import { SimpleSelect } from "../SimpleSelect.js";
|
|
5
|
+
|
|
6
|
+
const mimeTypeToLanguage = (mimeType: string) => {
|
|
7
|
+
const mimeTypeMapping = {
|
|
8
|
+
"application/json": "json",
|
|
9
|
+
"text/json": "json",
|
|
10
|
+
"text/html": "html",
|
|
11
|
+
"text/css": "css",
|
|
12
|
+
"text/javascript": "javascript",
|
|
13
|
+
"application/xml": "xml",
|
|
14
|
+
"application/xhtml+xml": "xhtml",
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
return Object.entries(mimeTypeMapping).find(([mime]) =>
|
|
18
|
+
mimeType.includes(mime),
|
|
19
|
+
)?.[1];
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
const detectLanguage = (headers: Headers) => {
|
|
23
|
+
const contentType = headers.get("Content-Type") || "";
|
|
24
|
+
return mimeTypeToLanguage(contentType);
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
const tryParseJson = (body: string) => {
|
|
28
|
+
try {
|
|
29
|
+
return JSON.stringify(JSON.parse(body), null, 2);
|
|
30
|
+
} catch {
|
|
31
|
+
return null;
|
|
32
|
+
}
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
export const ResponseTab = ({
|
|
36
|
+
body = "",
|
|
37
|
+
headers,
|
|
38
|
+
}: {
|
|
39
|
+
body?: string;
|
|
40
|
+
headers: Headers;
|
|
41
|
+
}) => {
|
|
42
|
+
const detectedLanguage = detectLanguage(headers);
|
|
43
|
+
const jsonContent = tryParseJson(body);
|
|
44
|
+
const beautifiedBody = jsonContent || body;
|
|
45
|
+
const [view, setView] = useState<"formatted" | "raw">(
|
|
46
|
+
jsonContent ? "formatted" : "raw",
|
|
47
|
+
);
|
|
48
|
+
|
|
49
|
+
return (
|
|
50
|
+
<div className="flex flex-col gap-2">
|
|
51
|
+
<Card className="shadow-none">
|
|
52
|
+
<SyntaxHighlight
|
|
53
|
+
language={
|
|
54
|
+
view === "raw" ? (jsonContent ? "plain" : detectedLanguage) : "json"
|
|
55
|
+
}
|
|
56
|
+
noBackground
|
|
57
|
+
showLanguageIndicator
|
|
58
|
+
className="overflow-x-auto p-4 text-xs"
|
|
59
|
+
code={view === "raw" ? body : beautifiedBody}
|
|
60
|
+
/>
|
|
61
|
+
</Card>
|
|
62
|
+
{jsonContent && (
|
|
63
|
+
<div className="flex justify-end">
|
|
64
|
+
<SimpleSelect
|
|
65
|
+
value={view}
|
|
66
|
+
onChange={(e) => setView(e.target.value as "formatted" | "raw")}
|
|
67
|
+
options={[
|
|
68
|
+
{ value: "formatted", label: "Formatted" },
|
|
69
|
+
{ value: "raw", label: "Raw" },
|
|
70
|
+
]}
|
|
71
|
+
/>
|
|
72
|
+
</div>
|
|
73
|
+
)}
|
|
74
|
+
</div>
|
|
75
|
+
);
|
|
76
|
+
};
|
package/src/lib/ui/Button.tsx
CHANGED
|
@@ -1,8 +1,38 @@
|
|
|
1
1
|
import { Slot } from "@radix-ui/react-slot";
|
|
2
|
-
import { VariantProps } from "class-variance-authority";
|
|
2
|
+
import { cva, VariantProps } from "class-variance-authority";
|
|
3
3
|
import * as React from "react";
|
|
4
4
|
import { cn } from "../util/cn.js";
|
|
5
|
-
|
|
5
|
+
|
|
6
|
+
const buttonVariants = cva(
|
|
7
|
+
"not-prose inline-flex items-center justify-center whitespace-nowrap rounded-md text-sm font-medium transition-colors focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:pointer-events-none disabled:opacity-50",
|
|
8
|
+
{
|
|
9
|
+
variants: {
|
|
10
|
+
variant: {
|
|
11
|
+
default:
|
|
12
|
+
"bg-primary text-primary-foreground shadow hover:bg-primary/90",
|
|
13
|
+
destructive:
|
|
14
|
+
"bg-destructive text-destructive-foreground shadow-sm hover:bg-destructive/90",
|
|
15
|
+
outline:
|
|
16
|
+
"border border-input bg-background shadow-sm hover:bg-accent hover:text-accent-foreground",
|
|
17
|
+
secondary:
|
|
18
|
+
"bg-secondary text-secondary-foreground shadow-sm hover:bg-secondary/80",
|
|
19
|
+
ghost: "hover:bg-accent hover:text-accent-foreground",
|
|
20
|
+
link: "text-primary underline-offset-4 hover:underline",
|
|
21
|
+
},
|
|
22
|
+
size: {
|
|
23
|
+
default: "h-9 px-4 py-2",
|
|
24
|
+
sm: "h-8 rounded-md px-3 text-xs",
|
|
25
|
+
lg: "h-10 rounded-md px-8",
|
|
26
|
+
xl: "h-14 rounded-lg px-10 text-lg",
|
|
27
|
+
icon: "h-9 w-9",
|
|
28
|
+
},
|
|
29
|
+
},
|
|
30
|
+
defaultVariants: {
|
|
31
|
+
variant: "default",
|
|
32
|
+
size: "default",
|
|
33
|
+
},
|
|
34
|
+
},
|
|
35
|
+
);
|
|
6
36
|
|
|
7
37
|
export interface ButtonProps
|
|
8
38
|
extends React.ButtonHTMLAttributes<HTMLButtonElement>,
|
|
@@ -1,4 +0,0 @@
|
|
|
1
|
-
export declare const buttonVariants: (props?: ({
|
|
2
|
-
variant?: "link" | "default" | "destructive" | "outline" | "secondary" | "ghost" | null | undefined;
|
|
3
|
-
size?: "default" | "sm" | "lg" | "xl" | "icon" | null | undefined;
|
|
4
|
-
} & import("class-variance-authority/types").ClassProp) | undefined) => string;
|
|
@@ -1,25 +0,0 @@
|
|
|
1
|
-
import { cva } from "class-variance-authority";
|
|
2
|
-
export const buttonVariants = cva("inline-flex items-center justify-center whitespace-nowrap rounded-md text-sm font-medium transition-colors focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:pointer-events-none disabled:opacity-50", {
|
|
3
|
-
variants: {
|
|
4
|
-
variant: {
|
|
5
|
-
default: "bg-primary text-primary-foreground shadow hover:bg-primary/90",
|
|
6
|
-
destructive: "bg-destructive text-destructive-foreground shadow-sm hover:bg-destructive/90",
|
|
7
|
-
outline: "border border-input bg-background shadow-sm hover:bg-accent hover:text-accent-foreground",
|
|
8
|
-
secondary: "bg-secondary text-secondary-foreground shadow-sm hover:bg-secondary/80",
|
|
9
|
-
ghost: "hover:bg-accent hover:text-accent-foreground",
|
|
10
|
-
link: "text-primary underline-offset-4 hover:underline",
|
|
11
|
-
},
|
|
12
|
-
size: {
|
|
13
|
-
default: "h-9 px-4 py-2",
|
|
14
|
-
sm: "h-8 rounded-md px-3 text-xs",
|
|
15
|
-
lg: "h-10 rounded-md px-8",
|
|
16
|
-
xl: "h-14 rounded-lg px-10 text-lg",
|
|
17
|
-
icon: "h-9 w-9",
|
|
18
|
-
},
|
|
19
|
-
},
|
|
20
|
-
defaultVariants: {
|
|
21
|
-
variant: "default",
|
|
22
|
-
size: "default",
|
|
23
|
-
},
|
|
24
|
-
});
|
|
25
|
-
//# sourceMappingURL=button-variants.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"button-variants.js","sourceRoot":"","sources":["../../../src/lib/ui/button-variants.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,EAAE,MAAM,0BAA0B,CAAC;AAE/C,MAAM,CAAC,MAAM,cAAc,GAAG,GAAG,CAC/B,qOAAqO,EACrO;IACE,QAAQ,EAAE;QACR,OAAO,EAAE;YACP,OAAO,EACL,+DAA+D;YACjE,WAAW,EACT,8EAA8E;YAChF,OAAO,EACL,0FAA0F;YAC5F,SAAS,EACP,wEAAwE;YAC1E,KAAK,EAAE,8CAA8C;YACrD,IAAI,EAAE,iDAAiD;SACxD;QACD,IAAI,EAAE;YACJ,OAAO,EAAE,eAAe;YACxB,EAAE,EAAE,6BAA6B;YACjC,EAAE,EAAE,sBAAsB;YAC1B,EAAE,EAAE,+BAA+B;YACnC,IAAI,EAAE,SAAS;SAChB;KACF;IACD,eAAe,EAAE;QACf,OAAO,EAAE,SAAS;QAClB,IAAI,EAAE,SAAS;KAChB;CACF,CACF,CAAC"}
|