@doist/todoist-cli 1.63.2 → 1.65.0-next.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/CHANGELOG.md +6 -0
- package/dist/commands/auth/index.d.ts.map +1 -1
- package/dist/commands/auth/index.js +24 -21
- package/dist/commands/auth/index.js.map +1 -1
- package/dist/commands/auth/logout.d.ts +5 -5
- package/dist/commands/auth/logout.js +5 -5
- package/dist/commands/auth/store-wrap.d.ts +19 -0
- package/dist/commands/auth/store-wrap.d.ts.map +1 -0
- package/dist/commands/auth/store-wrap.js +41 -0
- package/dist/commands/auth/store-wrap.js.map +1 -0
- package/dist/commands/auth/token.d.ts.map +1 -1
- package/dist/commands/auth/token.js +8 -10
- package/dist/commands/auth/token.js.map +1 -1
- package/dist/commands/config/view.d.ts.map +1 -1
- package/dist/commands/config/view.js +2 -1
- package/dist/commands/config/view.js.map +1 -1
- package/dist/commands/goal.d.ts +3 -0
- package/dist/commands/goal.d.ts.map +1 -0
- package/dist/commands/goal.js +344 -0
- package/dist/commands/goal.js.map +1 -0
- package/dist/commands/user/remove.d.ts.map +1 -1
- package/dist/commands/user/remove.js +10 -5
- package/dist/commands/user/remove.js.map +1 -1
- package/dist/commands/user/use.d.ts.map +1 -1
- package/dist/commands/user/use.js +6 -6
- package/dist/commands/user/use.js.map +1 -1
- package/dist/index.js +3 -1
- package/dist/index.js.map +1 -1
- package/dist/lib/auth-store.d.ts +26 -21
- package/dist/lib/auth-store.d.ts.map +1 -1
- package/dist/lib/auth-store.js +48 -74
- package/dist/lib/auth-store.js.map +1 -1
- package/dist/lib/auth.d.ts +6 -53
- package/dist/lib/auth.d.ts.map +1 -1
- package/dist/lib/auth.js +41 -349
- package/dist/lib/auth.js.map +1 -1
- package/dist/lib/config.d.ts +8 -0
- package/dist/lib/config.d.ts.map +1 -1
- package/dist/lib/config.js +11 -0
- package/dist/lib/config.js.map +1 -1
- package/dist/lib/global-args.d.ts +0 -7
- package/dist/lib/global-args.d.ts.map +1 -1
- package/dist/lib/global-args.js +0 -33
- package/dist/lib/global-args.js.map +1 -1
- package/dist/lib/migrate-auth.d.ts +9 -5
- package/dist/lib/migrate-auth.d.ts.map +1 -1
- package/dist/lib/migrate-auth.js +78 -121
- package/dist/lib/migrate-auth.js.map +1 -1
- package/dist/lib/output.d.ts +1 -1
- package/dist/lib/output.d.ts.map +1 -1
- package/dist/lib/output.js +15 -0
- package/dist/lib/output.js.map +1 -1
- package/dist/lib/pagination.d.ts +1 -0
- package/dist/lib/pagination.d.ts.map +1 -1
- package/dist/lib/pagination.js +1 -0
- package/dist/lib/pagination.js.map +1 -1
- package/dist/lib/refs.d.ts +2 -1
- package/dist/lib/refs.d.ts.map +1 -1
- package/dist/lib/refs.js +6 -1
- package/dist/lib/refs.js.map +1 -1
- package/dist/lib/skills/content.d.ts +1 -1
- package/dist/lib/skills/content.d.ts.map +1 -1
- package/dist/lib/skills/content.js +20 -0
- package/dist/lib/skills/content.js.map +1 -1
- package/dist/lib/urls.d.ts +2 -0
- package/dist/lib/urls.d.ts.map +1 -1
- package/dist/lib/urls.js +6 -0
- package/dist/lib/urls.js.map +1 -1
- package/dist/lib/user-records.d.ts +17 -0
- package/dist/lib/user-records.d.ts.map +1 -0
- package/dist/lib/user-records.js +84 -0
- package/dist/lib/user-records.js.map +1 -0
- package/dist/lib/users.d.ts +22 -15
- package/dist/lib/users.d.ts.map +1 -1
- package/dist/lib/users.js +41 -38
- package/dist/lib/users.js.map +1 -1
- package/package.json +7 -7
- package/dist/commands/auth/token-view.d.ts +0 -2
- package/dist/commands/auth/token-view.d.ts.map +0 -1
- package/dist/commands/auth/token-view.js +0 -13
- package/dist/commands/auth/token-view.js.map +0 -1
- package/dist/lib/secure-store.d.ts +0 -25
- package/dist/lib/secure-store.d.ts.map +0 -1
- package/dist/lib/secure-store.js +0 -72
- package/dist/lib/secure-store.js.map +0 -1
package/dist/lib/auth-store.js
CHANGED
|
@@ -1,12 +1,23 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
1
|
+
import { createKeyringTokenStore, } from '@doist/cli-core/auth';
|
|
2
|
+
import { getConfigPath } from './config.js';
|
|
3
|
+
import { createTodoistUserRecordStore } from './user-records.js';
|
|
4
|
+
import { matchUserRef } from './users.js';
|
|
5
|
+
/**
|
|
6
|
+
* Persisted identifiers for the keyring/config ABI. Shared with the read-side
|
|
7
|
+
* resolver (`auth.ts`) and the postinstall migration (`migrate-auth.ts`) so
|
|
8
|
+
* a rename can't silently desynchronise the three paths that touch the OS
|
|
9
|
+
* credential manager.
|
|
10
|
+
*/
|
|
11
|
+
export const SERVICE_NAME = 'todoist-cli';
|
|
12
|
+
export const LEGACY_ACCOUNT = 'api-token';
|
|
13
|
+
export const TOKEN_ENV_VAR = 'TODOIST_API_TOKEN';
|
|
14
|
+
export function accountForUser(id) {
|
|
15
|
+
return `user-${id}`;
|
|
16
|
+
}
|
|
5
17
|
/**
|
|
6
18
|
* Single source of truth for the `TodoistAccount` field layout. Used by the
|
|
7
|
-
* auth provider's `validateToken` (post-handshake)
|
|
8
|
-
* `
|
|
9
|
-
* what `set()` later disassembles via `accountToUpsertInput`.
|
|
19
|
+
* auth provider's `validateToken` (post-handshake), the migration helper,
|
|
20
|
+
* and the `UserRecordStore` adapter's record → account mapping.
|
|
10
21
|
*/
|
|
11
22
|
export function toTodoistAccount(input) {
|
|
12
23
|
return {
|
|
@@ -18,78 +29,41 @@ export function toTodoistAccount(input) {
|
|
|
18
29
|
auth_flags: input.authFlags,
|
|
19
30
|
};
|
|
20
31
|
}
|
|
21
|
-
/**
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
authMode: user.auth_mode ?? 'unknown',
|
|
37
|
-
authScope: user.auth_scope,
|
|
38
|
-
authFlags: user.auth_flags,
|
|
39
|
-
});
|
|
40
|
-
}
|
|
32
|
+
/**
|
|
33
|
+
* cli-core's keyring-backed `TokenStore`, wired to todoist-cli's
|
|
34
|
+
* `UserRecordStore` adapter. Two Todoist-specific overlays on top of the
|
|
35
|
+
* defaults:
|
|
36
|
+
*
|
|
37
|
+
* - `active()` short-circuits to `null` when `TODOIST_API_TOKEN` is set.
|
|
38
|
+
* The env var is the canonical override across the CLI; without this
|
|
39
|
+
* short-circuit, `td auth status` would render the stored account while
|
|
40
|
+
* `getAuthMetadata()` reports `source: 'env'` (wrong account, right
|
|
41
|
+
* diagnostic).
|
|
42
|
+
* - `accountForUser` / `matchAccount` are passed explicitly. `matchAccount`
|
|
43
|
+
* delegates to `matchUserRef` so the keyring-store path and the
|
|
44
|
+
* config-driven `findUserByRef` path share one matcher (case-insensitive
|
|
45
|
+
* email + trim).
|
|
46
|
+
*/
|
|
41
47
|
export function createTodoistTokenStore() {
|
|
42
|
-
|
|
43
|
-
|
|
48
|
+
const inner = createKeyringTokenStore({
|
|
49
|
+
serviceName: SERVICE_NAME,
|
|
50
|
+
userRecords: createTodoistUserRecordStore(),
|
|
51
|
+
recordsLocation: getConfigPath(),
|
|
52
|
+
accountForUser,
|
|
53
|
+
matchAccount: (account, ref) => matchUserRef({ id: account.id, email: account.email }, ref),
|
|
54
|
+
});
|
|
44
55
|
return {
|
|
45
|
-
|
|
46
|
-
* Pure view of persisted state. Deliberately ignores the global
|
|
47
|
-
* `--user` selector (a CLI-invocation concern, not storage) and
|
|
48
|
-
* returns `null` when `TODOIST_API_TOKEN` is in play (env tokens
|
|
49
|
-
* don't represent a persisted account). When multiple accounts
|
|
50
|
-
* are stored without a default, returns `null` rather than
|
|
51
|
-
* throwing a selection error — the runtime caller can react to
|
|
52
|
-
* "no active persisted account" but shouldn't see CLI-arg errors
|
|
53
|
-
* leaking out of a store read.
|
|
54
|
-
*/
|
|
55
|
-
async active() {
|
|
56
|
+
active: async (ref) => {
|
|
56
57
|
if (process.env[TOKEN_ENV_VAR])
|
|
57
58
|
return null;
|
|
58
|
-
|
|
59
|
-
const users = getStoredUsers(config);
|
|
60
|
-
if (users.length === 0)
|
|
61
|
-
return null;
|
|
62
|
-
const target = getDefaultUser(config) ?? (users.length === 1 ? users[0] : null);
|
|
63
|
-
if (!target)
|
|
64
|
-
return null;
|
|
65
|
-
try {
|
|
66
|
-
const { token } = await loadTokenForStoredUser(target);
|
|
67
|
-
return { token, account: storedUserToAccount(target) };
|
|
68
|
-
}
|
|
69
|
-
catch (error) {
|
|
70
|
-
// Token unreachable (no secret, keyring offline) — surface as
|
|
71
|
-
// "no active persisted account" so a `set()` retry can recover
|
|
72
|
-
// without a runtime caller having to special-case storage errors.
|
|
73
|
-
if (error instanceof NoTokenError)
|
|
74
|
-
return null;
|
|
75
|
-
if (error instanceof SecureStoreUnavailableError)
|
|
76
|
-
return null;
|
|
77
|
-
throw error;
|
|
78
|
-
}
|
|
79
|
-
},
|
|
80
|
-
async set(account, token) {
|
|
81
|
-
const { replaced: _replaced, ...result } = await upsertUser(accountToUpsertInput(account, token));
|
|
82
|
-
lastStorageResult = result;
|
|
83
|
-
},
|
|
84
|
-
async clear() {
|
|
85
|
-
lastClearResult = await clearApiToken();
|
|
86
|
-
},
|
|
87
|
-
getLastStorageResult() {
|
|
88
|
-
return lastStorageResult;
|
|
89
|
-
},
|
|
90
|
-
getLastClearResult() {
|
|
91
|
-
return lastClearResult;
|
|
59
|
+
return inner.active(ref);
|
|
92
60
|
},
|
|
61
|
+
set: (account, token) => inner.set(account, token),
|
|
62
|
+
clear: (ref) => inner.clear(ref),
|
|
63
|
+
list: () => inner.list(),
|
|
64
|
+
setDefault: (ref) => inner.setDefault(ref),
|
|
65
|
+
getLastStorageResult: () => inner.getLastStorageResult(),
|
|
66
|
+
getLastClearResult: () => inner.getLastClearResult(),
|
|
93
67
|
};
|
|
94
68
|
}
|
|
95
69
|
//# sourceMappingURL=auth-store.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"auth-store.js","sourceRoot":"","sources":["../../src/lib/auth-store.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"auth-store.js","sourceRoot":"","sources":["../../src/lib/auth-store.ts"],"names":[],"mappings":"AAAA,OAAO,EAGH,uBAAuB,GAE1B,MAAM,sBAAsB,CAAA;AAC7B,OAAO,EAAgC,aAAa,EAAE,MAAM,aAAa,CAAA;AACzE,OAAO,EAAE,4BAA4B,EAAE,MAAM,mBAAmB,CAAA;AAChE,OAAO,EAAE,YAAY,EAAE,MAAM,YAAY,CAAA;AAEzC;;;;;GAKG;AACH,MAAM,CAAC,MAAM,YAAY,GAAG,aAAa,CAAA;AACzC,MAAM,CAAC,MAAM,cAAc,GAAG,WAAW,CAAA;AACzC,MAAM,CAAC,MAAM,aAAa,GAAG,mBAAmB,CAAA;AAChD,MAAM,UAAU,cAAc,CAAC,EAAU;IACrC,OAAO,QAAQ,EAAE,EAAE,CAAA;AACvB,CAAC;AAsBD;;;;GAIG;AACH,MAAM,UAAU,gBAAgB,CAAC,KAA0B;IACvD,OAAO;QACH,EAAE,EAAE,KAAK,CAAC,EAAE;QACZ,KAAK,EAAE,KAAK,CAAC,KAAK;QAClB,KAAK,EAAE,KAAK,CAAC,KAAK;QAClB,SAAS,EAAE,KAAK,CAAC,QAAQ;QACzB,UAAU,EAAE,KAAK,CAAC,SAAS;QAC3B,UAAU,EAAE,KAAK,CAAC,SAAS;KAC9B,CAAA;AACL,CAAC;AAID;;;;;;;;;;;;;;GAcG;AACH,MAAM,UAAU,uBAAuB;IACnC,MAAM,KAAK,GAAG,uBAAuB,CAAiB;QAClD,WAAW,EAAE,YAAY;QACzB,WAAW,EAAE,4BAA4B,EAAE;QAC3C,eAAe,EAAE,aAAa,EAAE;QAChC,cAAc;QACd,YAAY,EAAE,CAAC,OAAuB,EAAE,GAAe,EAAE,EAAE,CACvD,YAAY,CAAC,EAAE,EAAE,EAAE,OAAO,CAAC,EAAE,EAAE,KAAK,EAAE,OAAO,CAAC,KAAK,EAAE,EAAE,GAAG,CAAC;KAClE,CAAC,CAAA;IACF,OAAO;QACH,MAAM,EAAE,KAAK,EAAE,GAAG,EAAE,EAAE;YAClB,IAAI,OAAO,CAAC,GAAG,CAAC,aAAa,CAAC;gBAAE,OAAO,IAAI,CAAA;YAC3C,OAAO,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAA;QAC5B,CAAC;QACD,GAAG,EAAE,CAAC,OAAO,EAAE,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,OAAO,EAAE,KAAK,CAAC;QAClD,KAAK,EAAE,CAAC,GAAG,EAAE,EAAE,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC;QAChC,IAAI,EAAE,GAAG,EAAE,CAAC,KAAK,CAAC,IAAI,EAAE;QACxB,UAAU,EAAE,CAAC,GAAG,EAAE,EAAE,CAAC,KAAK,CAAC,UAAU,CAAC,GAAG,CAAC;QAC1C,oBAAoB,EAAE,GAAG,EAAE,CAAC,KAAK,CAAC,oBAAoB,EAAE;QACxD,kBAAkB,EAAE,GAAG,EAAE,CAAC,KAAK,CAAC,kBAAkB,EAAE;KACvD,CAAA;AACL,CAAC"}
|
package/dist/lib/auth.d.ts
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
|
+
export type { TokenStorageLocation, TokenStorageResult } from '@doist/cli-core/auth';
|
|
1
2
|
export { AUTH_FLAG_ORDER, CONFIG_VERSION, getConfigPath, readConfig, writeConfig, type AuthFlag, type AuthMode, type Config, type StoredUser, type UpdateChannel, } from './config.js';
|
|
2
3
|
import { type AuthFlag, type AuthMode, type StoredUser } from './config.js';
|
|
3
4
|
import { CliError } from './errors.js';
|
|
4
|
-
export
|
|
5
|
+
export { TOKEN_ENV_VAR } from './auth-store.js';
|
|
5
6
|
export interface AuthMetadata {
|
|
6
7
|
authMode: AuthMode;
|
|
7
8
|
authScope?: string;
|
|
@@ -19,22 +20,9 @@ export interface ResolvedUser {
|
|
|
19
20
|
authFlags?: AuthFlag[];
|
|
20
21
|
source: AuthMetadata['source'];
|
|
21
22
|
}
|
|
22
|
-
export interface UpsertUserInput {
|
|
23
|
-
id: string;
|
|
24
|
-
email: string;
|
|
25
|
-
token: string;
|
|
26
|
-
authMode?: AuthMode;
|
|
27
|
-
authScope?: string;
|
|
28
|
-
authFlags?: AuthFlag[];
|
|
29
|
-
}
|
|
30
23
|
export declare class NoTokenError extends CliError {
|
|
31
24
|
constructor();
|
|
32
25
|
}
|
|
33
|
-
export type TokenStorageLocation = 'secure-store' | 'config-file';
|
|
34
|
-
export interface TokenStorageResult {
|
|
35
|
-
storage: TokenStorageLocation;
|
|
36
|
-
warning?: string;
|
|
37
|
-
}
|
|
38
26
|
/**
|
|
39
27
|
* Resolve which stored user this invocation should act as, and load their
|
|
40
28
|
* token. Honors `--user <ref>`, then `user.defaultUser`, then a single stored
|
|
@@ -48,52 +36,17 @@ export interface TokenStorageResult {
|
|
|
48
36
|
export declare function resolveActiveUser(opts?: {
|
|
49
37
|
ref?: string;
|
|
50
38
|
}): Promise<ResolvedUser>;
|
|
51
|
-
/**
|
|
52
|
-
* Backwards-compatible no-arg accessor for the active user's token. Most call
|
|
53
|
-
* sites (uploads, stats, api/core) only need the bearer string.
|
|
54
|
-
*/
|
|
39
|
+
/** Bearer-only shortcut. Most call sites (SDK, uploads, stats) only need this. */
|
|
55
40
|
export declare function getApiToken(): Promise<string>;
|
|
56
41
|
/**
|
|
57
|
-
* Like `resolveActiveUser` but
|
|
58
|
-
*
|
|
59
|
-
*
|
|
42
|
+
* Like `resolveActiveUser` but bundles the rendering metadata `td doctor` /
|
|
43
|
+
* `td config view` want. Lets `SecureStoreUnavailableError` propagate so the
|
|
44
|
+
* diagnostic surfaces can distinguish "missing token" from "broken keyring".
|
|
60
45
|
*/
|
|
61
46
|
export declare function probeApiToken(): Promise<{
|
|
62
47
|
token: string;
|
|
63
48
|
metadata: AuthMetadata;
|
|
64
49
|
}>;
|
|
65
50
|
export declare function getAuthMetadata(): Promise<AuthMetadata>;
|
|
66
|
-
/**
|
|
67
|
-
* Add or update a user record. Stores the token in the OS credential manager
|
|
68
|
-
* under `user-<id>` when available, falls back to per-user plaintext in config.
|
|
69
|
-
* Sets `defaultUser` automatically if this is the first user being stored.
|
|
70
|
-
*/
|
|
71
|
-
export declare function upsertUser(input: UpsertUserInput): Promise<TokenStorageResult & {
|
|
72
|
-
replaced: boolean;
|
|
73
|
-
}>;
|
|
74
|
-
/**
|
|
75
|
-
* Remove the active user (resolved via `--user` or default). For multi-user
|
|
76
|
-
* installs without a default, callers must pass `--user <ref>` to disambiguate.
|
|
77
|
-
*/
|
|
78
|
-
export declare function clearApiToken(opts?: {
|
|
79
|
-
ref?: string;
|
|
80
|
-
}): Promise<TokenStorageResult>;
|
|
81
|
-
/**
|
|
82
|
-
* Remove a specific user by id. Used by `td user remove` and as the underlying
|
|
83
|
-
* primitive for `clearApiToken`.
|
|
84
|
-
*
|
|
85
|
-
* Order matters: write the new config first (the source of truth) and only
|
|
86
|
-
* then delete the secret. If the config update fails the keyring is untouched,
|
|
87
|
-
* so the user remains fully functional and a retry will simply re-attempt
|
|
88
|
-
* the same operation. A keyring delete failure after a successful config
|
|
89
|
-
* update leaves an orphan secret that the keyring's own service can clean up
|
|
90
|
-
* later — the CLI no longer references it.
|
|
91
|
-
*/
|
|
92
|
-
export declare function removeUserById(id: string): Promise<TokenStorageResult>;
|
|
93
|
-
export declare function setDefaultUserId(id: string): Promise<void>;
|
|
94
51
|
export declare function listStoredUsers(): Promise<StoredUser[]>;
|
|
95
|
-
export declare function loadTokenForStoredUser(user: StoredUser): Promise<{
|
|
96
|
-
token: string;
|
|
97
|
-
source: 'secure-store' | 'config-file';
|
|
98
|
-
}>;
|
|
99
52
|
//# sourceMappingURL=auth.d.ts.map
|
package/dist/lib/auth.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../../src/lib/auth.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../../src/lib/auth.ts"],"names":[],"mappings":"AACA,YAAY,EAAE,oBAAoB,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAA;AACpF,OAAO,EACH,eAAe,EACf,cAAc,EACd,aAAa,EACb,UAAU,EACV,WAAW,EACX,KAAK,QAAQ,EACb,KAAK,QAAQ,EACb,KAAK,MAAM,EACX,KAAK,UAAU,EACf,KAAK,aAAa,GACrB,MAAM,aAAa,CAAA;AAGpB,OAAO,EAAE,KAAK,QAAQ,EAAE,KAAK,QAAQ,EAAc,KAAK,UAAU,EAAE,MAAM,aAAa,CAAA;AACvF,OAAO,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAA;AAItC,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAA;AAE/C,MAAM,WAAW,YAAY;IACzB,QAAQ,EAAE,QAAQ,CAAA;IAClB,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,SAAS,CAAC,EAAE,QAAQ,EAAE,CAAA;IACtB,MAAM,EAAE,KAAK,GAAG,cAAc,GAAG,aAAa,CAAA;IAC9C,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,KAAK,CAAC,EAAE,MAAM,CAAA;CACjB;AAED,MAAM,WAAW,YAAY;IACzB,EAAE,EAAE,MAAM,CAAA;IACV,KAAK,EAAE,MAAM,CAAA;IACb,KAAK,EAAE,MAAM,CAAA;IACb,QAAQ,EAAE,QAAQ,CAAA;IAClB,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,SAAS,CAAC,EAAE,QAAQ,EAAE,CAAA;IACtB,MAAM,EAAE,YAAY,CAAC,QAAQ,CAAC,CAAA;CACjC;AAED,qBAAa,YAAa,SAAQ,QAAQ;;CAUzC;AAED;;;;;;;;;GASG;AACH,wBAAsB,iBAAiB,CAAC,IAAI,GAAE;IAAE,GAAG,CAAC,EAAE,MAAM,CAAA;CAAO,GAAG,OAAO,CAAC,YAAY,CAAC,CA8B1F;AAeD,kFAAkF;AAClF,wBAAsB,WAAW,IAAI,OAAO,CAAC,MAAM,CAAC,CAEnD;AAED;;;;GAIG;AACH,wBAAsB,aAAa,IAAI,OAAO,CAAC;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,YAAY,CAAA;CAAE,CAAC,CAGxF;AAED,wBAAsB,eAAe,IAAI,OAAO,CAAC,YAAY,CAAC,CAW7D;AAED,wBAAsB,eAAe,IAAI,OAAO,CAAC,UAAU,EAAE,CAAC,CAE7D"}
|