@braidlabs/gateway 0.4.0 → 0.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +14 -7
- package/package.json +1 -1
- package/src/appd.d.ts +26 -8
- package/src/appd.js +56 -9
- package/src/appd.js.map +1 -1
- package/src/discovery.js +19 -17
- package/src/discovery.js.map +1 -1
- package/src/index.d.ts +2 -2
- package/src/index.js +1 -1
- package/src/index.js.map +1 -1
package/README.md
CHANGED
|
@@ -45,8 +45,9 @@ to load, and the element to mount:
|
|
|
45
45
|
createGateway({ registry, discovery: { appd: true } });
|
|
46
46
|
```
|
|
47
47
|
|
|
48
|
-
Serves the same registry
|
|
49
|
-
`/appd/v2/apps/{appId}`
|
|
48
|
+
Serves the same registry as an FDC3 2.2 App Directory: `/__braid/registry/appd/v2/apps` lists
|
|
49
|
+
`{ applications, message }`, and `/appd/v2/apps/{appId}` returns the bare `Application` record.
|
|
50
|
+
It is a **projection, not a second directory** — same manifests, same
|
|
50
51
|
`access.list` rules — so a caller can never see through AppD a resolver that discovery would have
|
|
51
52
|
hidden. `findIntent` becomes a registry query, and a user only sees resolvers they may use.
|
|
52
53
|
|
|
@@ -69,11 +70,17 @@ Two mapping decisions worth knowing:
|
|
|
69
70
|
A fragment is *mounted into a page*, not opened as a window, so a Braid-aware agent reads
|
|
70
71
|
`hostManifests.braid` and mounts a `<fragment-slot>`; one that does not falls back to the URL.
|
|
71
72
|
|
|
72
|
-
An app the caller may not list 404s
|
|
73
|
-
let an unauthorized caller enumerate the registry
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
73
|
+
An app the caller may not list 404s (with AppD's `{ code, message }` error body) exactly as an
|
|
74
|
+
unregistered one does — distinguishing them would let an unauthorized caller enumerate the registry
|
|
75
|
+
one id at a time.
|
|
76
|
+
|
|
77
|
+
Records are validated in the test suite against FDC3 2.2's own App Directory schema. Relative icon
|
|
78
|
+
`src` values are resolved against the origin, since AppD requires absolute URLs, and a link that is
|
|
79
|
+
not http(s) is dropped rather than passed on. Optional members
|
|
80
|
+
Braid has no data for (`lang`, `screenshots`, `localizedVersions`, `interop.appChannels`) are not
|
|
81
|
+
produced. To serve the same directory from the governed registry instead of a gateway, see
|
|
82
|
+
`createRegistryApi({ appd })` in `@braidlabs/registry`; to give fragments `window.fdc3`, see
|
|
83
|
+
`@braidlabs/fdc3`.
|
|
77
84
|
|
|
78
85
|
A relative `entry` is re-rooted into the fragment's namespace, so the module and its imports are
|
|
79
86
|
fetched through the gateway rather than from the host's root. Such a fragment serves no document,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@braidlabs/gateway",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.5.0",
|
|
4
4
|
"description": "Braid gateway — fetch-native origin-front middleware that routes fragment traffic by exact id under the reserved /__braid/frag/ namespace, loads fragment manifests, and passes everything else through to your existing app.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"micro-frontends",
|
package/src/appd.d.ts
CHANGED
|
@@ -11,9 +11,9 @@ import type { ResolvedFragmentManifest } from './registry.js';
|
|
|
11
11
|
* The payoff for FDC3 is direct: `findIntent` becomes a registry query, and because discovery
|
|
12
12
|
* filters by the caller's principal, a user only ever sees resolvers they are permitted to use.
|
|
13
13
|
*
|
|
14
|
-
*
|
|
15
|
-
*
|
|
16
|
-
*
|
|
14
|
+
* Records are checked against FDC3 2.2's own AppD schema in `appd.spec.ts` (vendored under
|
|
15
|
+
* `tools/fdc3/`). Optional members Braid has no data for — `lang`, `screenshots`,
|
|
16
|
+
* `localizedVersions`, `interop.appChannels` — are not produced.
|
|
17
17
|
*/
|
|
18
18
|
/** The `fdc3` block a manifest may carry. A superset of what AppD needs; the rest is for the runtime. */
|
|
19
19
|
export interface FragmentFdc3Metadata {
|
|
@@ -51,14 +51,14 @@ export interface FragmentAppdMetadata {
|
|
|
51
51
|
type?: string;
|
|
52
52
|
}[];
|
|
53
53
|
}
|
|
54
|
+
/** An FDC3 AppD v2 `Application` record — the members Braid fills. */
|
|
54
55
|
export interface AppdApplication {
|
|
55
56
|
appId: string;
|
|
56
|
-
|
|
57
|
+
title: string;
|
|
57
58
|
type: 'web';
|
|
58
59
|
details: {
|
|
59
60
|
url: string;
|
|
60
61
|
};
|
|
61
|
-
title?: string;
|
|
62
62
|
description?: string;
|
|
63
63
|
tooltip?: string;
|
|
64
64
|
version?: string;
|
|
@@ -75,7 +75,6 @@ export interface AppdApplication {
|
|
|
75
75
|
interop?: {
|
|
76
76
|
intents?: {
|
|
77
77
|
listensFor?: Record<string, {
|
|
78
|
-
name: string;
|
|
79
78
|
displayName?: string;
|
|
80
79
|
contexts: string[];
|
|
81
80
|
resultType?: string;
|
|
@@ -110,10 +109,29 @@ export interface AppdListResponse {
|
|
|
110
109
|
applications: AppdApplication[];
|
|
111
110
|
message: string;
|
|
112
111
|
}
|
|
113
|
-
|
|
114
|
-
|
|
112
|
+
/** AppD's error body, `ErrorDTO`. */
|
|
113
|
+
export interface AppdError {
|
|
114
|
+
code: number;
|
|
115
115
|
message: string;
|
|
116
116
|
}
|
|
117
|
+
/**
|
|
118
|
+
* The App Directory's two reads over a set of manifests the caller may already see: the listing,
|
|
119
|
+
* or one application by `appId`. `GET /v2/apps/{appId}` answers with the bare `Application`, not
|
|
120
|
+
* a wrapper. Headers are the caller's — what may be cached differs between the gateway, whose
|
|
121
|
+
* listing depends on who asked, and the registry.
|
|
122
|
+
*/
|
|
123
|
+
export declare function appdResponse(options: {
|
|
124
|
+
manifests: readonly ResolvedFragmentManifest[];
|
|
125
|
+
origin: string;
|
|
126
|
+
/** Present for `/v2/apps/{appId}`, absent for the listing. */
|
|
127
|
+
appId?: string;
|
|
128
|
+
}): {
|
|
129
|
+
status: 200;
|
|
130
|
+
body: AppdListResponse | AppdApplication;
|
|
131
|
+
} | {
|
|
132
|
+
status: 404;
|
|
133
|
+
body: AppdError;
|
|
134
|
+
};
|
|
117
135
|
/**
|
|
118
136
|
* Projects one manifest into an AppD record.
|
|
119
137
|
*
|
package/src/appd.js
CHANGED
|
@@ -1,4 +1,31 @@
|
|
|
1
1
|
import { BRAID_FRAGMENT_PREFIX } from './protocol.js';
|
|
2
|
+
/**
|
|
3
|
+
* The App Directory's two reads over a set of manifests the caller may already see: the listing,
|
|
4
|
+
* or one application by `appId`. `GET /v2/apps/{appId}` answers with the bare `Application`, not
|
|
5
|
+
* a wrapper. Headers are the caller's — what may be cached differs between the gateway, whose
|
|
6
|
+
* listing depends on who asked, and the registry.
|
|
7
|
+
*/
|
|
8
|
+
export function appdResponse(options) {
|
|
9
|
+
const { manifests, origin, appId } = options;
|
|
10
|
+
if (appId === undefined) {
|
|
11
|
+
// one manifest the projection cannot read is left out, not allowed to fail everyone's listing
|
|
12
|
+
const applications = manifests.flatMap((manifest) => {
|
|
13
|
+
try {
|
|
14
|
+
return [toAppdApplication(manifest, origin)];
|
|
15
|
+
}
|
|
16
|
+
catch {
|
|
17
|
+
return [];
|
|
18
|
+
}
|
|
19
|
+
});
|
|
20
|
+
return { status: 200, body: { applications, message: 'OK' } };
|
|
21
|
+
}
|
|
22
|
+
const match = manifests.find((manifest) => manifest.id === appId);
|
|
23
|
+
// the same 404 for "not visible to you" as for "not registered" — distinguishing them would let
|
|
24
|
+
// an unauthorized caller enumerate the registry one id at a time
|
|
25
|
+
if (!match)
|
|
26
|
+
return { status: 404, body: { code: 404, message: `No application with appId "${appId}"` } };
|
|
27
|
+
return { status: 200, body: toAppdApplication(match, origin) };
|
|
28
|
+
}
|
|
2
29
|
/**
|
|
3
30
|
* Projects one manifest into an AppD record.
|
|
4
31
|
*
|
|
@@ -15,12 +42,12 @@ import { BRAID_FRAGMENT_PREFIX } from './protocol.js';
|
|
|
15
42
|
export function toAppdApplication(manifest, origin) {
|
|
16
43
|
const mount = `${BRAID_FRAGMENT_PREFIX}${encodeURIComponent(manifest.id)}/`;
|
|
17
44
|
const page = firstPiercePage(manifest.pierce);
|
|
45
|
+
// `name` is deprecated in AppD v2 in favour of `appId` and `title`, so it is not set.
|
|
18
46
|
const application = {
|
|
19
47
|
appId: manifest.id,
|
|
20
|
-
|
|
48
|
+
title: manifest.title ?? manifest.id,
|
|
21
49
|
type: 'web',
|
|
22
50
|
details: { url: new URL(page ?? mount, origin).href },
|
|
23
|
-
title: manifest.title ?? manifest.id,
|
|
24
51
|
hostManifests: {
|
|
25
52
|
braid: { fragmentId: manifest.id, mount, adapter: manifest.adapter, standalonePage: page !== null },
|
|
26
53
|
},
|
|
@@ -36,14 +63,20 @@ export function toAppdApplication(manifest, origin) {
|
|
|
36
63
|
application.contactEmail = appd.contactEmail;
|
|
37
64
|
if (appd?.supportEmail)
|
|
38
65
|
application.supportEmail = appd.supportEmail;
|
|
39
|
-
|
|
40
|
-
|
|
66
|
+
const moreInfo = appd?.moreInfo ? webUrl(appd.moreInfo, origin) : null;
|
|
67
|
+
if (moreInfo)
|
|
68
|
+
application.moreInfo = moreInfo;
|
|
41
69
|
if (appd?.version)
|
|
42
70
|
application.version = appd.version;
|
|
43
71
|
if (appd?.tooltip)
|
|
44
72
|
application.tooltip = appd.tooltip;
|
|
45
|
-
|
|
46
|
-
|
|
73
|
+
// AppD requires an absolute icon url; a manifest may name one relative to the shell
|
|
74
|
+
const icons = (appd?.icons ?? []).flatMap((icon) => {
|
|
75
|
+
const src = webUrl(icon.src, origin);
|
|
76
|
+
return src ? [{ ...icon, src }] : [];
|
|
77
|
+
});
|
|
78
|
+
if (icons.length)
|
|
79
|
+
application.icons = icons;
|
|
47
80
|
const interop = toInterop(manifest.fdc3);
|
|
48
81
|
if (interop)
|
|
49
82
|
application.interop = interop;
|
|
@@ -53,10 +86,8 @@ function toInterop(fdc3) {
|
|
|
53
86
|
if (!fdc3)
|
|
54
87
|
return undefined;
|
|
55
88
|
const listensFor = Object.entries(fdc3.listensFor ?? {}).reduce((accumulator, [intent, declaration]) => {
|
|
56
|
-
//
|
|
57
|
-
// rather than requiring it in the manifest keeps one source of truth for the intent's name.
|
|
89
|
+
// the key is the intent's name; AppD v2's intent record has no `name` member of its own
|
|
58
90
|
accumulator[intent] = {
|
|
59
|
-
name: intent,
|
|
60
91
|
contexts: declaration.contexts ?? [],
|
|
61
92
|
...(declaration.displayName ? { displayName: declaration.displayName } : {}),
|
|
62
93
|
...(declaration.resultType ? { resultType: declaration.resultType } : {}),
|
|
@@ -73,6 +104,22 @@ function toInterop(fdc3) {
|
|
|
73
104
|
};
|
|
74
105
|
return Object.keys(interop).length > 0 ? interop : undefined;
|
|
75
106
|
}
|
|
107
|
+
/**
|
|
108
|
+
* A manifest-supplied link, absolute on `origin`, or null when it is not an http(s) URL. Dropping
|
|
109
|
+
* a bad one keeps one manifest's typo from failing the whole listing, and keeps `javascript:` out
|
|
110
|
+
* of every launcher that renders the directory.
|
|
111
|
+
*/
|
|
112
|
+
function webUrl(value, origin) {
|
|
113
|
+
if (typeof value !== 'string')
|
|
114
|
+
return null;
|
|
115
|
+
try {
|
|
116
|
+
const url = new URL(value, origin);
|
|
117
|
+
return url.protocol === 'https:' || url.protocol === 'http:' ? url.href : null;
|
|
118
|
+
}
|
|
119
|
+
catch {
|
|
120
|
+
return null;
|
|
121
|
+
}
|
|
122
|
+
}
|
|
76
123
|
/**
|
|
77
124
|
* The first pierce pattern reduced to a concrete page path.
|
|
78
125
|
*
|
package/src/appd.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"appd.js","sourceRoot":"","sources":["../../../../libs/braid-gateway/src/appd.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,qBAAqB,EAAE,MAAM,eAAe,CAAC;
|
|
1
|
+
{"version":3,"file":"appd.js","sourceRoot":"","sources":["../../../../libs/braid-gateway/src/appd.ts"],"names":[],"mappings":"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"}
|
package/src/discovery.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { BRAID_FRAGMENT_PREFIX, BRAID_PROTOCOL_VERSION } from './protocol.js';
|
|
2
|
-
import {
|
|
2
|
+
import { appdResponse } from './appd.js';
|
|
3
3
|
import { canFetch, canList } from './registry.js';
|
|
4
4
|
export const DEFAULT_DISCOVERY_PATH = '/__braid/registry';
|
|
5
5
|
export const DEFAULT_DISCOVERY_PAGE_SIZE = 100;
|
|
@@ -41,22 +41,15 @@ export function createDiscoveryHandler(registry, options, mode, resolvePrincipal
|
|
|
41
41
|
// so a caller can never see a resolver through AppD that discovery would have hidden.
|
|
42
42
|
if (appdEnabled && url.pathname.startsWith(appdPath)) {
|
|
43
43
|
const requested = url.pathname.slice(appdPath.length).replace(/^\//, '');
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
if (!match) {
|
|
54
|
-
// 404 for "not visible to you" as well as "not registered" — distinguishing them would
|
|
55
|
-
// let an unauthorized caller enumerate the registry one id at a time.
|
|
56
|
-
return json({ message: `No application with appId "${appId}"` }, 404, { 'Cache-Control': 'no-store' });
|
|
57
|
-
}
|
|
58
|
-
const body = { application: toAppdApplication(match, url.origin), message: 'OK' };
|
|
59
|
-
return json(body, 200, { 'Cache-Control': 'no-store', Vary: 'cookie, authorization' });
|
|
44
|
+
const { status, body } = appdResponse({
|
|
45
|
+
manifests: visible,
|
|
46
|
+
origin: url.origin,
|
|
47
|
+
...(requested ? { appId: safeDecode(requested) } : {}),
|
|
48
|
+
});
|
|
49
|
+
return json(body, status, {
|
|
50
|
+
'Cache-Control': 'no-store',
|
|
51
|
+
...(status === 200 ? { Vary: 'cookie, authorization' } : {}),
|
|
52
|
+
});
|
|
60
53
|
}
|
|
61
54
|
const pageSize = clampPageSize(url.searchParams.get('pageSize'), defaultPageSize, maxPageSize);
|
|
62
55
|
const totalPages = Math.max(1, Math.ceil(visible.length / pageSize));
|
|
@@ -118,6 +111,15 @@ function clampPage(requested, totalPages) {
|
|
|
118
111
|
return 1;
|
|
119
112
|
return Math.min(parsed, totalPages);
|
|
120
113
|
}
|
|
114
|
+
/** A malformed escape names no application, rather than throwing. */
|
|
115
|
+
function safeDecode(segment) {
|
|
116
|
+
try {
|
|
117
|
+
return decodeURIComponent(segment);
|
|
118
|
+
}
|
|
119
|
+
catch {
|
|
120
|
+
return segment;
|
|
121
|
+
}
|
|
122
|
+
}
|
|
121
123
|
function json(body, status, headers = {}) {
|
|
122
124
|
return new Response(JSON.stringify(body), {
|
|
123
125
|
status,
|
package/src/discovery.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"discovery.js","sourceRoot":"","sources":["../../../../libs/braid-gateway/src/discovery.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,qBAAqB,EAAE,sBAAsB,EAAE,MAAM,eAAe,CAAC;AAC9E,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"discovery.js","sourceRoot":"","sources":["../../../../libs/braid-gateway/src/discovery.ts"],"names":[],"mappings":"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"}
|
package/src/index.d.ts
CHANGED
|
@@ -25,8 +25,8 @@ export type { FragmentManifest, ResolvedFragmentManifest, FragmentFallback, Frag
|
|
|
25
25
|
export { satisfies, canList, canFetch } from './registry.js';
|
|
26
26
|
export { DEFAULT_DISCOVERY_PATH, DEFAULT_DISCOVERY_PAGE_SIZE } from './discovery.js';
|
|
27
27
|
export type { DiscoveryOptions, DiscoveryEntry, DiscoveryPage } from './discovery.js';
|
|
28
|
-
export { toAppdApplication } from './appd.js';
|
|
29
|
-
export type { AppdApplication, AppdListResponse,
|
|
28
|
+
export { appdResponse, toAppdApplication } from './appd.js';
|
|
29
|
+
export type { AppdApplication, AppdListResponse, AppdError, FragmentFdc3Metadata, FragmentAppdMetadata, } from './appd.js';
|
|
30
30
|
export { BRAID_FRAGMENT_PREFIX, BRAID_REALM_PREFIX, BRAID_DOCUMENT_PREFIX, BRAID_PROTOCOL_VERSION, BRAID_SERVICE_WORKER_PATH, parseBraidPathname, } from './protocol.js';
|
|
31
31
|
export type { BraidRoute, BraidRouteKind } from './protocol.js';
|
|
32
32
|
export { rewriteHtmlStream, concatStreams } from './rewriter/html-rewrite-stream.js';
|
package/src/index.js
CHANGED
|
@@ -19,7 +19,7 @@ export { createSingleFlight, singleFlightKey } from './single-flight.js';
|
|
|
19
19
|
export { DEFAULT_ADAPTER, DEFAULT_TIMEOUT_MS, normalizeManifest, Registry, } from './registry.js';
|
|
20
20
|
export { satisfies, canList, canFetch } from './registry.js';
|
|
21
21
|
export { DEFAULT_DISCOVERY_PATH, DEFAULT_DISCOVERY_PAGE_SIZE } from './discovery.js';
|
|
22
|
-
export { toAppdApplication } from './appd.js';
|
|
22
|
+
export { appdResponse, toAppdApplication } from './appd.js';
|
|
23
23
|
export { BRAID_FRAGMENT_PREFIX, BRAID_REALM_PREFIX, BRAID_DOCUMENT_PREFIX, BRAID_PROTOCOL_VERSION, BRAID_SERVICE_WORKER_PATH, parseBraidPathname, } from './protocol.js';
|
|
24
24
|
export { rewriteHtmlStream, concatStreams } from './rewriter/html-rewrite-stream.js';
|
|
25
25
|
export { prepareFragmentHtml, pierceShellHtml, BRAID_FRAGMENT_STYLES, BRAID_SHELL_STYLES, } from './rewriter/transforms.js';
|
package/src/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../libs/braid-gateway/src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,OAAO,EAAE,aAAa,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAE9E,OAAO,EAAE,SAAS,EAAE,iBAAiB,EAAE,qBAAqB,EAAE,MAAM,gBAAgB,CAAC;AACrF,OAAO,EAAE,aAAa,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAC9D,OAAO,EAAE,kBAAkB,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AAYzE,OAAO,EACL,eAAe,EACf,kBAAkB,EAClB,iBAAiB,EACjB,QAAQ,GACT,MAAM,eAAe,CAAC;AAWvB,OAAO,EAAE,SAAS,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AAC7D,OAAO,EAAE,sBAAsB,EAAE,2BAA2B,EAAE,MAAM,gBAAgB,CAAC;AAErF,OAAO,EAAE,iBAAiB,EAAE,MAAM,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../libs/braid-gateway/src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,OAAO,EAAE,aAAa,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAE9E,OAAO,EAAE,SAAS,EAAE,iBAAiB,EAAE,qBAAqB,EAAE,MAAM,gBAAgB,CAAC;AACrF,OAAO,EAAE,aAAa,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAC9D,OAAO,EAAE,kBAAkB,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AAYzE,OAAO,EACL,eAAe,EACf,kBAAkB,EAClB,iBAAiB,EACjB,QAAQ,GACT,MAAM,eAAe,CAAC;AAWvB,OAAO,EAAE,SAAS,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AAC7D,OAAO,EAAE,sBAAsB,EAAE,2BAA2B,EAAE,MAAM,gBAAgB,CAAC;AAErF,OAAO,EAAE,YAAY,EAAE,iBAAiB,EAAE,MAAM,WAAW,CAAC;AAQ5D,OAAO,EACL,qBAAqB,EACrB,kBAAkB,EAClB,qBAAqB,EACrB,sBAAsB,EACtB,yBAAyB,EACzB,kBAAkB,GACnB,MAAM,eAAe,CAAC;AAEvB,OAAO,EAAE,iBAAiB,EAAE,aAAa,EAAE,MAAM,mCAAmC,CAAC;AAErF,OAAO,EACL,mBAAmB,EACnB,eAAe,EACf,qBAAqB,EACrB,kBAAkB,GACnB,MAAM,0BAA0B,CAAC;AAClC,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,0BAA0B,CAAC"}
|