@mongodb-js/oidc-plugin 0.1.0-alpha.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/dist/plugin.js ADDED
@@ -0,0 +1,465 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || function (mod) {
19
+ if (mod && mod.__esModule) return mod;
20
+ var result = {};
21
+ if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
22
+ __setModuleDefault(result, mod);
23
+ return result;
24
+ };
25
+ var __importDefault = (this && this.__importDefault) || function (mod) {
26
+ return (mod && mod.__esModule) ? mod : { "default": mod };
27
+ };
28
+ Object.defineProperty(exports, "__esModule", { value: true });
29
+ exports.MongoDBOIDCPluginImpl = void 0;
30
+ const types_1 = require("./types");
31
+ const util_1 = require("./util");
32
+ const openid_client_1 = require("openid-client");
33
+ const rfc_8252_http_server_1 = require("./rfc-8252-http-server");
34
+ const open_1 = __importDefault(require("open"));
35
+ const util_2 = require("util");
36
+ const crypto_1 = require("crypto");
37
+ const events_1 = require("events");
38
+ const api_1 = require("./api");
39
+ const child_process_1 = require("child_process");
40
+ // eslint-disable-next-line @typescript-eslint/consistent-type-imports
41
+ let _electron = undefined;
42
+ async function getDefaultOpenBrowser() {
43
+ // If running electron, use electron.shell.openExternal() by default
44
+ // to open a browser.
45
+ if (process.versions.electron && _electron !== 'cannot-require') {
46
+ try {
47
+ _electron ?? (_electron = await Promise.resolve().then(() => __importStar(require('electron'))));
48
+ return ({ url }) =>
49
+ // eslint-disable-next-line @typescript-eslint/consistent-type-imports
50
+ _electron.shell.openExternal(url);
51
+ }
52
+ catch {
53
+ _electron = 'cannot-require';
54
+ }
55
+ }
56
+ // Otherwise, use open() from npm.
57
+ return async ({ url }) => {
58
+ const child = await (0, open_1.default)(url);
59
+ child.unref();
60
+ return child;
61
+ };
62
+ }
63
+ const kEnableFallback = Symbol.for('@@mdb.oidcplugin.kEnableFallback');
64
+ /** @internal */
65
+ class MongoDBOIDCPluginImpl {
66
+ constructor(options) {
67
+ this.mapUserToAuthState = new Map();
68
+ this.options = options;
69
+ this.logger = options.logger ?? new events_1.EventEmitter();
70
+ this.mongoClientOptions = {
71
+ authMechanismProperties: {
72
+ REQUEST_TOKEN_CALLBACK: this.requestToken.bind(this),
73
+ REFRESH_TOKEN_CALLBACK: this.refreshToken.bind(this),
74
+ },
75
+ };
76
+ }
77
+ // Is this flow supported and allowed?
78
+ isFlowAllowed(flow) {
79
+ if (this.options.allowedFlows?.includes(flow) === false)
80
+ return false;
81
+ if (flow === 'auth-code' && this.options.openBrowser === false)
82
+ return false;
83
+ if (flow === 'device-auth' && !this.options.notifyDeviceFlow)
84
+ return false;
85
+ return true;
86
+ }
87
+ // Return the current state for a given [server, username] configuration,
88
+ // or create a new one if none exists.
89
+ getAuthState(serverMetadata, principalName) {
90
+ if (!serverMetadata.clientId) {
91
+ throw new types_1.MongoDBOIDCError('No clientId passed in server OIDC metadata object');
92
+ }
93
+ principalName ?? (principalName = null);
94
+ const key = JSON.stringify({
95
+ clientId: serverMetadata.clientId,
96
+ principalName,
97
+ });
98
+ const existing = this.mapUserToAuthState.get(key);
99
+ if (existing)
100
+ return existing;
101
+ const newState = {
102
+ serverOIDCMetadata: serverMetadata,
103
+ currentAuthAttempt: null,
104
+ currentTokenSet: null,
105
+ };
106
+ this.mapUserToAuthState.set(key, newState);
107
+ return newState;
108
+ }
109
+ getRedirectURI() {
110
+ if (!this.isFlowAllowed('auth-code'))
111
+ return '';
112
+ // TODO(MONGOSH-1394): Properly standardize a port
113
+ return this.options.redirectURI ?? 'http://localhost:27097/redirect';
114
+ }
115
+ getInitialOIDCIssuerAndClientParams(serverMetadata) {
116
+ return {
117
+ scope: [
118
+ ...new Set([
119
+ 'openid',
120
+ 'offline_access',
121
+ ...(serverMetadata.requestScopes ?? []),
122
+ ]),
123
+ ].join(' '),
124
+ issuerParams: {
125
+ authorization_endpoint: serverMetadata.authorizationEndpoint,
126
+ token_endpoint: serverMetadata.tokenEndpoint,
127
+ device_authorization_endpoint: serverMetadata.deviceAuthorizationEndpoint,
128
+ // Required by the TS definitions, but we just don't have this data
129
+ // at this point. We re-define it later where necessary.
130
+ issuer: '',
131
+ },
132
+ clientParams: {
133
+ client_id: serverMetadata.clientId,
134
+ client_secret: serverMetadata.clientSecret,
135
+ redirect_uris: [this.getRedirectURI()],
136
+ response_types: ['code'],
137
+ // At least Okta requires this:
138
+ token_endpoint_auth_method: serverMetadata.clientSecret
139
+ ? 'client_secret_post'
140
+ : 'none',
141
+ },
142
+ };
143
+ }
144
+ async openBrowser(options) {
145
+ // Consistency check: options.url is a valid URL.
146
+ new URL(options.url);
147
+ this.logger.emit('mongodb-oidc-plugin:open-browser', {
148
+ customOpener: !!this.options.openBrowser,
149
+ });
150
+ if (this.options.openBrowser === false) {
151
+ // We should never really get to this point
152
+ throw new Error('Cannot open browser if `openBrowser` is false');
153
+ }
154
+ if (typeof this.options.openBrowser === 'function') {
155
+ return await this.options.openBrowser(options);
156
+ }
157
+ if (this.options.openBrowser === undefined) {
158
+ const defaultOpener = await getDefaultOpenBrowser();
159
+ return await defaultOpener(options);
160
+ }
161
+ if (typeof this.options.openBrowser?.command === 'string') {
162
+ const child = (0, child_process_1.spawn)(this.options.openBrowser.command, [options.url], {
163
+ shell: true,
164
+ stdio: 'ignore',
165
+ detached: true,
166
+ signal: this.options.openBrowser.abortable ? options.signal : undefined,
167
+ });
168
+ child.unref();
169
+ return child;
170
+ }
171
+ throw new Error('Unknown format for `openBrowser`');
172
+ }
173
+ async notifyDeviceFlow(deviceFlowInformation) {
174
+ if (!this.options.notifyDeviceFlow) {
175
+ // Should never happen.
176
+ throw new Error('notifyDeviceFlow() requested but not provided');
177
+ }
178
+ this.logger.emit('mongodb-oidc-plugin:notify-device-flow');
179
+ await this.options.notifyDeviceFlow(deviceFlowInformation);
180
+ }
181
+ storeTokenSet(state, tokenSet, client) {
182
+ state.currentTokenSet = {
183
+ set: tokenSet,
184
+ tryRefresh: async () => {
185
+ // Only refresh this token set if it is the one currently
186
+ // being used.
187
+ if (state.currentTokenSet?.set !== tokenSet)
188
+ return false;
189
+ try {
190
+ const refreshedTokens = await client.refresh(tokenSet);
191
+ // Check again to avoid race conditions.
192
+ if (state.currentTokenSet?.set === tokenSet) {
193
+ this.storeTokenSet(state, refreshedTokens, client);
194
+ return true;
195
+ }
196
+ }
197
+ catch (err) {
198
+ this.logger.emit('mongodb-oidc-plugin:refresh-failed', {
199
+ error: (0, util_1.errorString)(err),
200
+ });
201
+ }
202
+ return false;
203
+ },
204
+ };
205
+ }
206
+ async authorizationCodeFlow(state, signal) {
207
+ const { scope, issuerParams, clientParams } = this.getInitialOIDCIssuerAndClientParams(state.serverOIDCMetadata);
208
+ const codeVerifier = openid_client_1.generators.codeVerifier();
209
+ const codeChallenge = openid_client_1.generators.codeChallenge(codeVerifier);
210
+ let issuer = new openid_client_1.Issuer(issuerParams);
211
+ let client = new issuer.Client(clientParams);
212
+ const oidcStateParam = (await (0, util_2.promisify)(crypto_1.randomBytes)(16)).toString('hex');
213
+ const server = new rfc_8252_http_server_1.RFC8252HTTPServer({
214
+ redirectUrl: this.getRedirectURI(),
215
+ logger: this.logger,
216
+ redirectServerRequestHandler: this.options.redirectServerRequestHandler,
217
+ oidcStateParam,
218
+ });
219
+ let paramsUrl = '';
220
+ let enableFallback = true;
221
+ try {
222
+ await (0, util_1.withAbortCheck)(signal, async ({ signalCheck, signalPromise }) => {
223
+ await Promise.race([server.listen(), signalPromise]);
224
+ const authCodeFlowUrl = client.authorizationUrl({
225
+ scope,
226
+ code_challenge: codeChallenge,
227
+ code_challenge_method: 'S256',
228
+ state: oidcStateParam,
229
+ });
230
+ const { localUrl, onAccessed: onLocalUrlAccessed } = await server.addRedirect(authCodeFlowUrl);
231
+ signalCheck();
232
+ // Handle errors from opening a browser but do not await the Promise
233
+ // in case it only resolves when the browser exits (which is the case
234
+ // for the default `open` handler).
235
+ const browserStatePromise = new Promise((resolve, reject) => {
236
+ this.openBrowser({ url: localUrl, signal })
237
+ .then((browserHandle) => {
238
+ browserHandle?.once('error', (err) => reject(err));
239
+ browserHandle?.once('exit', (code) => {
240
+ if (code !== 0)
241
+ reject(new types_1.MongoDBOIDCError(`Opening browser failed with exit code ${code}`));
242
+ });
243
+ })
244
+ .catch(reject);
245
+ });
246
+ const timeout = new Promise((resolve, reject) => {
247
+ if (this.options.openBrowserTimeout !== 0) {
248
+ setTimeout(reject, this.options.openBrowserTimeout ?? api_1.kDefaultOpenBrowserTimeout, new types_1.MongoDBOIDCError('Opening browser timed out')).unref();
249
+ }
250
+ });
251
+ browserStatePromise.catch(() => {
252
+ /* squelch UnhandledPromiseRejectionWarning */
253
+ });
254
+ timeout.catch(() => {
255
+ /* ditto */
256
+ });
257
+ await Promise.race([
258
+ onLocalUrlAccessed,
259
+ timeout,
260
+ browserStatePromise,
261
+ signalPromise,
262
+ ]);
263
+ // If we reached this point, we know that we have successfully opened
264
+ // a server listening on a local port and a browser and that the
265
+ // browser accessed the server. We do not want to fall back to another
266
+ // flow anymore, any error from here on is most likely a genuine
267
+ // authentication error.
268
+ enableFallback = false;
269
+ paramsUrl = await server.waitForOIDCParamsAndClose({ signal });
270
+ });
271
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
272
+ }
273
+ catch (err) {
274
+ // Tell the outer logic here to fallback to device auth flow if it is
275
+ // available if any of the steps above failed.
276
+ if (Object.isExtensible(err)) {
277
+ err[kEnableFallback] = enableFallback;
278
+ }
279
+ throw err;
280
+ }
281
+ finally {
282
+ await server.close();
283
+ }
284
+ const params = client.callbackParams(paramsUrl);
285
+ // The oidc-client library requires `issuer` to be set here; we did not
286
+ // set it when we assembled the original `issuerParams` (because it was
287
+ // not available as information), but we should have received it from the
288
+ // callback parameters and can set it here.
289
+ issuerParams.issuer = String(params.iss);
290
+ issuer = new openid_client_1.Issuer(issuerParams);
291
+ client = new issuer.Client(clientParams);
292
+ client.validateIdToken = () => {
293
+ // Do not attempt to validate the ID token. The client library would
294
+ // do this by default, but we do not have access to the necessary
295
+ // JWKS here. This is in direct conflict with the OIDC spec (!!)
296
+ // https://openid.net/specs/openid-connect-core-1_0.html#IDTokenValidation:
297
+ //
298
+ // > Clients MUST validate the ID Token in the Token Response in the following manner: [...]
299
+ //
300
+ // We accept this because for the purposes of this plugin, we do not
301
+ // interact with the identity token, nor do we actually consume the
302
+ // access token. We leave it to the the server to validate that the token is
303
+ // valid, refers to the right identity, and comes from the right source.
304
+ };
305
+ const tokenSet = await client.callback(this.getRedirectURI(), params, {
306
+ code_verifier: codeVerifier,
307
+ state: oidcStateParam,
308
+ });
309
+ this.storeTokenSet(state, tokenSet, client);
310
+ }
311
+ async deviceAuthorizationFlow(state, signal) {
312
+ const { scope, issuerParams, clientParams } = this.getInitialOIDCIssuerAndClientParams(state.serverOIDCMetadata);
313
+ const issuer = new openid_client_1.Issuer(issuerParams);
314
+ const client = new issuer.Client(clientParams);
315
+ client.validateIdToken = () => {
316
+ /* see above */
317
+ };
318
+ await (0, util_1.withAbortCheck)(signal, async ({ signalCheck, signalPromise }) => {
319
+ const deviceFlowHandle = await Promise.race([
320
+ client.deviceAuthorization({
321
+ client_id: clientParams.client_id,
322
+ scope,
323
+ }),
324
+ signalPromise,
325
+ ]);
326
+ signalCheck();
327
+ await this.notifyDeviceFlow({
328
+ userCode: deviceFlowHandle.user_code,
329
+ verificationUrl: deviceFlowHandle.verification_uri,
330
+ });
331
+ const tokenSet = await deviceFlowHandle.poll({ signal });
332
+ this.storeTokenSet(state, tokenSet, client);
333
+ });
334
+ }
335
+ async initiateAuthAttempt(state, driverAbortSignal) {
336
+ (0, util_1.throwIfAborted)(this.options.signal);
337
+ (0, util_1.throwIfAborted)(driverAbortSignal);
338
+ const combinedAbortController = new util_1.AbortController();
339
+ const optionsAbortCb = () => {
340
+ // @ts-expect-error TS doesn't understand .abort(reason)
341
+ combinedAbortController.abort(this.options.signal.reason);
342
+ };
343
+ const driverAbortCb = () => {
344
+ // @ts-expect-error TS doesn't understand .abort(reason)
345
+ combinedAbortController.abort(driverAbortSignal.reason);
346
+ };
347
+ this.options.signal?.addEventListener('abort', optionsAbortCb);
348
+ driverAbortSignal?.addEventListener('abort', driverAbortCb);
349
+ const signal = combinedAbortController.signal;
350
+ try {
351
+ get_tokens: {
352
+ if ((state.currentTokenSet?.set?.expires_in ?? 0) > 5 * 60) {
353
+ this.logger.emit('mongodb-oidc-plugin:skip-auth-attempt', {
354
+ reason: 'not-expired',
355
+ });
356
+ break get_tokens;
357
+ }
358
+ if (await state.currentTokenSet?.tryRefresh?.()) {
359
+ this.logger.emit('mongodb-oidc-plugin:skip-auth-attempt', {
360
+ reason: 'refresh-succeeded',
361
+ });
362
+ break get_tokens;
363
+ }
364
+ state.currentTokenSet = null;
365
+ let error;
366
+ if (this.isFlowAllowed('auth-code')) {
367
+ try {
368
+ this.logger.emit('mongodb-oidc-plugin:auth-attempt-started', {
369
+ flow: 'auth-code',
370
+ });
371
+ await this.authorizationCodeFlow(state, signal);
372
+ this.logger.emit('mongodb-oidc-plugin:auth-attempt-succeeded');
373
+ break get_tokens;
374
+ }
375
+ catch (err) {
376
+ error = err;
377
+ this.logger.emit('mongodb-oidc-plugin:auth-attempt-failed', {
378
+ error: (0, util_1.errorString)(err),
379
+ });
380
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
381
+ if (!err?.[kEnableFallback])
382
+ throw err;
383
+ }
384
+ }
385
+ if (this.isFlowAllowed('device-auth')) {
386
+ try {
387
+ this.logger.emit('mongodb-oidc-plugin:auth-attempt-started', {
388
+ flow: 'device-auth',
389
+ });
390
+ await this.deviceAuthorizationFlow(state, signal);
391
+ this.logger.emit('mongodb-oidc-plugin:auth-attempt-succeeded');
392
+ break get_tokens;
393
+ }
394
+ catch (err) {
395
+ this.logger.emit('mongodb-oidc-plugin:auth-attempt-failed', {
396
+ error: (0, util_1.errorString)(err),
397
+ });
398
+ throw err;
399
+ }
400
+ }
401
+ if (error)
402
+ throw error;
403
+ }
404
+ if (!state.currentTokenSet?.set?.access_token) {
405
+ throw new types_1.MongoDBOIDCError('Could not retrieve valid access token');
406
+ }
407
+ }
408
+ catch (err) {
409
+ this.logger.emit('mongodb-oidc-plugin:auth-failed', {
410
+ error: (0, util_1.errorString)(err),
411
+ });
412
+ throw err;
413
+ }
414
+ finally {
415
+ this.options.signal?.removeEventListener('abort', optionsAbortCb);
416
+ driverAbortSignal?.removeEventListener('abort', driverAbortCb);
417
+ }
418
+ this.logger.emit('mongodb-oidc-plugin:auth-succeeded', {
419
+ hasRefreshToken: !!state.currentTokenSet.set.refresh_token,
420
+ expiresAt: state.currentTokenSet.set.expires_at
421
+ ? new Date(state.currentTokenSet.set.expires_at * 1000).toISOString()
422
+ : null,
423
+ });
424
+ return {
425
+ accessToken: state.currentTokenSet.set.access_token,
426
+ refreshToken: state.currentTokenSet.set.refresh_token,
427
+ // Passing `expiresInSeconds: 0` results in the driver not caching the token.
428
+ // We perform our own caching here inside the plugin, so interactions with the
429
+ // cache of the driver are not really required or necessarily helpful.
430
+ // The driver cache has a finer cache key (host address instead of clientId),
431
+ // so may require more authentication attempts, and is global,
432
+ // not per-MongoClient.
433
+ // It probably would be fine to pass in the actual expiration time here, but
434
+ // there seem to be no benefits to doing so.
435
+ expiresInSeconds: 0,
436
+ };
437
+ }
438
+ async requestToken(principalName, serverMetadata, driverAbortSignal) {
439
+ const state = this.getAuthState(serverMetadata, principalName);
440
+ if (state.currentAuthAttempt) {
441
+ return await state.currentAuthAttempt;
442
+ }
443
+ // The currently plan is for the 6.x driver (which may drop support
444
+ // for Node.js 14.x) to pass in an actual AbortSignal here. For
445
+ // compatibility with the 5.x driver/AbortSignal-less-Node.js, we accept
446
+ // a timeout in milliseconds as well.
447
+ if (typeof driverAbortSignal === 'number') {
448
+ driverAbortSignal = (0, util_1.timeoutSignal)(driverAbortSignal);
449
+ }
450
+ const newAuthAttempt = this.initiateAuthAttempt(state, driverAbortSignal);
451
+ state.currentAuthAttempt = newAuthAttempt;
452
+ newAuthAttempt.finally(() => {
453
+ if (state.currentAuthAttempt === newAuthAttempt)
454
+ state.currentAuthAttempt = null;
455
+ });
456
+ return newAuthAttempt;
457
+ }
458
+ async refreshToken(principalName, serverMetadata,
459
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
460
+ previousResult, driverAbortSignal) {
461
+ return await this.requestToken(principalName, serverMetadata, driverAbortSignal);
462
+ }
463
+ }
464
+ exports.MongoDBOIDCPluginImpl = MongoDBOIDCPluginImpl;
465
+ //# sourceMappingURL=plugin.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"plugin.js","sourceRoot":"","sources":["../src/plugin.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,68 @@
1
+ import type { MongoDBOIDCLogEventsMap, OIDCAbortSignal, TypedEventEmitter } from './types';
2
+ import type { RedirectServerRequestHandler } from './api';
3
+ export interface RFC8252HTTPServerOptions {
4
+ redirectUrl: string;
5
+ oidcStateParam: string;
6
+ logger?: TypedEventEmitter<MongoDBOIDCLogEventsMap>;
7
+ redirectServerRequestHandler?: RedirectServerRequestHandler;
8
+ }
9
+ /** @internal */
10
+ export declare class RFC8252HTTPServer {
11
+ private readonly redirectUrl;
12
+ private readonly oidcStateParam;
13
+ private readonly redirectServerHandler;
14
+ private readonly logger;
15
+ private servers;
16
+ private readonly expressApp;
17
+ private readonly redirects;
18
+ private readonly oidcParamsPromise;
19
+ private oidcParamsResolve?;
20
+ private oidcParamsReject?;
21
+ private oidcParams;
22
+ constructor(options: RFC8252HTTPServerOptions);
23
+ private _handleSuccess;
24
+ private _handleRedirectToExternal;
25
+ private _handleOIDCCallback;
26
+ private _fallbackHandler;
27
+ /**
28
+ * Add a redirect from a local URL served on the server to an external URL.
29
+ */
30
+ addRedirect(targetUrl: string): Promise<{
31
+ localUrl: string;
32
+ onAccessed: Promise<void>;
33
+ }>;
34
+ /**
35
+ * Returns the port that this server is listening on if
36
+ * listen() was successfully called and undefined otherwise.
37
+ */
38
+ get listeningPort(): number | undefined;
39
+ /**
40
+ * Returns the full redirectURL passed to the constructor, with
41
+ * a possible unspecified port resolved to the actual port,
42
+ * or undefined if this server is not listening.
43
+ */
44
+ get listeningRedirectUrl(): string | undefined;
45
+ /**
46
+ * Create HTTP servers and listen on them corresponding to the redirect URL
47
+ * provided to the constructor.
48
+ */
49
+ listen(): Promise<void>;
50
+ private createServerAndListen;
51
+ /**
52
+ * Returns the OIDC params as the full URL used to access them
53
+ * (regardless of whether OIDC params were passed as URL params or not)
54
+ */
55
+ waitForOIDCParams(): Promise<string>;
56
+ /**
57
+ * Close all resources associated with this server.
58
+ */
59
+ close(): Promise<void>;
60
+ /**
61
+ * Convenience method to wait until a single successful OIDC parameter
62
+ * request is received or abort early, and close the server in any case.
63
+ */
64
+ waitForOIDCParamsAndClose({ signal, }?: {
65
+ signal?: OIDCAbortSignal;
66
+ }): Promise<string>;
67
+ }
68
+ //# sourceMappingURL=rfc-8252-http-server.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rfc-8252-http-server.d.ts","sourceRoot":"","sources":["../src/rfc-8252-http-server.ts"],"names":[],"mappings":"AASA,OAAO,KAAK,EACV,uBAAuB,EACvB,eAAe,EACf,iBAAiB,EAClB,MAAM,SAAS,CAAC;AAIjB,OAAO,KAAK,EACV,4BAA4B,EAE7B,MAAM,OAAO,CAAC;AAIf,MAAM,WAAW,wBAAwB;IACvC,WAAW,EAAE,MAAM,CAAC;IACpB,cAAc,EAAE,MAAM,CAAC;IACvB,MAAM,CAAC,EAAE,iBAAiB,CAAC,uBAAuB,CAAC,CAAC;IACpD,4BAA4B,CAAC,EAAE,4BAA4B,CAAC;CAC7D;AAED,gBAAgB;AAChB,qBAAa,iBAAiB;IAC5B,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAM;IAClC,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAS;IACxC,OAAO,CAAC,QAAQ,CAAC,qBAAqB,CAA+B;IACrE,OAAO,CAAC,QAAQ,CAAC,MAAM,CAA6C;IACpE,OAAO,CAAC,OAAO,CAAoB;IACnC,OAAO,CAAC,QAAQ,CAAC,UAAU,CAA6B;IACxD,OAAO,CAAC,QAAQ,CAAC,SAAS,CAGtB;IAIJ,OAAO,CAAC,QAAQ,CAAC,iBAAiB,CAAkB;IACpD,OAAO,CAAC,iBAAiB,CAAC,CAA2B;IACrD,OAAO,CAAC,gBAAgB,CAAC,CAAoC;IAG7D,OAAO,CAAC,UAAU,CAAqB;gBAE3B,OAAO,EAAE,wBAAwB;IAqC7C,OAAO,CAAC,cAAc,CAcpB;IAEF,OAAO,CAAC,yBAAyB,CAiB/B;IAEF,OAAO,CAAC,mBAAmB,CAmHzB;IAEF,OAAO,CAAC,gBAAgB,CAYtB;IAEF;;OAEG;IACU,WAAW,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC;QACnD,QAAQ,EAAE,MAAM,CAAC;QACjB,UAAU,EAAE,OAAO,CAAC,IAAI,CAAC,CAAC;KAC3B,CAAC;IAgBF;;;OAGG;IACH,IAAW,aAAa,IAAI,MAAM,GAAG,SAAS,CAa7C;IAED;;;;OAIG;IACH,IAAW,oBAAoB,IAAI,MAAM,GAAG,SAAS,CAMpD;IAED;;;OAGG;IACU,MAAM,IAAI,OAAO,CAAC,IAAI,CAAC;IA6GpC,OAAO,CAAC,qBAAqB;IAoB7B;;;OAGG;IACU,iBAAiB,IAAI,OAAO,CAAC,MAAM,CAAC;IAIjD;;OAEG;IACU,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAcnC;;;OAGG;IACU,yBAAyB,CAAC,EACrC,MAAM,GACP,GAAE;QACD,MAAM,CAAC,EAAE,eAAe,CAAC;KACrB,GAAG,OAAO,CAAC,MAAM,CAAC;CASzB"}