@ya-accelerators/web-backend-framework 0.0.87 → 0.0.89
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/connector/google-auth/index.d.ts +10 -0
- package/dist/connector/google-auth/index.js +34 -26
- package/dist/connector/google-auth/index.js.map +1 -1
- package/dist/env.d.ts +3 -2
- package/dist/env.js +16 -16
- package/dist/env.js.map +1 -1
- package/dist/internal/federation/index.d.ts +9 -0
- package/dist/internal/federation/index.js +34 -10
- package/dist/internal/federation/index.js.map +1 -1
- package/package.json +1 -1
|
@@ -7,3 +7,13 @@ export declare const googleIdTokenAuth: (wifConfigBase64: string, audience: stri
|
|
|
7
7
|
bearer: () => Promise<string>;
|
|
8
8
|
withAuth: <T>(fn: () => Promise<T>) => Promise<T>;
|
|
9
9
|
};
|
|
10
|
+
export declare const googleImpersonatedAuth: (wifConfigBase64: string, { label, lifetime, targetScopes }: {
|
|
11
|
+
label: string;
|
|
12
|
+
lifetime: number;
|
|
13
|
+
targetScopes: string[];
|
|
14
|
+
}) => {
|
|
15
|
+
accessToken: () => Promise<{
|
|
16
|
+
token: string;
|
|
17
|
+
serviceAccountEmail: string;
|
|
18
|
+
}>;
|
|
19
|
+
};
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { runWithRequestHeaders } from '../../context/request/index.js';
|
|
2
|
-
import { awsSecurityCredentialsSupplier, parseWifConfig } from '../../internal/federation/index.js';
|
|
2
|
+
import { awsSecurityCredentialsSupplier, impersonatedClient, parseWifConfig } from '../../internal/federation/index.js';
|
|
3
3
|
import { logger } from '../../logger/index.js';
|
|
4
|
-
// AWS → Google Workload Identity Federation auth primitives.
|
|
5
|
-
// a Google Workload Identity Pool and impersonate the configured service account; they differ only in
|
|
6
|
-
// token they mint. The framework owns all `google-auth-library` usage — consumers pass their own base64
|
|
4
|
+
// AWS → Google Workload Identity Federation auth primitives. All three federate the running AWS identity
|
|
5
|
+
// into a Google Workload Identity Pool and impersonate the configured service account; they differ only in
|
|
6
|
+
// the token they mint. The framework owns all `google-auth-library` usage — consumers pass their own base64
|
|
7
7
|
// WIF cred config (holds no credential — points at the pool / provider / SA, read from the consumer's own
|
|
8
8
|
// env proxy) and never import `google-auth-library` themselves. `google-auth-library` is dynamically
|
|
9
9
|
// imported so a service that never calls Google does not load it. AWS credentials resolve through the AWS
|
|
@@ -66,29 +66,14 @@ export const googleIdTokenAuth = (wifConfigBase64, audience, forHost) => {
|
|
|
66
66
|
let cached;
|
|
67
67
|
let inflight;
|
|
68
68
|
const fetchIdToken = async () => {
|
|
69
|
-
const {
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
}
|
|
75
|
-
// AwsClient is the federation-only source (impersonation + built-in IMDS source stripped); Impersonated
|
|
76
|
-
// performs the SA impersonation via generateIdToken, for which the federated principal already holds
|
|
77
|
-
// roles/iam.serviceAccountTokenCreator on the SA.
|
|
69
|
+
const { impersonated } = await impersonatedClient({
|
|
70
|
+
wifConfigBase64,
|
|
71
|
+
label: 'googleIdTokenAuth',
|
|
72
|
+
lifetime: ID_TOKEN_TTL_SEC,
|
|
73
|
+
targetScopes: ['https://www.googleapis.com/auth/cloud-platform'],
|
|
74
|
+
});
|
|
78
75
|
return {
|
|
79
|
-
token: await
|
|
80
|
-
sourceClient: new AwsClient({
|
|
81
|
-
...config,
|
|
82
|
-
service_account_impersonation_url: undefined,
|
|
83
|
-
credential_source: undefined,
|
|
84
|
-
aws_security_credentials_supplier: awsSecurityCredentialsSupplier,
|
|
85
|
-
}),
|
|
86
|
-
targetPrincipal: serviceAccountEmail,
|
|
87
|
-
lifetime: ID_TOKEN_TTL_SEC,
|
|
88
|
-
targetScopes: ['https://www.googleapis.com/auth/cloud-platform'],
|
|
89
|
-
})
|
|
90
|
-
.fetchIdToken(audience, { includeEmail: true })
|
|
91
|
-
.catch((e) => {
|
|
76
|
+
token: await impersonated.fetchIdToken(audience, { includeEmail: true }).catch((e) => {
|
|
92
77
|
logger.error('google-auth', { op: 'id-token', error: e });
|
|
93
78
|
throw e;
|
|
94
79
|
}),
|
|
@@ -117,4 +102,27 @@ export const googleIdTokenAuth = (wifConfigBase64, audience, forHost) => {
|
|
|
117
102
|
withAuth: async (fn) => runWithRequestHeaders({ authorization: await bearer() }, fn, forHost === undefined ? undefined : { forHost }),
|
|
118
103
|
};
|
|
119
104
|
};
|
|
105
|
+
// Impersonated access-token auth for arbitrary target scopes — what googleCloudAuth's fixed cloud-platform
|
|
106
|
+
// scope does not cover (Cloud Identity / Directory admin / IAM provisioning, e.g. corporate-service's own
|
|
107
|
+
// server-side Google operations). Mints per call (no cache — callers cache the downstream result where it
|
|
108
|
+
// matters) and returns the impersonated SA's email alongside the token for follow-up IAM Credentials calls
|
|
109
|
+
// (e.g. a domain-wide-delegation signJwt). `label` prefixes error messages with the calling module's name.
|
|
110
|
+
export const googleImpersonatedAuth = (wifConfigBase64, { label, lifetime, targetScopes }) => ({
|
|
111
|
+
accessToken: async () => {
|
|
112
|
+
const { impersonated, serviceAccountEmail } = await impersonatedClient({
|
|
113
|
+
wifConfigBase64,
|
|
114
|
+
label,
|
|
115
|
+
lifetime,
|
|
116
|
+
targetScopes,
|
|
117
|
+
});
|
|
118
|
+
const { token } = await impersonated.getAccessToken().catch((e) => {
|
|
119
|
+
logger.error('google-auth', { op: 'access-token', label, error: e });
|
|
120
|
+
throw e;
|
|
121
|
+
});
|
|
122
|
+
if (token === undefined || token === null) {
|
|
123
|
+
throw new Error(`${label}: Impersonated returned no access token`);
|
|
124
|
+
}
|
|
125
|
+
return { token, serviceAccountEmail };
|
|
126
|
+
},
|
|
127
|
+
});
|
|
120
128
|
//# sourceMappingURL=index.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/connector/google-auth/index.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,qBAAqB,EAAE,MAAM,gCAAgC,CAAA;AACtE,OAAO,EAAE,8BAA8B,EAAE,cAAc,EAAE,MAAM,oCAAoC,CAAA;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/connector/google-auth/index.ts"],"names":[],"mappings":"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"}
|
package/dist/env.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
export declare const defaultEnv: {
|
|
2
|
+
AWS_REGION: string;
|
|
2
3
|
NODE_ENV: "development" | "production";
|
|
3
4
|
DEPLOY_ENV: "dev" | "prd" | "stg";
|
|
4
5
|
LOG_LEVEL?: "debug" | "error" | "info" | "warn" | undefined;
|
|
@@ -12,10 +13,10 @@ export declare const defaultEnv: {
|
|
|
12
13
|
REDIS_CLUSTER: boolean;
|
|
13
14
|
REDIS_HOST: string;
|
|
14
15
|
REDIS_PORT: number;
|
|
16
|
+
LOCAL_S3_ENDPOINT?: string | undefined;
|
|
17
|
+
STORAGE_BUCKET: string;
|
|
15
18
|
SERVICE: string;
|
|
16
19
|
PORT: number;
|
|
17
20
|
CORS_ORIGIN: string;
|
|
18
21
|
BASE_URL: string;
|
|
19
|
-
LOCAL_S3_ENDPOINT?: string | undefined;
|
|
20
|
-
AWS_REGION?: string | undefined;
|
|
21
22
|
};
|
package/dist/env.js
CHANGED
|
@@ -1,37 +1,38 @@
|
|
|
1
1
|
import { z } from 'zod';
|
|
2
2
|
import { Util } from './util/index.js';
|
|
3
3
|
export const defaultEnv = Util.createEnvProxy(z.object({
|
|
4
|
-
//
|
|
4
|
+
// ---- AWS
|
|
5
|
+
AWS_REGION: z.string().min(1),
|
|
6
|
+
// ---- Common
|
|
5
7
|
NODE_ENV: z.enum(['development', 'production']),
|
|
6
8
|
DEPLOY_ENV: z.enum(['dev', 'stg', 'prd']),
|
|
7
|
-
// When unset, the threshold defaults to debug on local dev and info on stg/prd (see logger).
|
|
8
|
-
|
|
9
|
-
// general
|
|
9
|
+
LOG_LEVEL: z.enum(['debug', 'info', 'warn', 'error']).optional(), // When unset, the threshold defaults to debug on local dev and info on stg/prd (see logger).
|
|
10
|
+
// ---- Infra
|
|
10
11
|
DATABASE_HOST: z.string().min(1),
|
|
11
12
|
DATABASE_PORT: z.string().min(1).transform(Number),
|
|
12
13
|
DATABASE_RO_HOST: z.string().min(1),
|
|
13
14
|
DATABASE_RO_PORT: z.string().min(1).transform(Number),
|
|
14
15
|
DATABASE_USER: z.string().min(1),
|
|
15
16
|
DATABASE_PASSWORD: z.string().min(1),
|
|
16
|
-
DATABASE_NAME: z.string().min(1).optional(),
|
|
17
|
+
DATABASE_NAME: z.string().min(1).optional(), // When unset, the database name is derived from the SERVICE env var (see repository/prisma/index.ts).
|
|
17
18
|
REDIS_CLUSTER: z.string().transform((val) => val === 'true'),
|
|
18
19
|
REDIS_HOST: z.string().min(1),
|
|
19
20
|
REDIS_PORT: z.string().min(1).transform(Number),
|
|
20
|
-
//
|
|
21
|
+
LOCAL_S3_ENDPOINT: z.string().min(1).optional(), // s3 (object storage) — LOCAL_S3_ENDPOINT points the client at MinIO on dev; both fall back to the AWS resolution chain.
|
|
22
|
+
STORAGE_BUCKET: z.string().min(1),
|
|
23
|
+
// ---- Package
|
|
21
24
|
SERVICE: z.string().min(1),
|
|
22
25
|
PORT: z.string().min(1).transform(Number),
|
|
23
26
|
CORS_ORIGIN: z.string().min(1),
|
|
24
27
|
BASE_URL: z.string().min(1),
|
|
25
|
-
// s3 (object storage) — LOCAL_S3_ENDPOINT points the client at MinIO on dev; both fall back to the AWS resolution chain.
|
|
26
|
-
// `.min(1)` so a set-but-empty value in stg/prd does not read as "set" and fall into the MinIO dev branch (absent stays undefined).
|
|
27
|
-
LOCAL_S3_ENDPOINT: z.string().min(1).optional(),
|
|
28
|
-
AWS_REGION: z.string().min(1).optional(),
|
|
29
28
|
}), () => ({
|
|
30
|
-
//
|
|
29
|
+
// ---- AWS
|
|
30
|
+
AWS_REGION: process.env.AWS_REGION,
|
|
31
|
+
// ---- Common
|
|
31
32
|
NODE_ENV: process.env.NODE_ENV,
|
|
32
33
|
DEPLOY_ENV: process.env.DEPLOY_ENV,
|
|
33
34
|
LOG_LEVEL: process.env.LOG_LEVEL,
|
|
34
|
-
//
|
|
35
|
+
// ---- Infra
|
|
35
36
|
DATABASE_HOST: process.env.DATABASE_HOST,
|
|
36
37
|
DATABASE_PORT: process.env.DATABASE_PORT,
|
|
37
38
|
DATABASE_RO_HOST: process.env.DATABASE_RO_HOST,
|
|
@@ -42,13 +43,12 @@ export const defaultEnv = Util.createEnvProxy(z.object({
|
|
|
42
43
|
REDIS_CLUSTER: process.env.REDIS_CLUSTER,
|
|
43
44
|
REDIS_HOST: process.env.REDIS_HOST,
|
|
44
45
|
REDIS_PORT: process.env.REDIS_PORT,
|
|
45
|
-
|
|
46
|
+
LOCAL_S3_ENDPOINT: process.env.LOCAL_S3_ENDPOINT,
|
|
47
|
+
STORAGE_BUCKET: process.env.STORAGE_BUCKET,
|
|
48
|
+
// ---- Package
|
|
46
49
|
SERVICE: process.env.SERVICE,
|
|
47
50
|
PORT: process.env.PORT,
|
|
48
51
|
CORS_ORIGIN: process.env.CORS_ORIGIN,
|
|
49
52
|
BASE_URL: process.env.BASE_URL,
|
|
50
|
-
// s3 (object storage)
|
|
51
|
-
LOCAL_S3_ENDPOINT: process.env.LOCAL_S3_ENDPOINT,
|
|
52
|
-
AWS_REGION: process.env.AWS_REGION,
|
|
53
53
|
}));
|
|
54
54
|
//# sourceMappingURL=env.js.map
|
package/dist/env.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"env.js","sourceRoot":"","sources":["../src/env.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AAEvB,OAAO,EAAE,IAAI,EAAE,MAAM,iBAAiB,CAAA;AAEtC,MAAM,CAAC,MAAM,UAAU,GAAG,IAAI,CAAC,cAAc,CAC3C,CAAC,CAAC,MAAM,CAAC;IACP,
|
|
1
|
+
{"version":3,"file":"env.js","sourceRoot":"","sources":["../src/env.ts"],"names":[],"mappings":"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"}
|
|
@@ -10,3 +10,12 @@ export declare const awsSecurityCredentialsSupplier: {
|
|
|
10
10
|
export declare const parseWifConfig: (base64: string, label: string) => AwsClientOptions & {
|
|
11
11
|
service_account_impersonation_url: string;
|
|
12
12
|
};
|
|
13
|
+
export declare const impersonatedClient: ({ wifConfigBase64, label, lifetime, targetScopes, }: {
|
|
14
|
+
wifConfigBase64: string;
|
|
15
|
+
label: string;
|
|
16
|
+
lifetime: number;
|
|
17
|
+
targetScopes: string[];
|
|
18
|
+
}) => Promise<{
|
|
19
|
+
impersonated: import("google-auth-library").Impersonated;
|
|
20
|
+
serviceAccountEmail: string;
|
|
21
|
+
}>;
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import { defaultEnv } from '../../env.js';
|
|
2
|
-
// Shared AWS → Google Workload Identity Federation plumbing.
|
|
3
|
-
// identity into a Google Workload Identity Pool and impersonate a service account:
|
|
4
|
-
//
|
|
5
|
-
// access token. What they share lives here — the
|
|
2
|
+
// Shared AWS → Google Workload Identity Federation plumbing. All consumers federate the running AWS
|
|
3
|
+
// identity into a Google Workload Identity Pool and impersonate a service account: googleIdTokenAuth
|
|
4
|
+
// mints an audience-bound OIDC id_token, googleCloudAuth a cloud-platform access token, and
|
|
5
|
+
// googleImpersonatedAuth an access token for arbitrary target scopes. What they share lives here — the
|
|
6
|
+
// AWS credential supplier, the cred-config parse, and the Impersonated-client builder.
|
|
6
7
|
//
|
|
7
8
|
// The AWS identity is resolved through the AWS SDK credential chain (env / ECS container credential
|
|
8
9
|
// endpoint / EC2 IMDS, rotation-aware) rather than google-auth-library's built-in AWS source, which
|
|
@@ -13,12 +14,7 @@ let awsCredentialProvider;
|
|
|
13
14
|
// An AwsSecurityCredentialsSupplier backed by the AWS SDK defaultProvider (the credential provider is
|
|
14
15
|
// dynamically imported and memoized so a service that never federates does not load it).
|
|
15
16
|
export const awsSecurityCredentialsSupplier = {
|
|
16
|
-
getAwsRegion: async () =>
|
|
17
|
-
if (defaultEnv.AWS_REGION === undefined) {
|
|
18
|
-
throw new Error('aws-google-federation: AWS_REGION is not set');
|
|
19
|
-
}
|
|
20
|
-
return defaultEnv.AWS_REGION;
|
|
21
|
-
},
|
|
17
|
+
getAwsRegion: async () => defaultEnv.AWS_REGION,
|
|
22
18
|
getAwsSecurityCredentials: async () => {
|
|
23
19
|
const { defaultProvider } = await import('@aws-sdk/credential-provider-node');
|
|
24
20
|
const c = await (awsCredentialProvider ??= defaultProvider())();
|
|
@@ -36,4 +32,32 @@ export const parseWifConfig = (base64, label) => {
|
|
|
36
32
|
}
|
|
37
33
|
return { ...config, service_account_impersonation_url };
|
|
38
34
|
};
|
|
35
|
+
// Build the Impersonated client the token mints run through: parse the WIF config, derive the target SA
|
|
36
|
+
// email from its impersonation URL, and wrap the federation-only AwsClient (impersonation URL + built-in
|
|
37
|
+
// IMDS source stripped in favour of the supplier — AwsClient rejects a credential source and a supplier at
|
|
38
|
+
// once) in an Impersonated for the requested lifetime / target scopes. Impersonation itself runs via
|
|
39
|
+
// generateAccessToken / generateIdToken, for which the federated principal holds
|
|
40
|
+
// roles/iam.serviceAccountTokenCreator on the SA.
|
|
41
|
+
export const impersonatedClient = async ({ wifConfigBase64, label, lifetime, targetScopes, }) => {
|
|
42
|
+
const { AwsClient, Impersonated } = await import('google-auth-library');
|
|
43
|
+
const config = parseWifConfig(wifConfigBase64, label);
|
|
44
|
+
const serviceAccountEmail = config.service_account_impersonation_url.match(/serviceAccounts\/([^/:]+):/)?.[1];
|
|
45
|
+
if (serviceAccountEmail === undefined) {
|
|
46
|
+
throw new Error(`${label}: cannot derive service account email from WIF config`);
|
|
47
|
+
}
|
|
48
|
+
return {
|
|
49
|
+
impersonated: new Impersonated({
|
|
50
|
+
sourceClient: new AwsClient({
|
|
51
|
+
...config,
|
|
52
|
+
service_account_impersonation_url: undefined,
|
|
53
|
+
credential_source: undefined,
|
|
54
|
+
aws_security_credentials_supplier: awsSecurityCredentialsSupplier,
|
|
55
|
+
}),
|
|
56
|
+
targetPrincipal: serviceAccountEmail,
|
|
57
|
+
lifetime,
|
|
58
|
+
targetScopes,
|
|
59
|
+
}),
|
|
60
|
+
serviceAccountEmail,
|
|
61
|
+
};
|
|
62
|
+
};
|
|
39
63
|
//# sourceMappingURL=index.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/internal/federation/index.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAA;AAEzC,qGAAqG;AACrG,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/internal/federation/index.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAA;AAEzC,oGAAoG;AACpG,qGAAqG;AACrG,4FAA4F;AAC5F,uGAAuG;AACvG,uFAAuF;AACvF,EAAE;AACF,oGAAoG;AACpG,oGAAoG;AACpG,iGAAiG;AACjG,qFAAqF;AACrF,8EAA8E;AAE9E,IAAI,qBAES,CAAA;AAEb,sGAAsG;AACtG,yFAAyF;AACzF,MAAM,CAAC,MAAM,8BAA8B,GAAG;IAC5C,YAAY,EAAE,KAAK,IAAI,EAAE,CAAC,UAAU,CAAC,UAAU;IAC/C,yBAAyB,EAAE,KAAK,IAAI,EAAE;QACpC,MAAM,EAAE,eAAe,EAAE,GAAG,MAAM,MAAM,CAAC,mCAAmC,CAAC,CAAA;QAC7E,MAAM,CAAC,GAAG,MAAM,CAAC,qBAAqB,KAAK,eAAe,EAAE,CAAC,EAAE,CAAA;QAC/D,OAAO,EAAE,WAAW,EAAE,CAAC,CAAC,WAAW,EAAE,eAAe,EAAE,CAAC,CAAC,eAAe,EAAE,KAAK,EAAE,CAAC,CAAC,YAAY,EAAE,CAAA;IAClG,CAAC;CACF,CAAA;AAED,mGAAmG;AACnG,mGAAmG;AACnG,yDAAyD;AACzD,MAAM,CAAC,MAAM,cAAc,GAAG,CAC5B,MAAc,EACd,KAAa,EACqD,EAAE;IACpE,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAqB,CAAA;IAC7F,MAAM,EAAE,iCAAiC,EAAE,GAAG,MAAM,CAAA;IACpD,IAAI,iCAAiC,KAAK,SAAS,EAAE,CAAC;QACpD,MAAM,IAAI,KAAK,CAAC,GAAG,KAAK,wDAAwD,CAAC,CAAA;IACnF,CAAC;IACD,OAAO,EAAE,GAAG,MAAM,EAAE,iCAAiC,EAAE,CAAA;AACzD,CAAC,CAAA;AAED,wGAAwG;AACxG,yGAAyG;AACzG,2GAA2G;AAC3G,qGAAqG;AACrG,iFAAiF;AACjF,kDAAkD;AAClD,MAAM,CAAC,MAAM,kBAAkB,GAAG,KAAK,EAAE,EACvC,eAAe,EACf,KAAK,EACL,QAAQ,EACR,YAAY,GAMb,EAAE,EAAE;IACH,MAAM,EAAE,SAAS,EAAE,YAAY,EAAE,GAAG,MAAM,MAAM,CAAC,qBAAqB,CAAC,CAAA;IACvE,MAAM,MAAM,GAAG,cAAc,CAAC,eAAe,EAAE,KAAK,CAAC,CAAA;IACrD,MAAM,mBAAmB,GAAG,MAAM,CAAC,iCAAiC,CAAC,KAAK,CAAC,4BAA4B,CAAC,EAAE,CAAC,CAAC,CAAC,CAAA;IAC7G,IAAI,mBAAmB,KAAK,SAAS,EAAE,CAAC;QACtC,MAAM,IAAI,KAAK,CAAC,GAAG,KAAK,uDAAuD,CAAC,CAAA;IAClF,CAAC;IACD,OAAO;QACL,YAAY,EAAE,IAAI,YAAY,CAAC;YAC7B,YAAY,EAAE,IAAI,SAAS,CAAC;gBAC1B,GAAG,MAAM;gBACT,iCAAiC,EAAE,SAAS;gBAC5C,iBAAiB,EAAE,SAAS;gBAC5B,iCAAiC,EAAE,8BAA8B;aAClE,CAAC;YACF,eAAe,EAAE,mBAAmB;YACpC,QAAQ;YACR,YAAY;SACb,CAAC;QACF,mBAAmB;KACpB,CAAA;AACH,CAAC,CAAA"}
|