@axis-backstage/plugin-readme 0.6.0 → 0.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.
@@ -1,4 +1,5 @@
1
1
  import { createRouteRef, createApiRef, createPlugin, createApiFactory, discoveryApiRef, fetchApiRef, identityApiRef, createRoutableExtension } from '@backstage/core-plugin-api';
2
+ import { parseEntityRef, DEFAULT_NAMESPACE } from '@backstage/catalog-model';
2
3
 
3
4
  const rootRouteRef = createRouteRef({
4
5
  id: "readme"
@@ -26,8 +27,11 @@ class ReadmeClient {
26
27
  async getReadmeContent(entityRef) {
27
28
  const { token } = await this.identityApi.getCredentials();
28
29
  const baseUrl = await this.discoveryApi.getBaseUrl("readme");
30
+ const { kind, name, namespace } = parseEntityRef(entityRef, {
31
+ defaultNamespace: DEFAULT_NAMESPACE
32
+ });
29
33
  const resp = await this.fetchApi.fetch(
30
- `${baseUrl}/${encodeURIComponent(entityRef)}`,
34
+ `${baseUrl}/${kind}/${namespace}/${name}`,
31
35
  {
32
36
  method: "GET",
33
37
  headers: { Authorization: `Bearer ${token}` }
@@ -66,10 +70,10 @@ const readmePlugin = createPlugin({
66
70
  const ReadmeCard = readmePlugin.provide(
67
71
  createRoutableExtension({
68
72
  name: "ReadmeCard",
69
- component: () => import('./index-29e5be16.esm.js').then((m) => m.ReadmeCard),
73
+ component: () => import('./index-fb77d32d.esm.js').then((m) => m.ReadmeCard),
70
74
  mountPoint: rootRouteRef
71
75
  })
72
76
  );
73
77
 
74
78
  export { ReadmeCard as R, readmePlugin as a, readmeApiRef as r };
75
- //# sourceMappingURL=index-1480bc27.esm.js.map
79
+ //# sourceMappingURL=index-357af793.esm.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index-357af793.esm.js","sources":["../../src/routes.ts","../../src/api/ReadmeApi.tsx","../../src/api/ReadmeClient.tsx","../../src/plugin.ts"],"sourcesContent":["import { createRouteRef } from '@backstage/core-plugin-api';\n\nexport const rootRouteRef = createRouteRef({\n id: 'readme',\n});\n","import { createApiRef } from '@backstage/core-plugin-api';\n\nexport const readmeApiRef = createApiRef<ReadmeApi>({\n id: 'plugin.readme',\n});\n\nexport type ReadmeApi = {\n getReadmeContent(entityRef: string): Promise<[string, string]>;\n};\n","import {\n DiscoveryApi,\n FetchApi,\n IdentityApi,\n} from '@backstage/core-plugin-api';\nimport { DEFAULT_NAMESPACE, parseEntityRef } from '@backstage/catalog-model';\nimport { ReadmeApi } from './ReadmeApi';\n\nexport class ReadmeClient implements ReadmeApi {\n private readonly discoveryApi: DiscoveryApi;\n private readonly fetchApi: FetchApi;\n private readonly identityApi: IdentityApi;\n\n constructor(options: {\n discoveryApi: DiscoveryApi;\n fetchApi: FetchApi;\n identityApi: IdentityApi;\n }) {\n this.discoveryApi = options.discoveryApi;\n this.fetchApi = options.fetchApi;\n this.identityApi = options.identityApi;\n }\n\n async getReadmeContent(entityRef: string): Promise<[string, string]> {\n const { token } = await this.identityApi.getCredentials();\n const baseUrl = await this.discoveryApi.getBaseUrl('readme');\n\n const { kind, name, namespace } = parseEntityRef(entityRef, {\n defaultNamespace: DEFAULT_NAMESPACE,\n });\n\n const resp = await this.fetchApi.fetch(\n `${baseUrl}/${kind}/${namespace}/${name}`,\n {\n method: 'GET',\n headers: { Authorization: `Bearer ${token}` },\n },\n );\n if (resp.ok) {\n return [\n await resp.text(),\n resp.headers.get('Content-Type') || 'text/plain',\n ];\n }\n if (resp.status === 404) {\n throw new Error('404');\n }\n throw new Error(`${resp.status}: ${resp.statusText}`);\n }\n}\n","import {\n createApiFactory,\n createPlugin,\n createRoutableExtension,\n discoveryApiRef,\n fetchApiRef,\n identityApiRef,\n} from '@backstage/core-plugin-api';\n\nimport { rootRouteRef } from './routes';\nimport { readmeApiRef } from './api/ReadmeApi';\nimport { ReadmeClient } from './api/ReadmeClient';\n\n/**\n * Plugin that provides the Readme api\n * @public */\nexport const readmePlugin = createPlugin({\n id: 'readme',\n apis: [\n createApiFactory({\n api: readmeApiRef,\n deps: {\n discoveryApi: discoveryApiRef,\n fetchApi: fetchApiRef,\n identityApi: identityApiRef,\n },\n factory: ({ discoveryApi, fetchApi, identityApi }) =>\n new ReadmeClient({ discoveryApi, fetchApi, identityApi }),\n }),\n ],\n routes: {\n root: rootRouteRef,\n },\n});\n\n/**\n * Readme card exported from the Readme plugin\n * @public */\nexport const ReadmeCard = readmePlugin.provide(\n createRoutableExtension({\n name: 'ReadmeCard',\n component: () => import('./components/ReadmeCard').then(m => m.ReadmeCard),\n mountPoint: rootRouteRef,\n }),\n);\n"],"names":[],"mappings":"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"}
@@ -5,7 +5,7 @@ import { Progress, Link, ErrorPanel, MarkdownContent, CodeSnippet, InfoCard } fr
5
5
  import { useEntity } from '@backstage/plugin-catalog-react';
6
6
  import { useApi } from '@backstage/core-plugin-api';
7
7
  import useAsync from 'react-use/lib/useAsync';
8
- import { r as readmeApiRef } from './index-1480bc27.esm.js';
8
+ import { r as readmeApiRef } from './index-357af793.esm.js';
9
9
  import { getEntitySourceLocation, stringifyEntityRef } from '@backstage/catalog-model';
10
10
  import Typography from '@mui/material/Typography';
11
11
  import OpenInNewIcon from '@mui/icons-material/OpenInNew';
@@ -110,4 +110,4 @@ const ReadmeCard = (props) => {
110
110
  };
111
111
 
112
112
  export { ReadmeCard };
113
- //# sourceMappingURL=index-29e5be16.esm.js.map
113
+ //# sourceMappingURL=index-fb77d32d.esm.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index-29e5be16.esm.js","sources":["../../src/components/FetchComponent/FetchComponent.tsx","../../src/components/ReadmeDialog/ReadmeDialog.tsx","../../src/components/ReadmeCard/ReadmeCard.tsx"],"sourcesContent":["import React from 'react';\nimport { useEntity } from '@backstage/plugin-catalog-react';\nimport { useApi } from '@backstage/core-plugin-api';\nimport {\n CodeSnippet,\n ErrorPanel,\n Link,\n MarkdownContent,\n Progress,\n} from '@backstage/core-components';\nimport useAsync from 'react-use/lib/useAsync';\nimport { readmeApiRef } from '../../api/ReadmeApi';\nimport { stringifyEntityRef } from '@backstage/catalog-model';\nimport { getEntitySourceLocation } from '@backstage/catalog-model';\nimport Box from '@mui/material/Box';\nimport Typography from '@mui/material/Typography';\n\nexport const FetchComponent = () => {\n const { entity } = useEntity();\n const readmeApi = useApi(readmeApiRef);\n let location;\n\n try {\n const { target } = getEntitySourceLocation(entity);\n location = target ?? target;\n } catch (err) {\n location = ': Unknown';\n }\n\n const {\n value: content,\n loading,\n error,\n } = useAsync(\n async (): Promise<string[]> =>\n await readmeApi.getReadmeContent(stringifyEntityRef(entity)),\n [entity],\n );\n\n if (loading) {\n return <Progress />;\n }\n if (error?.message === '404') {\n return (\n <Box>\n <Typography pb={2} variant=\"body2\">\n No README.md file found at source location:{' '}\n {location && <strong>{location}</strong>}\n </Typography>\n <Typography variant=\"body2\">\n Need help? Go to our{' '}\n <Link to=\"https://github.com/AxisCommunications/backstage-plugins/blob/main/plugins/readme/README.md\">\n documentation\n </Link>\n </Typography>\n </Box>\n );\n }\n\n if (error) {\n return <ErrorPanel error={error} />;\n }\n if (!content) {\n return <ErrorPanel error={Error('Unknown error')} />;\n }\n if (!content[1] || content[1] === 'error') {\n return <ErrorPanel error={Error(content[1] ?? 'Unknown error')} />;\n } else if (content[1].startsWith('text/markdown')) {\n return <MarkdownContent content={content[0]} />;\n }\n // probably text/plain\n return (\n <div data-testid=\"readme-content\">\n <CodeSnippet text={content[0]} language=\"plaintext\" />\n </div>\n );\n};\n","import React from 'react';\nimport Button from '@mui/material/Button';\nimport Dialog from '@mui/material/Dialog';\nimport DialogActions from '@mui/material/DialogActions';\nimport DialogContent from '@mui/material/DialogContent';\nimport DialogTitle from '@mui/material/DialogTitle';\nimport Box from '@mui/material/Box';\nimport { FetchComponent } from '../FetchComponent';\n\ntype Props = {\n open: boolean;\n onClose: () => void;\n};\n\nexport const ReadmeDialog = ({ open, onClose }: Props) => {\n return (\n <Dialog\n maxWidth=\"md\"\n open={open}\n onClose={onClose}\n data-testid=\"content-dialog\"\n >\n <DialogTitle>README</DialogTitle>\n <DialogContent dividers>\n <Box minWidth={650}>\n <FetchComponent />\n </Box>\n </DialogContent>\n <DialogActions>\n <Button\n variant=\"contained\"\n color=\"primary\"\n aria-label=\"close\"\n onClick={onClose}\n >\n Close\n </Button>\n </DialogActions>\n </Dialog>\n );\n};\n","import React, { useState } from 'react';\nimport IconButton from '@mui/material/IconButton';\nimport Box from '@mui/material/Box';\nimport { InfoCard, InfoCardVariants } from '@backstage/core-components';\nimport { FetchComponent } from '../FetchComponent';\nimport OpenInNewIcon from '@mui/icons-material/OpenInNew';\nimport { ReadmeDialog } from '../ReadmeDialog/ReadmeDialog';\n\n/**\n * ReadmeCardProps props.\n *\n * @public\n */\n\nexport type ReadmeCardProps = {\n variant?: InfoCardVariants;\n};\n\nexport const ReadmeCard = (props: ReadmeCardProps) => {\n const { variant = 'gridItem' } = props;\n const maxHeight = variant === 'fullHeight' ? 'none' : '235px';\n\n const [displayDialog, setDisplayDialog] = useState(false);\n\n return (\n <>\n <InfoCard\n title=\"README\"\n variant={variant}\n action={\n variant !== 'fullHeight' ? (\n <IconButton\n onClick={() => setDisplayDialog(true)}\n aria-label=\"open dialog\"\n role=\"button\"\n title=\"Open in dialog\"\n size=\"large\"\n >\n <OpenInNewIcon />\n </IconButton>\n ) : undefined\n }\n >\n <div style={{ overflow: 'auto' }}>\n <Box maxHeight={maxHeight}>\n <FetchComponent />\n </Box>\n </div>\n </InfoCard>\n\n <ReadmeDialog\n open={displayDialog}\n onClose={() => setDisplayDialog(false)}\n />\n </>\n );\n};\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index-fb77d32d.esm.js","sources":["../../src/components/FetchComponent/FetchComponent.tsx","../../src/components/ReadmeDialog/ReadmeDialog.tsx","../../src/components/ReadmeCard/ReadmeCard.tsx"],"sourcesContent":["import React from 'react';\nimport { useEntity } from '@backstage/plugin-catalog-react';\nimport { useApi } from '@backstage/core-plugin-api';\nimport {\n CodeSnippet,\n ErrorPanel,\n Link,\n MarkdownContent,\n Progress,\n} from '@backstage/core-components';\nimport useAsync from 'react-use/lib/useAsync';\nimport { readmeApiRef } from '../../api/ReadmeApi';\nimport { stringifyEntityRef } from '@backstage/catalog-model';\nimport { getEntitySourceLocation } from '@backstage/catalog-model';\nimport Box from '@mui/material/Box';\nimport Typography from '@mui/material/Typography';\n\nexport const FetchComponent = () => {\n const { entity } = useEntity();\n const readmeApi = useApi(readmeApiRef);\n let location;\n\n try {\n const { target } = getEntitySourceLocation(entity);\n location = target ?? target;\n } catch (err) {\n location = ': Unknown';\n }\n\n const {\n value: content,\n loading,\n error,\n } = useAsync(\n async (): Promise<string[]> =>\n await readmeApi.getReadmeContent(stringifyEntityRef(entity)),\n [entity],\n );\n\n if (loading) {\n return <Progress />;\n }\n if (error?.message === '404') {\n return (\n <Box>\n <Typography pb={2} variant=\"body2\">\n No README.md file found at source location:{' '}\n {location && <strong>{location}</strong>}\n </Typography>\n <Typography variant=\"body2\">\n Need help? Go to our{' '}\n <Link to=\"https://github.com/AxisCommunications/backstage-plugins/blob/main/plugins/readme/README.md\">\n documentation\n </Link>\n </Typography>\n </Box>\n );\n }\n\n if (error) {\n return <ErrorPanel error={error} />;\n }\n if (!content) {\n return <ErrorPanel error={Error('Unknown error')} />;\n }\n if (!content[1] || content[1] === 'error') {\n return <ErrorPanel error={Error(content[1] ?? 'Unknown error')} />;\n } else if (content[1].startsWith('text/markdown')) {\n return <MarkdownContent content={content[0]} />;\n }\n // probably text/plain\n return (\n <div data-testid=\"readme-content\">\n <CodeSnippet text={content[0]} language=\"plaintext\" />\n </div>\n );\n};\n","import React from 'react';\nimport Button from '@mui/material/Button';\nimport Dialog from '@mui/material/Dialog';\nimport DialogActions from '@mui/material/DialogActions';\nimport DialogContent from '@mui/material/DialogContent';\nimport DialogTitle from '@mui/material/DialogTitle';\nimport Box from '@mui/material/Box';\nimport { FetchComponent } from '../FetchComponent';\n\ntype Props = {\n open: boolean;\n onClose: () => void;\n};\n\nexport const ReadmeDialog = ({ open, onClose }: Props) => {\n return (\n <Dialog\n maxWidth=\"md\"\n open={open}\n onClose={onClose}\n data-testid=\"content-dialog\"\n >\n <DialogTitle>README</DialogTitle>\n <DialogContent dividers>\n <Box minWidth={650}>\n <FetchComponent />\n </Box>\n </DialogContent>\n <DialogActions>\n <Button\n variant=\"contained\"\n color=\"primary\"\n aria-label=\"close\"\n onClick={onClose}\n >\n Close\n </Button>\n </DialogActions>\n </Dialog>\n );\n};\n","import React, { useState } from 'react';\nimport IconButton from '@mui/material/IconButton';\nimport Box from '@mui/material/Box';\nimport { InfoCard, InfoCardVariants } from '@backstage/core-components';\nimport { FetchComponent } from '../FetchComponent';\nimport OpenInNewIcon from '@mui/icons-material/OpenInNew';\nimport { ReadmeDialog } from '../ReadmeDialog/ReadmeDialog';\n\n/**\n * ReadmeCardProps props.\n *\n * @public\n */\n\nexport type ReadmeCardProps = {\n variant?: InfoCardVariants;\n};\n\nexport const ReadmeCard = (props: ReadmeCardProps) => {\n const { variant = 'gridItem' } = props;\n const maxHeight = variant === 'fullHeight' ? 'none' : '235px';\n\n const [displayDialog, setDisplayDialog] = useState(false);\n\n return (\n <>\n <InfoCard\n title=\"README\"\n variant={variant}\n action={\n variant !== 'fullHeight' ? (\n <IconButton\n onClick={() => setDisplayDialog(true)}\n aria-label=\"open dialog\"\n role=\"button\"\n title=\"Open in dialog\"\n size=\"large\"\n >\n <OpenInNewIcon />\n </IconButton>\n ) : undefined\n }\n >\n <div style={{ overflow: 'auto' }}>\n <Box maxHeight={maxHeight}>\n <FetchComponent />\n </Box>\n </div>\n </InfoCard>\n\n <ReadmeDialog\n open={displayDialog}\n onClose={() => setDisplayDialog(false)}\n />\n </>\n );\n};\n"],"names":[],"mappings":"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"}
package/dist/index.esm.js CHANGED
@@ -1,3 +1,4 @@
1
- export { R as ReadmeCard, a as readmePlugin } from './esm/index-1480bc27.esm.js';
1
+ export { R as ReadmeCard, a as readmePlugin } from './esm/index-357af793.esm.js';
2
2
  import '@backstage/core-plugin-api';
3
+ import '@backstage/catalog-model';
3
4
  //# sourceMappingURL=index.esm.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.esm.js","sources":[],"sourcesContent":[],"names":[],"mappings":";"}
1
+ {"version":3,"file":"index.esm.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@axis-backstage/plugin-readme",
3
- "version": "0.6.0",
3
+ "version": "0.7.0",
4
4
  "main": "dist/index.esm.js",
5
5
  "types": "dist/index.d.ts",
6
6
  "license": "Apache-2.0",
@@ -1 +0,0 @@
1
- {"version":3,"file":"index-1480bc27.esm.js","sources":["../../src/routes.ts","../../src/api/ReadmeApi.tsx","../../src/api/ReadmeClient.tsx","../../src/plugin.ts"],"sourcesContent":["import { createRouteRef } from '@backstage/core-plugin-api';\n\nexport const rootRouteRef = createRouteRef({\n id: 'readme',\n});\n","import { createApiRef } from '@backstage/core-plugin-api';\n\nexport const readmeApiRef = createApiRef<ReadmeApi>({\n id: 'plugin.readme',\n});\n\nexport type ReadmeApi = {\n getReadmeContent(entityRef: string): Promise<[string, string]>;\n};\n","import {\n DiscoveryApi,\n FetchApi,\n IdentityApi,\n} from '@backstage/core-plugin-api';\nimport { ReadmeApi } from './ReadmeApi';\n\nexport class ReadmeClient implements ReadmeApi {\n private readonly discoveryApi: DiscoveryApi;\n private readonly fetchApi: FetchApi;\n private readonly identityApi: IdentityApi;\n\n constructor(options: {\n discoveryApi: DiscoveryApi;\n fetchApi: FetchApi;\n identityApi: IdentityApi;\n }) {\n this.discoveryApi = options.discoveryApi;\n this.fetchApi = options.fetchApi;\n this.identityApi = options.identityApi;\n }\n\n async getReadmeContent(entityRef: string): Promise<[string, string]> {\n const { token } = await this.identityApi.getCredentials();\n const baseUrl = await this.discoveryApi.getBaseUrl('readme');\n\n const resp = await this.fetchApi.fetch(\n `${baseUrl}/${encodeURIComponent(entityRef)}`,\n {\n method: 'GET',\n headers: { Authorization: `Bearer ${token}` },\n },\n );\n if (resp.ok) {\n return [\n await resp.text(),\n resp.headers.get('Content-Type') || 'text/plain',\n ];\n }\n if (resp.status === 404) {\n throw new Error('404');\n }\n throw new Error(`${resp.status}: ${resp.statusText}`);\n }\n}\n","import {\n createApiFactory,\n createPlugin,\n createRoutableExtension,\n discoveryApiRef,\n fetchApiRef,\n identityApiRef,\n} from '@backstage/core-plugin-api';\n\nimport { rootRouteRef } from './routes';\nimport { readmeApiRef } from './api/ReadmeApi';\nimport { ReadmeClient } from './api/ReadmeClient';\n\n/**\n * Plugin that provides the Readme api\n * @public */\nexport const readmePlugin = createPlugin({\n id: 'readme',\n apis: [\n createApiFactory({\n api: readmeApiRef,\n deps: {\n discoveryApi: discoveryApiRef,\n fetchApi: fetchApiRef,\n identityApi: identityApiRef,\n },\n factory: ({ discoveryApi, fetchApi, identityApi }) =>\n new ReadmeClient({ discoveryApi, fetchApi, identityApi }),\n }),\n ],\n routes: {\n root: rootRouteRef,\n },\n});\n\n/**\n * Readme card exported from the Readme plugin\n * @public */\nexport const ReadmeCard = readmePlugin.provide(\n createRoutableExtension({\n name: 'ReadmeCard',\n component: () => import('./components/ReadmeCard').then(m => m.ReadmeCard),\n mountPoint: rootRouteRef,\n }),\n);\n"],"names":[],"mappings":";;AAEO,MAAM,eAAe,cAAe,CAAA;AAAA,EACzC,EAAI,EAAA,QAAA;AACN,CAAC,CAAA;;ACFM,MAAM,eAAe,YAAwB,CAAA;AAAA,EAClD,EAAI,EAAA,eAAA;AACN,CAAC;;;;;;;;ACGM,MAAM,YAAkC,CAAA;AAAA,EAK7C,YAAY,OAIT,EAAA;AARH,IAAiB,aAAA,CAAA,IAAA,EAAA,cAAA,CAAA,CAAA;AACjB,IAAiB,aAAA,CAAA,IAAA,EAAA,UAAA,CAAA,CAAA;AACjB,IAAiB,aAAA,CAAA,IAAA,EAAA,aAAA,CAAA,CAAA;AAOf,IAAA,IAAA,CAAK,eAAe,OAAQ,CAAA,YAAA,CAAA;AAC5B,IAAA,IAAA,CAAK,WAAW,OAAQ,CAAA,QAAA,CAAA;AACxB,IAAA,IAAA,CAAK,cAAc,OAAQ,CAAA,WAAA,CAAA;AAAA,GAC7B;AAAA,EAEA,MAAM,iBAAiB,SAA8C,EAAA;AACnE,IAAA,MAAM,EAAE,KAAM,EAAA,GAAI,MAAM,IAAA,CAAK,YAAY,cAAe,EAAA,CAAA;AACxD,IAAA,MAAM,OAAU,GAAA,MAAM,IAAK,CAAA,YAAA,CAAa,WAAW,QAAQ,CAAA,CAAA;AAE3D,IAAM,MAAA,IAAA,GAAO,MAAM,IAAA,CAAK,QAAS,CAAA,KAAA;AAAA,MAC/B,CAAG,EAAA,OAAO,CAAI,CAAA,EAAA,kBAAA,CAAmB,SAAS,CAAC,CAAA,CAAA;AAAA,MAC3C;AAAA,QACE,MAAQ,EAAA,KAAA;AAAA,QACR,OAAS,EAAA,EAAE,aAAe,EAAA,CAAA,OAAA,EAAU,KAAK,CAAG,CAAA,EAAA;AAAA,OAC9C;AAAA,KACF,CAAA;AACA,IAAA,IAAI,KAAK,EAAI,EAAA;AACX,MAAO,OAAA;AAAA,QACL,MAAM,KAAK,IAAK,EAAA;AAAA,QAChB,IAAK,CAAA,OAAA,CAAQ,GAAI,CAAA,cAAc,CAAK,IAAA,YAAA;AAAA,OACtC,CAAA;AAAA,KACF;AACA,IAAI,IAAA,IAAA,CAAK,WAAW,GAAK,EAAA;AACvB,MAAM,MAAA,IAAI,MAAM,KAAK,CAAA,CAAA;AAAA,KACvB;AACA,IAAM,MAAA,IAAI,MAAM,CAAG,EAAA,IAAA,CAAK,MAAM,CAAK,EAAA,EAAA,IAAA,CAAK,UAAU,CAAE,CAAA,CAAA,CAAA;AAAA,GACtD;AACF;;AC5BO,MAAM,eAAe,YAAa,CAAA;AAAA,EACvC,EAAI,EAAA,QAAA;AAAA,EACJ,IAAM,EAAA;AAAA,IACJ,gBAAiB,CAAA;AAAA,MACf,GAAK,EAAA,YAAA;AAAA,MACL,IAAM,EAAA;AAAA,QACJ,YAAc,EAAA,eAAA;AAAA,QACd,QAAU,EAAA,WAAA;AAAA,QACV,WAAa,EAAA,cAAA;AAAA,OACf;AAAA,MACA,OAAS,EAAA,CAAC,EAAE,YAAA,EAAc,QAAU,EAAA,WAAA,EAClC,KAAA,IAAI,YAAa,CAAA,EAAE,YAAc,EAAA,QAAA,EAAU,aAAa,CAAA;AAAA,KAC3D,CAAA;AAAA,GACH;AAAA,EACA,MAAQ,EAAA;AAAA,IACN,IAAM,EAAA,YAAA;AAAA,GACR;AACF,CAAC,EAAA;AAKM,MAAM,aAAa,YAAa,CAAA,OAAA;AAAA,EACrC,uBAAwB,CAAA;AAAA,IACtB,IAAM,EAAA,YAAA;AAAA,IACN,SAAA,EAAW,MAAM,OAAO,yBAAyB,EAAE,IAAK,CAAA,CAAA,CAAA,KAAK,EAAE,UAAU,CAAA;AAAA,IACzE,UAAY,EAAA,YAAA;AAAA,GACb,CAAA;AACH;;;;"}