@levr-one/auth 1.0.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 +37 -0
- package/dist/config-watcher.d.ts +65 -0
- package/dist/config-watcher.d.ts.map +1 -0
- package/dist/config-watcher.js +140 -0
- package/dist/config-watcher.js.map +1 -0
- package/dist/config-watcher.test.d.ts +2 -0
- package/dist/config-watcher.test.d.ts.map +1 -0
- package/dist/config-watcher.test.js +116 -0
- package/dist/config-watcher.test.js.map +1 -0
- package/dist/config.d.ts +58 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +234 -0
- package/dist/config.js.map +1 -0
- package/dist/config.test.d.ts +2 -0
- package/dist/config.test.d.ts.map +1 -0
- package/dist/config.test.js +221 -0
- package/dist/config.test.js.map +1 -0
- package/dist/file-lock.d.ts +41 -0
- package/dist/file-lock.d.ts.map +1 -0
- package/dist/file-lock.js +110 -0
- package/dist/file-lock.js.map +1 -0
- package/dist/index.d.ts +43 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +43 -0
- package/dist/index.js.map +1 -0
- package/dist/oauth-client.d.ts +156 -0
- package/dist/oauth-client.d.ts.map +1 -0
- package/dist/oauth-client.js +572 -0
- package/dist/oauth-client.js.map +1 -0
- package/dist/oauth-client.test.d.ts +2 -0
- package/dist/oauth-client.test.d.ts.map +1 -0
- package/dist/oauth-client.test.js +290 -0
- package/dist/oauth-client.test.js.map +1 -0
- package/dist/test-utils.d.ts +10 -0
- package/dist/test-utils.d.ts.map +1 -0
- package/dist/test-utils.js +45 -0
- package/dist/test-utils.js.map +1 -0
- package/dist/token-store.d.ts +78 -0
- package/dist/token-store.d.ts.map +1 -0
- package/dist/token-store.js +299 -0
- package/dist/token-store.js.map +1 -0
- package/dist/token-store.test.d.ts +2 -0
- package/dist/token-store.test.d.ts.map +1 -0
- package/dist/token-store.test.js +239 -0
- package/dist/token-store.test.js.map +1 -0
- package/dist/token-watcher.d.ts +82 -0
- package/dist/token-watcher.d.ts.map +1 -0
- package/dist/token-watcher.js +185 -0
- package/dist/token-watcher.js.map +1 -0
- package/dist/types.d.ts +70 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +5 -0
- package/dist/types.js.map +1 -0
- package/dist/workspace-store.d.ts +60 -0
- package/dist/workspace-store.d.ts.map +1 -0
- package/dist/workspace-store.js +147 -0
- package/dist/workspace-store.js.map +1 -0
- package/dist/workspace-store.test.d.ts +2 -0
- package/dist/workspace-store.test.d.ts.map +1 -0
- package/dist/workspace-store.test.js +169 -0
- package/dist/workspace-store.test.js.map +1 -0
- package/dist/workspaces.d.ts +60 -0
- package/dist/workspaces.d.ts.map +1 -0
- package/dist/workspaces.js +80 -0
- package/dist/workspaces.js.map +1 -0
- package/dist/workspaces.test.d.ts +2 -0
- package/dist/workspaces.test.d.ts.map +1 -0
- package/dist/workspaces.test.js +111 -0
- package/dist/workspaces.test.js.map +1 -0
- package/package.json +58 -0
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @levr-one/auth - Shared OAuth 2.1 client with self-healing token management
|
|
3
|
+
*
|
|
4
|
+
* This package provides:
|
|
5
|
+
* - OAuthClient: OAuth 2.1 with PKCE for authorization flow
|
|
6
|
+
* - TokenWatcher: Self-healing token file watching
|
|
7
|
+
* - Token storage utilities with atomic writes
|
|
8
|
+
*
|
|
9
|
+
* Usage in MCP servers:
|
|
10
|
+
*
|
|
11
|
+
* ```typescript
|
|
12
|
+
* import { OAuthClient, TokenWatcher } from '@levr-one/auth';
|
|
13
|
+
*
|
|
14
|
+
* // Initialize OAuth client
|
|
15
|
+
* const oauth = new OAuthClient({ clientId: 'my-client' });
|
|
16
|
+
*
|
|
17
|
+
* // Start token watcher for self-healing
|
|
18
|
+
* const watcher = new TokenWatcher();
|
|
19
|
+
* watcher.onTokenChange((tokens) => {
|
|
20
|
+
* if (tokens) {
|
|
21
|
+
* oauth.setTokensFromStorage(tokens);
|
|
22
|
+
* }
|
|
23
|
+
* });
|
|
24
|
+
* watcher.start();
|
|
25
|
+
* ```
|
|
26
|
+
*/
|
|
27
|
+
export type { TokenResponse, StoredTokens, OAuthConfig, AuthStatus, TokenChangeCallback, DeviceAuthorizationResponse, } from './types.js';
|
|
28
|
+
export { loadTokens, loadTokensForEnv, loadTokensForUrl, saveTokens, saveTokensForEnv, clearTokens, restoreTokensFromBackup, hasStoredTokens, getTokenFilePath, getTqDir, resolveEnvFromUrl, resolveUrlFromEnv, } from './token-store.js';
|
|
29
|
+
export type { EnvName } from './token-store.js';
|
|
30
|
+
export { loadWorkspace, saveWorkspace, clearWorkspace, getWorkspaceFilePath, loadIdentityCache, saveIdentityCache, } from './workspace-store.js';
|
|
31
|
+
export type { IdentityCache } from './workspace-store.js';
|
|
32
|
+
export { loadConfig, writeConfig, getConfigFilePath, resolveFromApiUrl, PRESETS, } from './config.js';
|
|
33
|
+
export type { TqConfig } from './config.js';
|
|
34
|
+
export { OAuthClient } from './oauth-client.js';
|
|
35
|
+
export { listWorkspaces, WorkspaceFetchError } from './workspaces.js';
|
|
36
|
+
export type { WorkspaceSite, WorkspaceFetchErrorCode } from './workspaces.js';
|
|
37
|
+
export { acquireFileLock, getLockPath } from './file-lock.js';
|
|
38
|
+
export type { FileLockHandle } from './file-lock.js';
|
|
39
|
+
export { TokenWatcher } from './token-watcher.js';
|
|
40
|
+
export type { TokenWatcherOptions } from './token-watcher.js';
|
|
41
|
+
export { ConfigWatcher } from './config-watcher.js';
|
|
42
|
+
export type { ConfigWatcherOptions, ConfigChangeCallback, } from './config-watcher.js';
|
|
43
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AAGH,YAAY,EACV,aAAa,EACb,YAAY,EACZ,WAAW,EACX,UAAU,EACV,mBAAmB,EACnB,2BAA2B,GAC5B,MAAM,YAAY,CAAC;AAGpB,OAAO,EACL,UAAU,EACV,gBAAgB,EAChB,gBAAgB,EAChB,UAAU,EACV,gBAAgB,EAChB,WAAW,EACX,uBAAuB,EACvB,eAAe,EACf,gBAAgB,EAChB,QAAQ,EACR,iBAAiB,EACjB,iBAAiB,GAClB,MAAM,kBAAkB,CAAC;AAC1B,YAAY,EAAE,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAGhD,OAAO,EACL,aAAa,EACb,aAAa,EACb,cAAc,EACd,oBAAoB,EACpB,iBAAiB,EACjB,iBAAiB,GAClB,MAAM,sBAAsB,CAAC;AAC9B,YAAY,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAG1D,OAAO,EACL,UAAU,EACV,WAAW,EACX,iBAAiB,EACjB,iBAAiB,EACjB,OAAO,GACR,MAAM,aAAa,CAAC;AACrB,YAAY,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAG5C,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAGhD,OAAO,EAAE,cAAc,EAAE,mBAAmB,EAAE,MAAM,iBAAiB,CAAC;AACtE,YAAY,EAAE,aAAa,EAAE,uBAAuB,EAAE,MAAM,iBAAiB,CAAC;AAG9E,OAAO,EAAE,eAAe,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAC9D,YAAY,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAGrD,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,YAAY,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AAG9D,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACpD,YAAY,EACV,oBAAoB,EACpB,oBAAoB,GACrB,MAAM,qBAAqB,CAAC"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @levr-one/auth - Shared OAuth 2.1 client with self-healing token management
|
|
3
|
+
*
|
|
4
|
+
* This package provides:
|
|
5
|
+
* - OAuthClient: OAuth 2.1 with PKCE for authorization flow
|
|
6
|
+
* - TokenWatcher: Self-healing token file watching
|
|
7
|
+
* - Token storage utilities with atomic writes
|
|
8
|
+
*
|
|
9
|
+
* Usage in MCP servers:
|
|
10
|
+
*
|
|
11
|
+
* ```typescript
|
|
12
|
+
* import { OAuthClient, TokenWatcher } from '@levr-one/auth';
|
|
13
|
+
*
|
|
14
|
+
* // Initialize OAuth client
|
|
15
|
+
* const oauth = new OAuthClient({ clientId: 'my-client' });
|
|
16
|
+
*
|
|
17
|
+
* // Start token watcher for self-healing
|
|
18
|
+
* const watcher = new TokenWatcher();
|
|
19
|
+
* watcher.onTokenChange((tokens) => {
|
|
20
|
+
* if (tokens) {
|
|
21
|
+
* oauth.setTokensFromStorage(tokens);
|
|
22
|
+
* }
|
|
23
|
+
* });
|
|
24
|
+
* watcher.start();
|
|
25
|
+
* ```
|
|
26
|
+
*/
|
|
27
|
+
// Token storage (with atomic writes, map keyed by backend URL)
|
|
28
|
+
export { loadTokens, loadTokensForEnv, loadTokensForUrl, saveTokens, saveTokensForEnv, clearTokens, restoreTokensFromBackup, hasStoredTokens, getTokenFilePath, getTqDir, resolveEnvFromUrl, resolveUrlFromEnv, } from './token-store.js';
|
|
29
|
+
// Workspace storage
|
|
30
|
+
export { loadWorkspace, saveWorkspace, clearWorkspace, getWorkspaceFilePath, loadIdentityCache, saveIdentityCache, } from './workspace-store.js';
|
|
31
|
+
// Unified environment config
|
|
32
|
+
export { loadConfig, writeConfig, getConfigFilePath, resolveFromApiUrl, PRESETS, } from './config.js';
|
|
33
|
+
// OAuth client
|
|
34
|
+
export { OAuthClient } from './oauth-client.js';
|
|
35
|
+
// Workspace listing (public library surface)
|
|
36
|
+
export { listWorkspaces, WorkspaceFetchError } from './workspaces.js';
|
|
37
|
+
// File lock (cross-process refresh coordination)
|
|
38
|
+
export { acquireFileLock, getLockPath } from './file-lock.js';
|
|
39
|
+
// Token watcher (self-healing core)
|
|
40
|
+
export { TokenWatcher } from './token-watcher.js';
|
|
41
|
+
// Config watcher (environment change detection)
|
|
42
|
+
export { ConfigWatcher } from './config-watcher.js';
|
|
43
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AAYH,+DAA+D;AAC/D,OAAO,EACL,UAAU,EACV,gBAAgB,EAChB,gBAAgB,EAChB,UAAU,EACV,gBAAgB,EAChB,WAAW,EACX,uBAAuB,EACvB,eAAe,EACf,gBAAgB,EAChB,QAAQ,EACR,iBAAiB,EACjB,iBAAiB,GAClB,MAAM,kBAAkB,CAAC;AAG1B,oBAAoB;AACpB,OAAO,EACL,aAAa,EACb,aAAa,EACb,cAAc,EACd,oBAAoB,EACpB,iBAAiB,EACjB,iBAAiB,GAClB,MAAM,sBAAsB,CAAC;AAG9B,6BAA6B;AAC7B,OAAO,EACL,UAAU,EACV,WAAW,EACX,iBAAiB,EACjB,iBAAiB,EACjB,OAAO,GACR,MAAM,aAAa,CAAC;AAGrB,eAAe;AACf,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAEhD,6CAA6C;AAC7C,OAAO,EAAE,cAAc,EAAE,mBAAmB,EAAE,MAAM,iBAAiB,CAAC;AAGtE,iDAAiD;AACjD,OAAO,EAAE,eAAe,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAG9D,oCAAoC;AACpC,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAGlD,gDAAgD;AAChD,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC"}
|
|
@@ -0,0 +1,156 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* OAuth 2.0 client for TQ MCP servers
|
|
3
|
+
* Implements authorization code flow with PKCE (RFC 7636)
|
|
4
|
+
*/
|
|
5
|
+
import type { OAuthConfig, StoredTokens } from './types.js';
|
|
6
|
+
export declare class OAuthClient {
|
|
7
|
+
private config;
|
|
8
|
+
private accessToken;
|
|
9
|
+
private refreshToken;
|
|
10
|
+
private expiresAt;
|
|
11
|
+
private consecutiveRefreshFailures;
|
|
12
|
+
/**
|
|
13
|
+
* Set when refresh is definitively rejected (400/401).
|
|
14
|
+
* Prevents further network refresh attempts until re-authorization
|
|
15
|
+
* or fresh tokens are loaded via setTokensFromStorage/authorize.
|
|
16
|
+
*/
|
|
17
|
+
private refreshRejected;
|
|
18
|
+
/**
|
|
19
|
+
* Deduplicates concurrent refresh calls. When multiple callers invoke
|
|
20
|
+
* refresh() simultaneously (e.g., parallel MCP tool requests), they
|
|
21
|
+
* all await the same in-flight promise instead of each firing a
|
|
22
|
+
* separate token rotation request — which would cause the second
|
|
23
|
+
* request to fail with invalid_grant (token already revoked by first).
|
|
24
|
+
*/
|
|
25
|
+
private refreshPromise;
|
|
26
|
+
constructor(config: Partial<OAuthConfig> & {
|
|
27
|
+
clientId: string;
|
|
28
|
+
});
|
|
29
|
+
/**
|
|
30
|
+
* Load tokens from persistent storage
|
|
31
|
+
*/
|
|
32
|
+
private loadStoredTokens;
|
|
33
|
+
/**
|
|
34
|
+
* Set tokens from external storage (used during initialization)
|
|
35
|
+
*/
|
|
36
|
+
setTokensFromStorage(tokens: StoredTokens): void;
|
|
37
|
+
/**
|
|
38
|
+
* Generate PKCE code verifier and challenge
|
|
39
|
+
* @see https://datatracker.ietf.org/doc/html/rfc7636
|
|
40
|
+
*/
|
|
41
|
+
private generatePKCE;
|
|
42
|
+
/**
|
|
43
|
+
* Start local HTTP server to receive OAuth callback
|
|
44
|
+
*/
|
|
45
|
+
private waitForCallback;
|
|
46
|
+
/**
|
|
47
|
+
* Perform full OAuth authorization flow
|
|
48
|
+
* Opens browser for user to authorize, waits for callback
|
|
49
|
+
*/
|
|
50
|
+
authorize(): Promise<void>;
|
|
51
|
+
/**
|
|
52
|
+
* Perform OAuth 2.0 Device Authorization Grant (RFC 8628).
|
|
53
|
+
* Works in headless/remote terminals — no browser redirect needed.
|
|
54
|
+
* Displays a URL and code for the user to authorize on any device.
|
|
55
|
+
*/
|
|
56
|
+
authorizeDevice(): Promise<void>;
|
|
57
|
+
/**
|
|
58
|
+
* Exchange authorization code for access and refresh tokens
|
|
59
|
+
*/
|
|
60
|
+
private exchangeCode;
|
|
61
|
+
/**
|
|
62
|
+
* Refresh access token using refresh token.
|
|
63
|
+
*
|
|
64
|
+
* Two layers of coordination:
|
|
65
|
+
* 1. In-process: `refreshPromise` dedups concurrent callers within
|
|
66
|
+
* this OAuthClient instance.
|
|
67
|
+
* 2. Cross-process: a file lock keyed on apiBaseUrl serializes
|
|
68
|
+
* refreshes across MCP server processes. On lock acquire, we
|
|
69
|
+
* re-read the on-disk token — if another process already
|
|
70
|
+
* refreshed while we waited, adopt their tokens and skip the
|
|
71
|
+
* network call. This avoids the "N processes all POST with the
|
|
72
|
+
* same refresh_token, all but one get invalid_grant" race that
|
|
73
|
+
* would otherwise exhaust consecutiveRefreshFailures and trigger
|
|
74
|
+
* clearTokens().
|
|
75
|
+
*/
|
|
76
|
+
refresh(): Promise<void>;
|
|
77
|
+
/**
|
|
78
|
+
* Acquire the cross-process refresh lock, re-check disk state, and
|
|
79
|
+
* either adopt freshly-rotated tokens from disk or call the refresh
|
|
80
|
+
* endpoint. Always releases the lock.
|
|
81
|
+
*/
|
|
82
|
+
private refreshWithLock;
|
|
83
|
+
/**
|
|
84
|
+
* Internal refresh implementation — called only once per dedup window.
|
|
85
|
+
* All concurrent callers share the same promise via refresh().
|
|
86
|
+
*/
|
|
87
|
+
private refreshInternal;
|
|
88
|
+
/**
|
|
89
|
+
* Store tokens in memory and persist to disk.
|
|
90
|
+
*
|
|
91
|
+
* Non-refresh grants (authorization_code, device_code, password) carry
|
|
92
|
+
* `tokens.user.workspace_id` — the workspace the user just logged into.
|
|
93
|
+
* Refresh grants omit it. When present we persist it to ~/.tq/workspace.json
|
|
94
|
+
* so MCP clients pick up the selected workspace without a separate round-trip.
|
|
95
|
+
*/
|
|
96
|
+
private setTokens;
|
|
97
|
+
/**
|
|
98
|
+
* Get a valid access token, refreshing if needed
|
|
99
|
+
* Note: Does NOT auto-authorize - throws if no tokens available
|
|
100
|
+
*/
|
|
101
|
+
getAccessToken(): Promise<string>;
|
|
102
|
+
/**
|
|
103
|
+
* Get access token without auto-refresh (for checking current state)
|
|
104
|
+
*/
|
|
105
|
+
getAccessTokenSync(): string | null;
|
|
106
|
+
/**
|
|
107
|
+
* Check if client has valid tokens
|
|
108
|
+
*/
|
|
109
|
+
isAuthorized(): boolean;
|
|
110
|
+
/**
|
|
111
|
+
* Check if tokens exist (may be expired)
|
|
112
|
+
*/
|
|
113
|
+
hasTokens(): boolean;
|
|
114
|
+
/**
|
|
115
|
+
* Attempt a proactive (background) refresh without accumulating toward
|
|
116
|
+
* the nuclear clearTokens() threshold. If refresh fails, the failure
|
|
117
|
+
* counter is reset so background timer ticks can never delete the
|
|
118
|
+
* token file. Only critical-path refreshes (from getAccessToken /
|
|
119
|
+
* ensureAuth) should count toward the threshold.
|
|
120
|
+
*
|
|
121
|
+
* @returns true if refresh succeeded, false otherwise
|
|
122
|
+
*/
|
|
123
|
+
refreshProactive(): Promise<boolean>;
|
|
124
|
+
/**
|
|
125
|
+
* Clear all tokens (logout). Also clears the persisted workspace selection
|
|
126
|
+
* so the next login starts from a clean state on shared machines.
|
|
127
|
+
*/
|
|
128
|
+
clearTokens(): void;
|
|
129
|
+
/**
|
|
130
|
+
* Get token expiration time
|
|
131
|
+
*/
|
|
132
|
+
getExpiresAt(): number;
|
|
133
|
+
/**
|
|
134
|
+
* Get current refresh token (for storage)
|
|
135
|
+
*/
|
|
136
|
+
getRefreshToken(): string | null;
|
|
137
|
+
/**
|
|
138
|
+
* Get time until expiration in milliseconds
|
|
139
|
+
*/
|
|
140
|
+
getTimeUntilExpiry(): number;
|
|
141
|
+
/**
|
|
142
|
+
* Check if token is expiring soon (within given minutes)
|
|
143
|
+
*/
|
|
144
|
+
isExpiringSoon(withinMinutes?: number): boolean;
|
|
145
|
+
/**
|
|
146
|
+
* Check if refresh was definitively rejected (token revoked/invalid).
|
|
147
|
+
* When true, no further refresh attempts will be made until
|
|
148
|
+
* re-authorization or fresh tokens are loaded.
|
|
149
|
+
*/
|
|
150
|
+
isRefreshRejected(): boolean;
|
|
151
|
+
/**
|
|
152
|
+
* Reload tokens from storage (useful after external refresh)
|
|
153
|
+
*/
|
|
154
|
+
reloadTokens(): void;
|
|
155
|
+
}
|
|
156
|
+
//# sourceMappingURL=oauth-client.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"oauth-client.d.ts","sourceRoot":"","sources":["../src/oauth-client.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAcH,OAAO,KAAK,EAEV,WAAW,EACX,YAAY,EAEb,MAAM,YAAY,CAAC;AAYpB,qBAAa,WAAW;IACtB,OAAO,CAAC,MAAM,CAAc;IAC5B,OAAO,CAAC,WAAW,CAAuB;IAC1C,OAAO,CAAC,YAAY,CAAuB;IAC3C,OAAO,CAAC,SAAS,CAAa;IAC9B,OAAO,CAAC,0BAA0B,CAAa;IAC/C;;;;OAIG;IACH,OAAO,CAAC,eAAe,CAAkB;IACzC;;;;;;OAMG;IACH,OAAO,CAAC,cAAc,CAA8B;gBAExC,MAAM,EAAE,OAAO,CAAC,WAAW,CAAC,GAAG;QAAE,QAAQ,EAAE,MAAM,CAAA;KAAE;IAkB/D;;OAEG;IACH,OAAO,CAAC,gBAAgB;IASxB;;OAEG;IACH,oBAAoB,CAAC,MAAM,EAAE,YAAY,GAAG,IAAI;IAQhD;;;OAGG;IACH,OAAO,CAAC,YAAY;IAapB;;OAEG;YACW,eAAe;IAkF7B;;;OAGG;IACG,SAAS,IAAI,OAAO,CAAC,IAAI,CAAC;IAsChC;;;;OAIG;IACG,eAAe,IAAI,OAAO,CAAC,IAAI,CAAC;IAkFtC;;OAEG;YACW,YAAY;IAgC1B;;;;;;;;;;;;;;OAcG;IACG,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;IAkC9B;;;;OAIG;YACW,eAAe;IA+C7B;;;OAGG;YACW,eAAe;IAyE7B;;;;;;;OAOG;IACH,OAAO,CAAC,SAAS;IAuBjB;;;OAGG;IACG,cAAc,IAAI,OAAO,CAAC,MAAM,CAAC;IAoBvC;;OAEG;IACH,kBAAkB,IAAI,MAAM,GAAG,IAAI;IAInC;;OAEG;IACH,YAAY,IAAI,OAAO;IAIvB;;OAEG;IACH,SAAS,IAAI,OAAO;IAIpB;;;;;;;;OAQG;IACG,gBAAgB,IAAI,OAAO,CAAC,OAAO,CAAC;IAY1C;;;OAGG;IACH,WAAW,IAAI,IAAI;IAQnB;;OAEG;IACH,YAAY,IAAI,MAAM;IAItB;;OAEG;IACH,eAAe,IAAI,MAAM,GAAG,IAAI;IAIhC;;OAEG;IACH,kBAAkB,IAAI,MAAM;IAI5B;;OAEG;IACH,cAAc,CAAC,aAAa,GAAE,MAAU,GAAG,OAAO;IAMlD;;;;OAIG;IACH,iBAAiB,IAAI,OAAO;IAI5B;;OAEG;IACH,YAAY,IAAI,IAAI;CAGrB"}
|