@frontmcp/adapters 1.11.0-rc.2 → 1.11.1-rc.1
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/esm/index.mjs +2 -2
- package/esm/openapi/index.mjs +2 -2
- package/esm/package.json +6 -6
- package/esm/skills/index.mjs +1 -1
- package/index.js +2 -2
- package/openapi/index.js +2 -2
- package/openapi/openapi.adapter.d.ts.map +1 -1
- package/openapi/openapi.output-schema.d.ts +11 -0
- package/openapi/openapi.output-schema.d.ts.map +1 -0
- package/openapi/openapi.utils.d.ts.map +1 -1
- package/package.json +6 -6
- package/skills/bundle/bundle-diff.d.ts.map +1 -1
- package/skills/bundle/bundle.schema.d.ts +1 -0
- package/skills/bundle/bundle.schema.d.ts.map +1 -1
- package/skills/bundle/bundle.types.d.ts +2 -0
- package/skills/bundle/bundle.types.d.ts.map +1 -1
- package/skills/bundle/overlay-parser.d.ts.map +1 -1
- package/skills/index.d.ts +3 -3
- package/skills/index.d.ts.map +1 -1
- package/skills/index.js +1 -1
- package/skills/openapi/compile-skilled-bundle.d.ts +1 -0
- package/skills/openapi/compile-skilled-bundle.d.ts.map +1 -1
- package/skills/security/jwt-verifier.d.ts +1 -1
- package/skills/security/jwt-verifier.d.ts.map +1 -1
- package/skills/security/webhook-replay-guard.d.ts +3 -0
- package/skills/security/webhook-replay-guard.d.ts.map +1 -1
- package/skills/source-options.d.ts.map +1 -1
- package/skills/sources/index.d.ts +3 -3
- package/skills/sources/index.d.ts.map +1 -1
- package/skills/sources/saas-pull.source.d.ts +50 -12
- package/skills/sources/saas-pull.source.d.ts.map +1 -1
- package/skills/sources/skill-bundle-source.interface.d.ts +21 -4
- package/skills/sources/skill-bundle-source.interface.d.ts.map +1 -1
- package/skills/sources/static.source.d.ts +6 -2
- package/skills/sources/static.source.d.ts.map +1 -1
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { FrontMcpLogger } from '@frontmcp/sdk';
|
|
2
2
|
import type { ResolvedBundle } from '../bundle/bundle.types';
|
|
3
3
|
import type { SaasSourceOptions } from '../source-options';
|
|
4
|
-
import type { BundleSourceDeps, BundleSourceListener, SkillBundleSource } from './skill-bundle-source.interface';
|
|
4
|
+
import type { BundlePushReceiver, BundleSourceDeps, BundleSourceListener, SkillBundleSource } from './skill-bundle-source.interface';
|
|
5
5
|
/**
|
|
6
6
|
* The pinned pull token failed verification against `jwksUrl`, `expectedIssuer`
|
|
7
7
|
* or `expectedAudience`. Unlike an outage, this never falls back to a cached
|
|
@@ -10,6 +10,14 @@ import type { BundleSourceDeps, BundleSourceListener, SkillBundleSource } from '
|
|
|
10
10
|
export declare class SaasPullTokenRejectedError extends Error {
|
|
11
11
|
constructor(reason: string);
|
|
12
12
|
}
|
|
13
|
+
/**
|
|
14
|
+
* The token of a pushed bundle was refused: it fails the checks the pull token passes (`invalid-token`), or a push
|
|
15
|
+
* already used it (`replayed`). The pushed bundle is not applied.
|
|
16
|
+
*/
|
|
17
|
+
export declare class SaasPushRefusedError extends Error {
|
|
18
|
+
readonly refusal: 'invalid-token' | 'replayed';
|
|
19
|
+
constructor(refusal: 'invalid-token' | 'replayed', reason: string);
|
|
20
|
+
}
|
|
13
21
|
/**
|
|
14
22
|
* Pulls bundles from a configured SaaS endpoint via authenticated HTTPS.
|
|
15
23
|
*
|
|
@@ -17,13 +25,16 @@ export declare class SaasPullTokenRejectedError extends Error {
|
|
|
17
25
|
* - Always attempts a fresh pull on `start()`.
|
|
18
26
|
* - If the pull fails AND a cached bundle exists on disk, falls back to it
|
|
19
27
|
* and emits a warning. This prevents a SaaS outage at boot from killing
|
|
20
|
-
* the customer's MCP server.
|
|
21
|
-
*
|
|
28
|
+
* the customer's MCP server. The cache holds the last bundle the plugin
|
|
29
|
+
* applied ({@link SaasPullSource.keepBundle}): a pulled bundle that fails
|
|
30
|
+
* its signature or apply never replaces it.
|
|
31
|
+
* - If both pull and cache fail, `start()` throws. Polling still starts, so a
|
|
32
|
+
* later pull that succeeds loads the bundle.
|
|
22
33
|
*
|
|
23
34
|
* Refresh: poll on `pollIntervalMs`. Single-flight per source — overlapping
|
|
24
|
-
* polls are skipped, never queued.
|
|
25
|
-
*
|
|
26
|
-
*
|
|
35
|
+
* polls are skipped, never queued. With `enableWebhook` the source also takes
|
|
36
|
+
* pushed bundles ({@link SaasPullSource.verifyPushToken}): the plugin serves
|
|
37
|
+
* them at `POST /__skilled_openapi/push`.
|
|
27
38
|
*
|
|
28
39
|
* Before every pull the pinned `authToken` is verified: it must be a JWT signed
|
|
29
40
|
* by a key in the issuer's JWKS (`jwksUrl`), with `iss` equal to
|
|
@@ -36,7 +47,7 @@ export declare class SaasPullTokenRejectedError extends Error {
|
|
|
36
47
|
* NOTE: Bundle signature verification is applied by the bundle-sync service
|
|
37
48
|
* before the bundle becomes active.
|
|
38
49
|
*/
|
|
39
|
-
export declare class SaasPullSource implements SkillBundleSource {
|
|
50
|
+
export declare class SaasPullSource implements SkillBundleSource, BundlePushReceiver {
|
|
40
51
|
private readonly options;
|
|
41
52
|
private readonly cacheDir;
|
|
42
53
|
private readonly logger;
|
|
@@ -44,20 +55,39 @@ export declare class SaasPullSource implements SkillBundleSource {
|
|
|
44
55
|
readonly id: string;
|
|
45
56
|
private listeners;
|
|
46
57
|
private pollHandle;
|
|
47
|
-
|
|
58
|
+
/** The pull running now, from start, a poll or a refresh; only one runs at a time. */
|
|
59
|
+
private inFlightPull;
|
|
48
60
|
private stopped;
|
|
49
61
|
private readonly jwksService;
|
|
62
|
+
private readonly replayGuard?;
|
|
63
|
+
private pushSigningKeys?;
|
|
64
|
+
private pushSigningKeysLoading?;
|
|
50
65
|
constructor(options: SaasSourceOptions, cacheDir: string | undefined, logger: FrontMcpLogger, deps?: BundleSourceDeps);
|
|
66
|
+
/** This source, when `enableWebhook` is on: it then takes bundles pushed to the server. */
|
|
67
|
+
get push(): BundlePushReceiver | undefined;
|
|
68
|
+
/**
|
|
69
|
+
* Check the token of a pushed bundle: by the rules the pull token passes (a key in `jwksUrl`, `iss`, `aud`,
|
|
70
|
+
* `resource`, expiry), then by the replay guard, so its `iat` must be within five minutes and its `jti` unused.
|
|
71
|
+
* Throws {@link SaasPushRefusedError}, or a plain Error when the JWKS can't be read.
|
|
72
|
+
*/
|
|
73
|
+
verifyPushToken(token: string): Promise<void>;
|
|
74
|
+
/** Keep a bundle the plugin applied, pulled or pushed, as the last good one a start falls back to. */
|
|
75
|
+
keepBundle(bundle: ResolvedBundle): Promise<void>;
|
|
51
76
|
start(): Promise<void>;
|
|
77
|
+
private pullAtStart;
|
|
78
|
+
/** Run `pull` as the one pull in flight, so a start, a poll and a refresh never pull at once. */
|
|
79
|
+
private exclusivePull;
|
|
52
80
|
onChange(listener: BundleSourceListener): () => void;
|
|
53
81
|
stop(): Promise<void>;
|
|
54
82
|
private schedulePoll;
|
|
55
83
|
/**
|
|
56
|
-
* Manually pull a fresh bundle
|
|
84
|
+
* Manually pull a fresh bundle and notify listeners, resolving once they are
|
|
85
|
+
* done with it (the plugin applied and kept it, or refused it). Drive this
|
|
57
86
|
* from a Cron Trigger / Durable Object alarm on runtimes without background
|
|
58
|
-
* timers (where `disablePolling` is set). Single-flight:
|
|
59
|
-
*
|
|
60
|
-
*
|
|
87
|
+
* timers (where `disablePolling` is set). Single-flight: while a pull is
|
|
88
|
+
* already in flight it waits for that pull to finish, applied and kept, and
|
|
89
|
+
* returns `undefined` without pulling again; throws if its own pull fails (the
|
|
90
|
+
* caller — e.g. a scheduled handler — decides how to surface it).
|
|
61
91
|
*/
|
|
62
92
|
refresh(): Promise<ResolvedBundle | undefined>;
|
|
63
93
|
private pollOnce;
|
|
@@ -71,6 +101,14 @@ export declare class SaasPullSource implements SkillBundleSource {
|
|
|
71
101
|
* plain Error when the JWKS can't be fetched (an outage).
|
|
72
102
|
*/
|
|
73
103
|
private verifyPullToken;
|
|
104
|
+
/**
|
|
105
|
+
* The issuer's signing keys for checking a push token: fetched at most once a minute, and shared by concurrent
|
|
106
|
+
* pushes. A pull always fetches them, so a key the issuer removed stops a pull at once.
|
|
107
|
+
*/
|
|
108
|
+
private signingKeysForPush;
|
|
109
|
+
private fetchSigningKeys;
|
|
110
|
+
/** Check a token the issuer signed, against its JWKS, issuer and audience. */
|
|
111
|
+
private verifyIssuedToken;
|
|
74
112
|
private fetchOnce;
|
|
75
113
|
/** Where the last-good bundle is kept, for messages: an injected store (a Worker's KV) has no file path. */
|
|
76
114
|
private cacheLocation;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"saas-pull.source.d.ts","sourceRoot":"","sources":["../../../src/skills/sources/saas-pull.source.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAGpD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC;
|
|
1
|
+
{"version":3,"file":"saas-pull.source.d.ts","sourceRoot":"","sources":["../../../src/skills/sources/saas-pull.source.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAGpD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC;AAG7D,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AAC3D,OAAO,KAAK,EACV,kBAAkB,EAClB,gBAAgB,EAChB,oBAAoB,EACpB,iBAAiB,EAClB,MAAM,iCAAiC,CAAC;AASzC;;;;GAIG;AACH,qBAAa,0BAA2B,SAAQ,KAAK;gBACvC,MAAM,EAAE,MAAM;CAI3B;AAED;;;GAGG;AACH,qBAAa,oBAAqB,SAAQ,KAAK;IAE3C,QAAQ,CAAC,OAAO,EAAE,eAAe,GAAG,UAAU;gBAArC,OAAO,EAAE,eAAe,GAAG,UAAU,EAC9C,MAAM,EAAE,MAAM;CAKjB;AAqCD;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AACH,qBAAa,cAAe,YAAW,iBAAiB,EAAE,kBAAkB;IAcxE,OAAO,CAAC,QAAQ,CAAC,OAAO;IACxB,OAAO,CAAC,QAAQ,CAAC,QAAQ;IACzB,OAAO,CAAC,QAAQ,CAAC,MAAM;IACvB,OAAO,CAAC,QAAQ,CAAC,IAAI;IAhBvB,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IAEpB,OAAO,CAAC,SAAS,CAAmC;IACpD,OAAO,CAAC,UAAU,CAA6B;IAC/C,sFAAsF;IACtF,OAAO,CAAC,YAAY,CAA+B;IACnD,OAAO,CAAC,OAAO,CAAS;IACxB,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAuB;IACnD,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAC,CAAqB;IAClD,OAAO,CAAC,eAAe,CAAC,CAAyC;IACjE,OAAO,CAAC,sBAAsB,CAAC,CAAqB;gBAGjC,OAAO,EAAE,iBAAiB,EAC1B,QAAQ,EAAE,MAAM,GAAG,SAAS,EAC5B,MAAM,EAAE,cAAc,EACtB,IAAI,GAAE,gBAAqB;IAM9C,2FAA2F;IAC3F,IAAI,IAAI,IAAI,kBAAkB,GAAG,SAAS,CAEzC;IAED;;;;OAIG;IACG,eAAe,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAoBnD,sGAAsG;IACtG,UAAU,CAAC,MAAM,EAAE,cAAc,GAAG,OAAO,CAAC,IAAI,CAAC;IAI3C,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;YAcd,WAAW;IAsBzB,iGAAiG;IACjG,OAAO,CAAC,aAAa;IAQrB,QAAQ,CAAC,QAAQ,EAAE,oBAAoB,GAAG,MAAM,IAAI;IAO9C,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IAS3B,OAAO,CAAC,YAAY;IAcpB;;;;;;;;OAQG;IACG,OAAO,IAAI,OAAO,CAAC,cAAc,GAAG,SAAS,CAAC;YAatC,QAAQ;cAwBN,OAAO,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,OAAO,CAAC;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC;IAoBhH;;;;OAIG;YACW,eAAe;IAK7B;;;OAGG;IACH,OAAO,CAAC,kBAAkB;YAcZ,gBAAgB;IA0B9B,8EAA8E;YAChE,iBAAiB;YAuBjB,SAAS;IAkBvB,4GAA4G;IAC5G,OAAO,CAAC,aAAa;IAIrB,OAAO,CAAC,SAAS;YAKH,YAAY;YAeZ,SAAS;YAkBT,MAAM;CASrB"}
|
|
@@ -8,12 +8,15 @@ import type { ResolvedBundle } from '../bundle/bundle.types';
|
|
|
8
8
|
* its initial fetch and begins any background polling/watching.
|
|
9
9
|
* - `onChange()` registers a listener invoked every time a new bundle is
|
|
10
10
|
* available (initial fetch + every refresh).
|
|
11
|
+
* - `keepBundle()`, on a source with a last-good cache, keeps a bundle once
|
|
12
|
+
* the plugin has applied it.
|
|
11
13
|
* - `stop()` halts all background work and releases resources.
|
|
12
14
|
*
|
|
13
15
|
* Sources are responsible for parsing/validating their input into a
|
|
14
16
|
* ResolvedBundle (typically by calling `parseOverlay` from bundle/overlay-parser).
|
|
15
17
|
* They MUST NOT verify signatures themselves — the bundle-sync service applies
|
|
16
|
-
* the signature gate before swapping the bundle into the registry.
|
|
18
|
+
* the signature gate before swapping the bundle into the registry. For the same
|
|
19
|
+
* reason they never cache a bundle they fetched until they are asked to keep it.
|
|
17
20
|
*/
|
|
18
21
|
export interface SkillBundleSource {
|
|
19
22
|
/** Stable id of this source (e.g. 'static:/path/to/bundle.yaml'). */
|
|
@@ -35,14 +38,28 @@ export interface SkillBundleSource {
|
|
|
35
38
|
* remote/pulling sources implement it. On runtimes with no background
|
|
36
39
|
* execution (Cloudflare Workers) a Cron Trigger / Durable Object alarm
|
|
37
40
|
* calls this instead of relying on an internal timer. Resolves to the new
|
|
38
|
-
* bundle
|
|
39
|
-
*
|
|
41
|
+
* bundle once its listeners are done with it (the plugin has applied it, or
|
|
42
|
+
* refused it), or to `undefined` if a pull is already in flight / the source
|
|
43
|
+
* is stopped.
|
|
40
44
|
*/
|
|
41
45
|
refresh?(): Promise<ResolvedBundle | undefined>;
|
|
46
|
+
/**
|
|
47
|
+
* Keep a bundle the plugin applied as the last good one, which a start that can't fetch falls back to. Present on
|
|
48
|
+
* a source with a last-good cache: the `saas` source.
|
|
49
|
+
*/
|
|
50
|
+
keepBundle?(bundle: ResolvedBundle): Promise<void>;
|
|
51
|
+
/** Present on a source that takes pushed bundles: the `saas` source with `enableWebhook`. */
|
|
52
|
+
readonly push?: BundlePushReceiver;
|
|
42
53
|
/** Halt background work; idempotent. */
|
|
43
54
|
stop(): Promise<void>;
|
|
44
55
|
}
|
|
45
|
-
|
|
56
|
+
/** The check a pushed bundle's token passes before the bundle is applied. */
|
|
57
|
+
export interface BundlePushReceiver {
|
|
58
|
+
/** Resolves when the push token is accepted; throws when it is refused or can't be checked. */
|
|
59
|
+
verifyPushToken(token: string): Promise<void>;
|
|
60
|
+
}
|
|
61
|
+
/** Takes each new bundle; a pulling source waits for a promise it returns before its pull counts as done. */
|
|
62
|
+
export type BundleSourceListener = (bundle: ResolvedBundle) => unknown;
|
|
46
63
|
/**
|
|
47
64
|
* Pluggable last-good bundle cache. The default (Node) implementation writes to
|
|
48
65
|
* disk; V8-isolate runtimes (Cloudflare Workers) inject a KV-backed store
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"skill-bundle-source.interface.d.ts","sourceRoot":"","sources":["../../../src/skills/sources/skill-bundle-source.interface.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC;AAE7D
|
|
1
|
+
{"version":3,"file":"skill-bundle-source.interface.d.ts","sourceRoot":"","sources":["../../../src/skills/sources/skill-bundle-source.interface.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC;AAE7D;;;;;;;;;;;;;;;;;;GAkBG;AACH,MAAM,WAAW,iBAAiB;IAChC,qEAAqE;IACrE,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IAEpB;;;;OAIG;IACH,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IAEvB;;;OAGG;IACH,QAAQ,CAAC,QAAQ,EAAE,oBAAoB,GAAG,MAAM,IAAI,CAAC;IAErD;;;;;;;;;OASG;IACH,OAAO,CAAC,IAAI,OAAO,CAAC,cAAc,GAAG,SAAS,CAAC,CAAC;IAEhD;;;OAGG;IACH,UAAU,CAAC,CAAC,MAAM,EAAE,cAAc,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAEnD,6FAA6F;IAC7F,QAAQ,CAAC,IAAI,CAAC,EAAE,kBAAkB,CAAC;IAEnC,wCAAwC;IACxC,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CACvB;AAED,6EAA6E;AAC7E,MAAM,WAAW,kBAAkB;IACjC,+FAA+F;IAC/F,eAAe,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CAC/C;AAED,6GAA6G;AAC7G,MAAM,MAAM,oBAAoB,GAAG,CAAC,MAAM,EAAE,cAAc,KAAK,OAAO,CAAC;AAEvE;;;;GAIG;AACH,MAAM,WAAW,gBAAgB;IAC/B,IAAI,IAAI,OAAO,CAAC,cAAc,GAAG,SAAS,CAAC,CAAC;IAC5C,KAAK,CAAC,MAAM,EAAE,cAAc,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CAC9C;AAED;;;;;;;;GAQG;AACH,MAAM,WAAW,gBAAgB;IAC/B;;;OAGG;IACH,KAAK,CAAC,EAAE,gBAAgB,CAAC;IACzB;;;;OAIG;IACH,cAAc,CAAC,EAAE,OAAO,CAAC;CAC1B"}
|
|
@@ -3,7 +3,9 @@ import type { StaticSourceOptions } from '../source-options';
|
|
|
3
3
|
import type { BundleSourceListener, SkillBundleSource } from './skill-bundle-source.interface';
|
|
4
4
|
/**
|
|
5
5
|
* Loads a bundle from a local file (YAML or JSON). Optionally watches the
|
|
6
|
-
* file for changes via `fs.watch` and re-fetches on edit.
|
|
6
|
+
* file for changes via `fs.watch` and re-fetches on edit. The watch starts
|
|
7
|
+
* before the first read, so fixing a file that failed to load reloads it. A
|
|
8
|
+
* refresh that reads the same content as the last read applies nothing.
|
|
7
9
|
*
|
|
8
10
|
* Bundle file extensions:
|
|
9
11
|
* - `.yaml` / `.yml` — parsed as YAML
|
|
@@ -18,11 +20,13 @@ export declare class StaticSource implements SkillBundleSource {
|
|
|
18
20
|
private watcher;
|
|
19
21
|
private debounceTimer;
|
|
20
22
|
private stopped;
|
|
23
|
+
private lastContent;
|
|
21
24
|
constructor(options: StaticSourceOptions, logger: FrontMcpLogger);
|
|
22
25
|
start(): Promise<void>;
|
|
23
26
|
onChange(listener: BundleSourceListener): () => void;
|
|
24
27
|
stop(): Promise<void>;
|
|
25
|
-
private
|
|
28
|
+
private readBundleFile;
|
|
29
|
+
private parse;
|
|
26
30
|
private notify;
|
|
27
31
|
private beginWatch;
|
|
28
32
|
private scheduleRefresh;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"static.source.d.ts","sourceRoot":"","sources":["../../../src/skills/sources/static.source.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAKpD,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AAC7D,OAAO,KAAK,EAAE,oBAAoB,EAAE,iBAAiB,EAAE,MAAM,iCAAiC,CAAC;AAE/F
|
|
1
|
+
{"version":3,"file":"static.source.d.ts","sourceRoot":"","sources":["../../../src/skills/sources/static.source.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAKpD,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AAC7D,OAAO,KAAK,EAAE,oBAAoB,EAAE,iBAAiB,EAAE,MAAM,iCAAiC,CAAC;AAE/F;;;;;;;;;;GAUG;AACH,qBAAa,YAAa,YAAW,iBAAiB;IAUlD,OAAO,CAAC,QAAQ,CAAC,OAAO;IACxB,OAAO,CAAC,QAAQ,CAAC,MAAM;IAVzB,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IAEpB,OAAO,CAAC,SAAS,CAAmC;IACpD,OAAO,CAAC,OAAO,CAAgC;IAC/C,OAAO,CAAC,aAAa,CAA6B;IAClD,OAAO,CAAC,OAAO,CAAS;IACxB,OAAO,CAAC,WAAW,CAAqB;gBAGrB,OAAO,EAAE,mBAAmB,EAC5B,MAAM,EAAE,cAAc;IAKnC,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAS5B,QAAQ,CAAC,QAAQ,EAAE,oBAAoB,GAAG,MAAM,IAAI;IAO9C,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IAa3B,OAAO,CAAC,cAAc;IAItB,OAAO,CAAC,KAAK;IAkBb,OAAO,CAAC,MAAM;IAUd,OAAO,CAAC,UAAU;IAmBlB,OAAO,CAAC,eAAe;CAexB"}
|