@dynamic-labs-wallet/core 1.0.88 → 1.0.90
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/index.cjs +41 -12
- package/index.esm.js +40 -13
- package/package.json +3 -3
- package/src/services/axiosErrorResponse.d.ts +12 -0
- package/src/services/axiosErrorResponse.d.ts.map +1 -1
package/index.cjs
CHANGED
|
@@ -951,7 +951,7 @@ const getRequiredExternalKeyShareId = (ks)=>{
|
|
|
951
951
|
* before it is posted and surfaces in Datadog exactly as the recovery path does.
|
|
952
952
|
*/ const assertDynamicLocationsHaveExternalKeyShareId = (locations)=>locations.filter((location)=>location.location === BackupLocation.DYNAMIC).forEach((location)=>getRequiredExternalKeyShareId(location));
|
|
953
953
|
|
|
954
|
-
var version = "1.0.
|
|
954
|
+
var version = "1.0.90";
|
|
955
955
|
|
|
956
956
|
class BaseClient {
|
|
957
957
|
/**
|
|
@@ -2391,6 +2391,18 @@ const extractServerErrorCode = (error)=>{
|
|
|
2391
2391
|
return candidates.find((value)=>typeof value === 'string');
|
|
2392
2392
|
};
|
|
2393
2393
|
const INTERNAL_SERVER_ERROR_MESSAGE = 'Internal server error';
|
|
2394
|
+
/**
|
|
2395
|
+
* `status` for a request that never received an HTTP response at all — the
|
|
2396
|
+
* client lost connectivity, the request was aborted, DNS/TLS failed, or CORS
|
|
2397
|
+
* blocked it. 0 matches the XHR/`fetch` convention for "no response".
|
|
2398
|
+
*
|
|
2399
|
+
* This used to be reported as `500 Internal server error`, which made a
|
|
2400
|
+
* client-side network failure indistinguishable from a backend fault: the
|
|
2401
|
+
* "Backend 500s" monitor counted 1,395 events on a day when the API returned
|
|
2402
|
+
* only 33 real 5xx responses.
|
|
2403
|
+
*/ const NETWORK_ERROR_STATUS = 0;
|
|
2404
|
+
const NETWORK_ERROR_CODE = 'NETWORK_ERROR';
|
|
2405
|
+
const NETWORK_ERROR_MESSAGE = 'Network error - no response received';
|
|
2394
2406
|
const STATUS_MESSAGES = {
|
|
2395
2407
|
400: 'Invalid request',
|
|
2396
2408
|
403: 'Forbidden',
|
|
@@ -2439,13 +2451,20 @@ const resolveStatusMessage = (status, error)=>{
|
|
|
2439
2451
|
return undefined;
|
|
2440
2452
|
};
|
|
2441
2453
|
const handleAxiosError = (error, message, context, _logger)=>{
|
|
2442
|
-
var _error_config, _error_config1, _error_response, _error_response1, _error_response2
|
|
2454
|
+
var _error_config, _error_config1, _error_response, _error_response1, _error_response2;
|
|
2443
2455
|
const requestUrl = (_error_config = error.config) == null ? void 0 : _error_config.url;
|
|
2444
2456
|
const requestBaseUrl = (_error_config1 = error.config) == null ? void 0 : _error_config1.baseURL;
|
|
2457
|
+
// The HTTP status MUST NOT be logged as a top-level `status` field: Datadog
|
|
2458
|
+
// reserves `status` for the log level and its remapper turns a numeric value
|
|
2459
|
+
// into `info`, silently burying every 4xx/5xx we emit here. `http.status_code`
|
|
2460
|
+
// is Datadog's standard attribute, so the level survives and these logs join
|
|
2461
|
+
// against edge/CDN logs on the same field.
|
|
2445
2462
|
const logPayload = _extends({
|
|
2446
2463
|
message,
|
|
2447
2464
|
error: (_error_response = error.response) == null ? void 0 : _error_response.data,
|
|
2448
|
-
|
|
2465
|
+
http: {
|
|
2466
|
+
status_code: (_error_response1 = error.response) == null ? void 0 : _error_response1.status
|
|
2467
|
+
}
|
|
2449
2468
|
}, requestBaseUrl && {
|
|
2450
2469
|
requestBaseUrl
|
|
2451
2470
|
}, requestUrl && {
|
|
@@ -2453,17 +2472,25 @@ const handleAxiosError = (error, message, context, _logger)=>{
|
|
|
2453
2472
|
}, {
|
|
2454
2473
|
context
|
|
2455
2474
|
});
|
|
2475
|
+
const status = (_error_response2 = error.response) == null ? void 0 : _error_response2.status;
|
|
2456
2476
|
// A 429 (Too Many Requests) is a transient rate-limit signal, not a code or
|
|
2457
|
-
// logic failure
|
|
2458
|
-
//
|
|
2459
|
-
//
|
|
2460
|
-
|
|
2477
|
+
// logic failure — and a request that never got a response is a client-side
|
|
2478
|
+
// connectivity problem, not a server fault. Both are logged at `warn` so they
|
|
2479
|
+
// don't pollute error dashboards or trigger PagerDuty. The 429 case covers
|
|
2480
|
+
// both Cloudflare WAF blocks and application-level rate limiting.
|
|
2481
|
+
const logLevel = status === 429 || status === undefined ? 'warn' : 'error';
|
|
2461
2482
|
Logger[logLevel]('[DynamicWaasWalletClient] Axios error: ', logPayload);
|
|
2462
|
-
|
|
2463
|
-
|
|
2464
|
-
|
|
2465
|
-
|
|
2466
|
-
|
|
2483
|
+
// No response at all: report it as such rather than laundering it into a 500.
|
|
2484
|
+
if (status === undefined) {
|
|
2485
|
+
throw new WalletApiError(NETWORK_ERROR_STATUS, NETWORK_ERROR_MESSAGE, NETWORK_ERROR_CODE);
|
|
2486
|
+
}
|
|
2487
|
+
var _resolveStatusMessage;
|
|
2488
|
+
// Preserve the real status. Collapsing every unmapped code to 500 made a 404
|
|
2489
|
+
// (backup not found) and a 504 (gateway timeout) both surface as
|
|
2490
|
+
// "Internal server error", so neither the caller nor a monitor could tell a
|
|
2491
|
+
// missing resource from an outage.
|
|
2492
|
+
const resolvedMessage = (_resolveStatusMessage = resolveStatusMessage(status, error)) != null ? _resolveStatusMessage : `Request failed with status ${status}`;
|
|
2493
|
+
throw new WalletApiError(status, resolvedMessage, extractServerErrorCode(error));
|
|
2467
2494
|
};
|
|
2468
2495
|
|
|
2469
2496
|
Object.defineProperty(exports, "SigningAlgorithm", {
|
|
@@ -2547,6 +2574,8 @@ exports.MPC_RELAY_DEV_API_URL = MPC_RELAY_DEV_API_URL;
|
|
|
2547
2574
|
exports.MPC_RELAY_PREPROD_API_URL = MPC_RELAY_PREPROD_API_URL;
|
|
2548
2575
|
exports.MPC_RELAY_PROD_API_URL = MPC_RELAY_PROD_API_URL;
|
|
2549
2576
|
exports.MPC_RELAY_URL_MAP = MPC_RELAY_URL_MAP;
|
|
2577
|
+
exports.NETWORK_ERROR_CODE = NETWORK_ERROR_CODE;
|
|
2578
|
+
exports.NETWORK_ERROR_STATUS = NETWORK_ERROR_STATUS;
|
|
2550
2579
|
exports.NoopLogger = NoopLogger;
|
|
2551
2580
|
exports.PREPROD_RELAY_API_KEY = PREPROD_RELAY_API_KEY;
|
|
2552
2581
|
exports.PREPROD_RELAY_APP_ID = PREPROD_RELAY_APP_ID;
|
package/index.esm.js
CHANGED
|
@@ -951,7 +951,7 @@ const getRequiredExternalKeyShareId = (ks)=>{
|
|
|
951
951
|
* before it is posted and surfaces in Datadog exactly as the recovery path does.
|
|
952
952
|
*/ const assertDynamicLocationsHaveExternalKeyShareId = (locations)=>locations.filter((location)=>location.location === BackupLocation.DYNAMIC).forEach((location)=>getRequiredExternalKeyShareId(location));
|
|
953
953
|
|
|
954
|
-
var version = "1.0.
|
|
954
|
+
var version = "1.0.90";
|
|
955
955
|
|
|
956
956
|
class BaseClient {
|
|
957
957
|
/**
|
|
@@ -2391,6 +2391,18 @@ const extractServerErrorCode = (error)=>{
|
|
|
2391
2391
|
return candidates.find((value)=>typeof value === 'string');
|
|
2392
2392
|
};
|
|
2393
2393
|
const INTERNAL_SERVER_ERROR_MESSAGE = 'Internal server error';
|
|
2394
|
+
/**
|
|
2395
|
+
* `status` for a request that never received an HTTP response at all — the
|
|
2396
|
+
* client lost connectivity, the request was aborted, DNS/TLS failed, or CORS
|
|
2397
|
+
* blocked it. 0 matches the XHR/`fetch` convention for "no response".
|
|
2398
|
+
*
|
|
2399
|
+
* This used to be reported as `500 Internal server error`, which made a
|
|
2400
|
+
* client-side network failure indistinguishable from a backend fault: the
|
|
2401
|
+
* "Backend 500s" monitor counted 1,395 events on a day when the API returned
|
|
2402
|
+
* only 33 real 5xx responses.
|
|
2403
|
+
*/ const NETWORK_ERROR_STATUS = 0;
|
|
2404
|
+
const NETWORK_ERROR_CODE = 'NETWORK_ERROR';
|
|
2405
|
+
const NETWORK_ERROR_MESSAGE = 'Network error - no response received';
|
|
2394
2406
|
const STATUS_MESSAGES = {
|
|
2395
2407
|
400: 'Invalid request',
|
|
2396
2408
|
403: 'Forbidden',
|
|
@@ -2439,13 +2451,20 @@ const resolveStatusMessage = (status, error)=>{
|
|
|
2439
2451
|
return undefined;
|
|
2440
2452
|
};
|
|
2441
2453
|
const handleAxiosError = (error, message, context, _logger)=>{
|
|
2442
|
-
var _error_config, _error_config1, _error_response, _error_response1, _error_response2
|
|
2454
|
+
var _error_config, _error_config1, _error_response, _error_response1, _error_response2;
|
|
2443
2455
|
const requestUrl = (_error_config = error.config) == null ? void 0 : _error_config.url;
|
|
2444
2456
|
const requestBaseUrl = (_error_config1 = error.config) == null ? void 0 : _error_config1.baseURL;
|
|
2457
|
+
// The HTTP status MUST NOT be logged as a top-level `status` field: Datadog
|
|
2458
|
+
// reserves `status` for the log level and its remapper turns a numeric value
|
|
2459
|
+
// into `info`, silently burying every 4xx/5xx we emit here. `http.status_code`
|
|
2460
|
+
// is Datadog's standard attribute, so the level survives and these logs join
|
|
2461
|
+
// against edge/CDN logs on the same field.
|
|
2445
2462
|
const logPayload = _extends({
|
|
2446
2463
|
message,
|
|
2447
2464
|
error: (_error_response = error.response) == null ? void 0 : _error_response.data,
|
|
2448
|
-
|
|
2465
|
+
http: {
|
|
2466
|
+
status_code: (_error_response1 = error.response) == null ? void 0 : _error_response1.status
|
|
2467
|
+
}
|
|
2449
2468
|
}, requestBaseUrl && {
|
|
2450
2469
|
requestBaseUrl
|
|
2451
2470
|
}, requestUrl && {
|
|
@@ -2453,17 +2472,25 @@ const handleAxiosError = (error, message, context, _logger)=>{
|
|
|
2453
2472
|
}, {
|
|
2454
2473
|
context
|
|
2455
2474
|
});
|
|
2475
|
+
const status = (_error_response2 = error.response) == null ? void 0 : _error_response2.status;
|
|
2456
2476
|
// A 429 (Too Many Requests) is a transient rate-limit signal, not a code or
|
|
2457
|
-
// logic failure
|
|
2458
|
-
//
|
|
2459
|
-
//
|
|
2460
|
-
|
|
2477
|
+
// logic failure — and a request that never got a response is a client-side
|
|
2478
|
+
// connectivity problem, not a server fault. Both are logged at `warn` so they
|
|
2479
|
+
// don't pollute error dashboards or trigger PagerDuty. The 429 case covers
|
|
2480
|
+
// both Cloudflare WAF blocks and application-level rate limiting.
|
|
2481
|
+
const logLevel = status === 429 || status === undefined ? 'warn' : 'error';
|
|
2461
2482
|
Logger[logLevel]('[DynamicWaasWalletClient] Axios error: ', logPayload);
|
|
2462
|
-
|
|
2463
|
-
|
|
2464
|
-
|
|
2465
|
-
|
|
2466
|
-
|
|
2483
|
+
// No response at all: report it as such rather than laundering it into a 500.
|
|
2484
|
+
if (status === undefined) {
|
|
2485
|
+
throw new WalletApiError(NETWORK_ERROR_STATUS, NETWORK_ERROR_MESSAGE, NETWORK_ERROR_CODE);
|
|
2486
|
+
}
|
|
2487
|
+
var _resolveStatusMessage;
|
|
2488
|
+
// Preserve the real status. Collapsing every unmapped code to 500 made a 404
|
|
2489
|
+
// (backup not found) and a 504 (gateway timeout) both surface as
|
|
2490
|
+
// "Internal server error", so neither the caller nor a monitor could tell a
|
|
2491
|
+
// missing resource from an outage.
|
|
2492
|
+
const resolvedMessage = (_resolveStatusMessage = resolveStatusMessage(status, error)) != null ? _resolveStatusMessage : `Request failed with status ${status}`;
|
|
2493
|
+
throw new WalletApiError(status, resolvedMessage, extractServerErrorCode(error));
|
|
2467
2494
|
};
|
|
2468
2495
|
|
|
2469
|
-
export { AuthMode, BITCOIN_ADDRESS_TYPE_CONFIG, BITCOIN_DERIVATION_PATHS, BROWSER_SDK_ROUTE_PREFIX, BackupLocation, BitcoinAddressType, BitcoinNetwork, BusinessAccountClient, BusinessAccountMemberRole, BusinessAccountSignerType, CreateRoomPartiesOptions, DELEGATED_SHARE_COUNT, DYNAMIC_AUTH_BASE_API_URL_MAP, DYNAMIC_AUTH_DEV_BASE_API_URL, DYNAMIC_AUTH_PREPROD_BASE_API_URL, DYNAMIC_AUTH_PROD_BASE_API_URL, DYNAMIC_CLIENT_RELAY_REDCOAST_API_KEY_MAP, DYNAMIC_CLIENT_RELAY_REDCOAST_APP_ID_MAP, DYNAMIC_FORWARD_MPC_DEV_ENCLAVE_URL, DYNAMIC_FORWARD_MPC_ENCLAVE_ATTESTATION_CONFIG_MAP, DYNAMIC_FORWARD_MPC_ENCLAVE_URL_MAP, DYNAMIC_FORWARD_MPC_PREPROD_ENCLAVE_URL, DYNAMIC_FORWARD_MPC_PROD_ENCLAVE_URL, DYNAMIC_KEYSHARES_RELAY_MAP, DYNAMIC_KEYSHARES_RELAY_PREPROD_BASE_API_URL, DYNAMIC_KEYSHARES_RELAY_PROD_BASE_API_URL, DynamicApiClient, DynamicClientSessionSignature, DynamicElevatedAccessTokenHeader, DynamicForwardMPCHeader, DynamicMfaTokenHeader, DynamicRequestIdHeader, DynamicServerApiClient, DynamicSessionPublicKeyHeader, DynamicTraceElapsedTimeHeader, DynamicTraceIdHeader, ENCRYPTED_SHARES_STORAGE_SUFFIX, ENVIRONMENT_ENUM, EVM_COMPATIBLE_CHAINS, FEATURE_FLAGS, IFRAME_DOMAIN_MAP, Logger, MIDNIGHT_DERIVATION_PATHS, MPC_CHAIN_CONFIG, MPC_CONFIG, MPC_RELAY_DEV_API_URL, MPC_RELAY_PREPROD_API_URL, MPC_RELAY_PROD_API_URL, MPC_RELAY_URL_MAP, NoopLogger, PREPROD_RELAY_API_KEY, PREPROD_RELAY_APP_ID, PROD_RELAY_API_KEY, PROD_RELAY_APP_ID, RELAY_API_KEY_HEADER, RELAY_APP_ID_HEADER, SDK_NAMESPACE, SERVER_SDK_ROUTE_PREFIX, SOLANA_RPC_URL, SuccessEventType, ThresholdSignatureScheme, URL_PATTERNS, WalletApiError, WalletOperation, WalletReadyState, assertDynamicLocationsHaveExternalKeyShareId, chain, chainEnumToVerifiedCredentialName, formatNamespacedVersion, getBitcoinChainConfig, getClientThreshold, getDynamicServerThreshold, getEnvironmentFromUrl, getMPCChainConfig, getRequiredExternalKeyShareId, getReshareConfig, getServerWalletReshareConfig, getTSSConfig, getVersionNamespace, getVersionWithoutNamespace, handleAxiosError, isEvmCompatibleChain, isRecoveredForwardMpcConnectionChurn, parseNamespacedVersion, serializeError, serializeMessageForForwardMPC, verifiedCredentialNameToChainEnum };
|
|
2496
|
+
export { AuthMode, BITCOIN_ADDRESS_TYPE_CONFIG, BITCOIN_DERIVATION_PATHS, BROWSER_SDK_ROUTE_PREFIX, BackupLocation, BitcoinAddressType, BitcoinNetwork, BusinessAccountClient, BusinessAccountMemberRole, BusinessAccountSignerType, CreateRoomPartiesOptions, DELEGATED_SHARE_COUNT, DYNAMIC_AUTH_BASE_API_URL_MAP, DYNAMIC_AUTH_DEV_BASE_API_URL, DYNAMIC_AUTH_PREPROD_BASE_API_URL, DYNAMIC_AUTH_PROD_BASE_API_URL, DYNAMIC_CLIENT_RELAY_REDCOAST_API_KEY_MAP, DYNAMIC_CLIENT_RELAY_REDCOAST_APP_ID_MAP, DYNAMIC_FORWARD_MPC_DEV_ENCLAVE_URL, DYNAMIC_FORWARD_MPC_ENCLAVE_ATTESTATION_CONFIG_MAP, DYNAMIC_FORWARD_MPC_ENCLAVE_URL_MAP, DYNAMIC_FORWARD_MPC_PREPROD_ENCLAVE_URL, DYNAMIC_FORWARD_MPC_PROD_ENCLAVE_URL, DYNAMIC_KEYSHARES_RELAY_MAP, DYNAMIC_KEYSHARES_RELAY_PREPROD_BASE_API_URL, DYNAMIC_KEYSHARES_RELAY_PROD_BASE_API_URL, DynamicApiClient, DynamicClientSessionSignature, DynamicElevatedAccessTokenHeader, DynamicForwardMPCHeader, DynamicMfaTokenHeader, DynamicRequestIdHeader, DynamicServerApiClient, DynamicSessionPublicKeyHeader, DynamicTraceElapsedTimeHeader, DynamicTraceIdHeader, ENCRYPTED_SHARES_STORAGE_SUFFIX, ENVIRONMENT_ENUM, EVM_COMPATIBLE_CHAINS, FEATURE_FLAGS, IFRAME_DOMAIN_MAP, Logger, MIDNIGHT_DERIVATION_PATHS, MPC_CHAIN_CONFIG, MPC_CONFIG, MPC_RELAY_DEV_API_URL, MPC_RELAY_PREPROD_API_URL, MPC_RELAY_PROD_API_URL, MPC_RELAY_URL_MAP, NETWORK_ERROR_CODE, NETWORK_ERROR_STATUS, NoopLogger, PREPROD_RELAY_API_KEY, PREPROD_RELAY_APP_ID, PROD_RELAY_API_KEY, PROD_RELAY_APP_ID, RELAY_API_KEY_HEADER, RELAY_APP_ID_HEADER, SDK_NAMESPACE, SERVER_SDK_ROUTE_PREFIX, SOLANA_RPC_URL, SuccessEventType, ThresholdSignatureScheme, URL_PATTERNS, WalletApiError, WalletOperation, WalletReadyState, assertDynamicLocationsHaveExternalKeyShareId, chain, chainEnumToVerifiedCredentialName, formatNamespacedVersion, getBitcoinChainConfig, getClientThreshold, getDynamicServerThreshold, getEnvironmentFromUrl, getMPCChainConfig, getRequiredExternalKeyShareId, getReshareConfig, getServerWalletReshareConfig, getTSSConfig, getVersionNamespace, getVersionWithoutNamespace, handleAxiosError, isEvmCompatibleChain, isRecoveredForwardMpcConnectionChurn, parseNamespacedVersion, serializeError, serializeMessageForForwardMPC, verifiedCredentialNameToChainEnum };
|
package/package.json
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@dynamic-labs-wallet/core",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.90",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"dependencies": {
|
|
7
|
-
"@dynamic-labs/sdk-api-core": "^0.0.
|
|
8
|
-
"@dynamic-labs-wallet/primitives": "1.0.
|
|
7
|
+
"@dynamic-labs/sdk-api-core": "^0.0.1093",
|
|
8
|
+
"@dynamic-labs-wallet/primitives": "1.0.90",
|
|
9
9
|
"axios": "1.16.0",
|
|
10
10
|
"uuid": "11.1.0"
|
|
11
11
|
},
|
|
@@ -4,6 +4,18 @@ export declare class WalletApiError extends Error {
|
|
|
4
4
|
code?: string;
|
|
5
5
|
constructor(status: number, message: string, code?: string);
|
|
6
6
|
}
|
|
7
|
+
/**
|
|
8
|
+
* `status` for a request that never received an HTTP response at all — the
|
|
9
|
+
* client lost connectivity, the request was aborted, DNS/TLS failed, or CORS
|
|
10
|
+
* blocked it. 0 matches the XHR/`fetch` convention for "no response".
|
|
11
|
+
*
|
|
12
|
+
* This used to be reported as `500 Internal server error`, which made a
|
|
13
|
+
* client-side network failure indistinguishable from a backend fault: the
|
|
14
|
+
* "Backend 500s" monitor counted 1,395 events on a day when the API returned
|
|
15
|
+
* only 33 real 5xx responses.
|
|
16
|
+
*/
|
|
17
|
+
export declare const NETWORK_ERROR_STATUS = 0;
|
|
18
|
+
export declare const NETWORK_ERROR_CODE = "NETWORK_ERROR";
|
|
7
19
|
export declare const handleAxiosError: (error: AxiosError, message: string, context: Record<string, unknown>, _logger?: unknown) => never;
|
|
8
20
|
export type { AxiosError } from 'axios';
|
|
9
21
|
export { isAxiosError } from 'axios';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"axiosErrorResponse.d.ts","sourceRoot":"","sources":["../../src/services/axiosErrorResponse.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,OAAO,CAAC;AAGxC,qBAAa,cAAe,SAAQ,KAAK;IACvC,MAAM,EAAE,MAAM,CAAC;IAIf,IAAI,CAAC,EAAE,MAAM,CAAC;gBAEF,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM;CAM3D;
|
|
1
|
+
{"version":3,"file":"axiosErrorResponse.d.ts","sourceRoot":"","sources":["../../src/services/axiosErrorResponse.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,OAAO,CAAC;AAGxC,qBAAa,cAAe,SAAQ,KAAK;IACvC,MAAM,EAAE,MAAM,CAAC;IAIf,IAAI,CAAC,EAAE,MAAM,CAAC;gBAEF,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM;CAM3D;AAgBD;;;;;;;;;GASG;AACH,eAAO,MAAM,oBAAoB,IAAI,CAAC;AACtC,eAAO,MAAM,kBAAkB,kBAAkB,CAAC;AAqDlD,eAAO,MAAM,gBAAgB,UACpB,UAAU,WACR,MAAM,WACN,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,YACtB,OAAO,UAqClB,CAAC;AAEF,YAAY,EAAE,UAAU,EAAE,MAAM,OAAO,CAAC;AACxC,OAAO,EAAE,YAAY,EAAE,MAAM,OAAO,CAAC"}
|