opencode-account-manager 0.4.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.
Files changed (131) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +266 -0
  3. package/dist/cli.d.ts +3 -0
  4. package/dist/cli.d.ts.map +1 -0
  5. package/dist/cli.js +183 -0
  6. package/dist/cli.js.map +1 -0
  7. package/dist/core/accounts.d.ts +19 -0
  8. package/dist/core/accounts.d.ts.map +1 -0
  9. package/dist/core/accounts.js +181 -0
  10. package/dist/core/accounts.js.map +1 -0
  11. package/dist/core/config-store.d.ts +48 -0
  12. package/dist/core/config-store.d.ts.map +1 -0
  13. package/dist/core/config-store.js +206 -0
  14. package/dist/core/config-store.js.map +1 -0
  15. package/dist/core/crypto.d.ts +40 -0
  16. package/dist/core/crypto.d.ts.map +1 -0
  17. package/dist/core/crypto.js +172 -0
  18. package/dist/core/crypto.js.map +1 -0
  19. package/dist/core/importers/amJson.d.ts +17 -0
  20. package/dist/core/importers/amJson.d.ts.map +1 -0
  21. package/dist/core/importers/amJson.js +131 -0
  22. package/dist/core/importers/amJson.js.map +1 -0
  23. package/dist/core/opencode-config.d.ts +92 -0
  24. package/dist/core/opencode-config.d.ts.map +1 -0
  25. package/dist/core/opencode-config.js +148 -0
  26. package/dist/core/opencode-config.js.map +1 -0
  27. package/dist/core/paths.d.ts +5 -0
  28. package/dist/core/paths.d.ts.map +1 -0
  29. package/dist/core/paths.js +38 -0
  30. package/dist/core/paths.js.map +1 -0
  31. package/dist/core/types.d.ts +74 -0
  32. package/dist/core/types.d.ts.map +1 -0
  33. package/dist/core/types.js +30 -0
  34. package/dist/core/types.js.map +1 -0
  35. package/dist/core/utils.d.ts +5 -0
  36. package/dist/core/utils.d.ts.map +1 -0
  37. package/dist/core/utils.js +35 -0
  38. package/dist/core/utils.js.map +1 -0
  39. package/dist/tui/Dashboard.d.ts +7 -0
  40. package/dist/tui/Dashboard.d.ts.map +1 -0
  41. package/dist/tui/Dashboard.js +331 -0
  42. package/dist/tui/Dashboard.js.map +1 -0
  43. package/dist/tui/components/AccountList.d.ts +18 -0
  44. package/dist/tui/components/AccountList.d.ts.map +1 -0
  45. package/dist/tui/components/AccountList.js +92 -0
  46. package/dist/tui/components/AccountList.js.map +1 -0
  47. package/dist/tui/components/Box.d.ts +11 -0
  48. package/dist/tui/components/Box.d.ts.map +1 -0
  49. package/dist/tui/components/Box.js +15 -0
  50. package/dist/tui/components/Box.js.map +1 -0
  51. package/dist/tui/components/ExportModal.d.ts +10 -0
  52. package/dist/tui/components/ExportModal.d.ts.map +1 -0
  53. package/dist/tui/components/ExportModal.js +192 -0
  54. package/dist/tui/components/ExportModal.js.map +1 -0
  55. package/dist/tui/components/FileBrowser.d.ts +12 -0
  56. package/dist/tui/components/FileBrowser.d.ts.map +1 -0
  57. package/dist/tui/components/FileBrowser.js +349 -0
  58. package/dist/tui/components/FileBrowser.js.map +1 -0
  59. package/dist/tui/components/Header.d.ts +8 -0
  60. package/dist/tui/components/Header.d.ts.map +1 -0
  61. package/dist/tui/components/Header.js +20 -0
  62. package/dist/tui/components/Header.js.map +1 -0
  63. package/dist/tui/components/ImportModal.d.ts +10 -0
  64. package/dist/tui/components/ImportModal.d.ts.map +1 -0
  65. package/dist/tui/components/ImportModal.js +215 -0
  66. package/dist/tui/components/ImportModal.js.map +1 -0
  67. package/dist/tui/components/McpServerList.d.ts +8 -0
  68. package/dist/tui/components/McpServerList.d.ts.map +1 -0
  69. package/dist/tui/components/McpServerList.js +35 -0
  70. package/dist/tui/components/McpServerList.js.map +1 -0
  71. package/dist/tui/components/Menu.d.ts +10 -0
  72. package/dist/tui/components/Menu.d.ts.map +1 -0
  73. package/dist/tui/components/Menu.js +83 -0
  74. package/dist/tui/components/Menu.js.map +1 -0
  75. package/dist/tui/components/PasswordInput.d.ts +12 -0
  76. package/dist/tui/components/PasswordInput.d.ts.map +1 -0
  77. package/dist/tui/components/PasswordInput.js +130 -0
  78. package/dist/tui/components/PasswordInput.js.map +1 -0
  79. package/dist/tui/components/ProviderList.d.ts +8 -0
  80. package/dist/tui/components/ProviderList.d.ts.map +1 -0
  81. package/dist/tui/components/ProviderList.js +37 -0
  82. package/dist/tui/components/ProviderList.js.map +1 -0
  83. package/dist/tui/components/SectionBox.d.ts +10 -0
  84. package/dist/tui/components/SectionBox.d.ts.map +1 -0
  85. package/dist/tui/components/SectionBox.js +16 -0
  86. package/dist/tui/components/SectionBox.js.map +1 -0
  87. package/dist/tui/components/StatsRow.d.ts +13 -0
  88. package/dist/tui/components/StatsRow.d.ts.map +1 -0
  89. package/dist/tui/components/StatsRow.js +18 -0
  90. package/dist/tui/components/StatsRow.js.map +1 -0
  91. package/dist/tui/components/StatusBadge.d.ts +8 -0
  92. package/dist/tui/components/StatusBadge.d.ts.map +1 -0
  93. package/dist/tui/components/StatusBadge.js +30 -0
  94. package/dist/tui/components/StatusBadge.js.map +1 -0
  95. package/dist/tui/components/index.d.ts +14 -0
  96. package/dist/tui/components/index.d.ts.map +1 -0
  97. package/dist/tui/components/index.js +32 -0
  98. package/dist/tui/components/index.js.map +1 -0
  99. package/dist/tui/index.d.ts +5 -0
  100. package/dist/tui/index.d.ts.map +1 -0
  101. package/dist/tui/index.js +13 -0
  102. package/dist/tui/index.js.map +1 -0
  103. package/docs/BLUEPRINT.md +476 -0
  104. package/docs/ROADMAP.md +74 -0
  105. package/package.json +38 -0
  106. package/src/cli.ts +207 -0
  107. package/src/core/accounts.ts +215 -0
  108. package/src/core/config-store.ts +212 -0
  109. package/src/core/crypto.ts +162 -0
  110. package/src/core/importers/amJson.ts +185 -0
  111. package/src/core/opencode-config.ts +217 -0
  112. package/src/core/paths.ts +32 -0
  113. package/src/core/types.ts +118 -0
  114. package/src/core/utils.ts +28 -0
  115. package/src/tui/Dashboard.tsx +431 -0
  116. package/src/tui/components/AccountList.tsx +155 -0
  117. package/src/tui/components/Box.tsx +37 -0
  118. package/src/tui/components/ExportModal.tsx +255 -0
  119. package/src/tui/components/FileBrowser.tsx +393 -0
  120. package/src/tui/components/Header.tsx +26 -0
  121. package/src/tui/components/ImportModal.tsx +288 -0
  122. package/src/tui/components/McpServerList.tsx +67 -0
  123. package/src/tui/components/Menu.tsx +103 -0
  124. package/src/tui/components/PasswordInput.tsx +159 -0
  125. package/src/tui/components/ProviderList.tsx +61 -0
  126. package/src/tui/components/SectionBox.tsx +35 -0
  127. package/src/tui/components/StatsRow.tsx +33 -0
  128. package/src/tui/components/StatusBadge.tsx +33 -0
  129. package/src/tui/components/index.ts +13 -0
  130. package/src/tui/index.tsx +11 -0
  131. package/tsconfig.json +20 -0
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 d-init-d
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,266 @@
1
+ # OpenCode Account Manager (OCAM)
2
+
3
+ TUI Dashboard để quản lý tất cả providers, MCP servers, và plugin accounts của [OpenCode](https://opencode.ai).
4
+
5
+ ## Tính năng
6
+
7
+ ### Dashboard
8
+ - **Providers**: Xem tất cả AI providers (Google, Ollama, Claudible, Antigravity Manager) với số models
9
+ - **MCP Servers**: Xem trạng thái enabled/disabled của các MCP servers
10
+ - **Plugin Accounts**: Quản lý accounts của Antigravity Auth plugin
11
+ - Xem rate limit status theo từng model (claude, gemini)
12
+ - Enable/Disable accounts
13
+ - Xóa accounts
14
+
15
+ ### Export/Import (v0.4.0)
16
+ - **Encrypted Export (.ocam)**: Mã hóa AES-256-GCM với password
17
+ - **Plain JSON Export**: Format không mã hóa (backward compatible)
18
+ - **File Browser**: Chọn nhanh Desktop/Documents, duyệt folder, paste path
19
+ - **Import Preview**: Xem accounts nào đã tồn tại trước khi import
20
+ - **Overwrite Mode**: Accounts trùng sẽ được cập nhật khi import
21
+
22
+ ---
23
+
24
+ ## Cài đặt
25
+
26
+ ### Cách 1: Clone từ GitHub (Recommended)
27
+
28
+ ```bash
29
+ # Clone repo
30
+ git clone https://github.com/d-init-d/opencode-account-manager.git
31
+ cd opencode-account-manager
32
+
33
+ # Cài dependencies
34
+ npm install
35
+
36
+ # Build TypeScript
37
+ npm run build
38
+
39
+ # (Optional) Link để dùng command `ocam` ở mọi nơi
40
+ npm link
41
+ ```
42
+
43
+ ### Cách 2: Cài trực tiếp từ GitHub
44
+
45
+ ```bash
46
+ npm install -g github:d-init-d/opencode-account-manager
47
+ ```
48
+
49
+ ### Kiểm tra cài đặt
50
+
51
+ ```bash
52
+ # Nếu đã npm link hoặc cài global
53
+ ocam --version
54
+
55
+ # Hoặc chạy trực tiếp
56
+ node dist/cli.js --version
57
+ ```
58
+
59
+ ---
60
+
61
+ ## Sử dụng
62
+
63
+ ### Mở Dashboard (TUI)
64
+
65
+ ```bash
66
+ # Cách 1: Command ngắn (nếu đã npm link)
67
+ ocam
68
+
69
+ # Cách 2: Command đầy đủ
70
+ opencode-account-manager
71
+
72
+ # Cách 3: Từ thư mục project
73
+ npm run dashboard
74
+
75
+ # Cách 4: Chạy trực tiếp
76
+ node dist/cli.js dashboard
77
+ ```
78
+
79
+ ### CLI Commands
80
+
81
+ ```bash
82
+ # Xem danh sách accounts
83
+ ocam list
84
+
85
+ # Export accounts ra file JSON
86
+ ocam export -o backup.json
87
+
88
+ # Import accounts từ file
89
+ ocam import backup.json
90
+
91
+ # Import từ Antigravity Manager folder
92
+ ocam import-am
93
+
94
+ # Xem help
95
+ ocam --help
96
+ ```
97
+
98
+ ---
99
+
100
+ ## Phím tắt trong Dashboard
101
+
102
+ ### Main Dashboard
103
+
104
+ | Phím | Chức năng |
105
+ |------|-----------|
106
+ | `Tab` | Chuyển section (Providers → Accounts → MCP) |
107
+ | `R` | Refresh dữ liệu |
108
+ | `E` | Export accounts (mở menu chọn format) |
109
+ | `I` | Import accounts (mở file browser) |
110
+ | `A` | Import từ Antigravity Manager folder |
111
+ | `S` | Bật Select Mode (trong section Accounts) |
112
+ | `Q` | Thoát |
113
+
114
+ ### Select Mode (trong Accounts)
115
+
116
+ | Phím | Chức năng |
117
+ |------|-----------|
118
+ | `↑/↓` | Di chuyển lên/xuống |
119
+ | `Space` | Chọn/bỏ chọn account |
120
+ | `A` | Chọn tất cả |
121
+ | `N` | Bỏ chọn tất cả |
122
+ | `E` | Enable các accounts đã chọn |
123
+ | `D` | Disable các accounts đã chọn |
124
+ | `X` | Export các accounts đã chọn |
125
+ | `DEL` | Xóa các accounts đã chọn |
126
+ | `S` / `Esc` | Thoát Select Mode |
127
+
128
+ ### Export Flow
129
+
130
+ 1. Bấm `E` để export
131
+ 2. Chọn format: `[1] Encrypted (.ocam)` hoặc `[2] Plain JSON`
132
+ 3. Chọn folder lưu file
133
+ 4. Nhập password (chỉ với encrypted)
134
+ 5. Done!
135
+
136
+ ### Import Flow
137
+
138
+ 1. Bấm `I` để import
139
+ 2. Duyệt và chọn file `.ocam` hoặc `.json`
140
+ 3. Nhập password (chỉ với file encrypted)
141
+ 4. Xem preview các accounts
142
+ 5. Bấm `Enter` để confirm import
143
+
144
+ ---
145
+
146
+ ## File Formats
147
+
148
+ ### Encrypted (.ocam)
149
+ - Mã hóa AES-256-GCM với scrypt key derivation
150
+ - Cần password để mở
151
+ - Khuyến nghị dùng khi backup hoặc share
152
+
153
+ ### Plain JSON (.json)
154
+ - Human-readable, không mã hóa
155
+ - Chứa refresh tokens dạng clear text
156
+ - Chỉ nên dùng cho local backup
157
+
158
+ ---
159
+
160
+ ## Các file cấu hình
161
+
162
+ | File | Vị trí | Mô tả |
163
+ |------|--------|-------|
164
+ | `opencode.json` | `~/.config/opencode/` | Config chính của OpenCode (providers, MCP) |
165
+ | `antigravity-accounts.json` | `%APPDATA%/opencode/` | Accounts của plugin (Windows) |
166
+ | `antigravity-accounts.json` | `~/.config/opencode/` | Accounts của plugin (Linux/Mac) |
167
+ | `ocam-config.json` | `%APPDATA%/opencode/` | Preferences của app (recent folders) |
168
+
169
+ ---
170
+
171
+ ## Yêu cầu hệ thống
172
+
173
+ - **Node.js**: >= 16.x
174
+ - **OpenCode**: Cần cài sẵn OpenCode với Antigravity Auth plugin
175
+ - **Terminal**: Hỗ trợ Unicode và 256 colors (Windows Terminal, iTerm2, etc.)
176
+
177
+ ---
178
+
179
+ ## Screenshots
180
+
181
+ ```
182
+ * OpenCode Account Manager - Dashboard
183
+ ────────────────────────────────────────────────────────────────
184
+ Providers Models MCP On MCP Off Accounts Available Limited
185
+ 4 29 6 0 5 3 2
186
+
187
+ Sections: [1] Providers [2] Accounts [3] MCP (Tab to switch)
188
+
189
+ ╭─ PROVIDERS ──────────────────────────────────────────────────╮
190
+ │ PROVIDER MODELS TYPE BASE URL │
191
+ │ Google 7 builtin - │
192
+ │ Ollama 5 custom http://localhost:11434│
193
+ │ Claudible 3 custom https://claudible.io │
194
+ │ Antigravity Manager 14 custom http://localhost:8045 │
195
+ ╰──────────────────────────────────────────────────────────────╯
196
+
197
+ ╭─ PLUGIN ACCOUNTS (opencode-antigravity-auth) ────────────────╮
198
+ │ EMAIL STATUS RATE LIMIT │
199
+ │ user1@gmail.com enabled claude: 2.1h │
200
+ │ user2@gmail.com enabled OK │
201
+ │ user3@gmail.com disabled - │
202
+ ╰──────────────────────────────────────────────────────────────╯
203
+
204
+ ╭─ MCP SERVERS ────────────────────────────────────────────────╮
205
+ │ SERVER STATUS ENV COMMAND │
206
+ │ playwright enabled 0 npx @playwright/mcp │
207
+ │ firecrawl enabled 1 npx firecrawl-mcp │
208
+ │ github enabled 1 npx @modelcontextprot...│
209
+ ╰──────────────────────────────────────────────────────────────╯
210
+
211
+ ┌──────────────────────────────────────────────────────────────┐
212
+ │ [R] Refresh [E] Export [I] Import [A] AM Import [S] Select Mode [Q] Quit │
213
+ └──────────────────────────────────────────────────────────────┘
214
+ ```
215
+
216
+ ---
217
+
218
+ ## Troubleshooting
219
+
220
+ ### Lỗi "command not found: ocam"
221
+
222
+ ```bash
223
+ # Nếu chưa npm link, chạy:
224
+ cd /path/to/opencode-account-manager
225
+ npm link
226
+
227
+ # Hoặc chạy trực tiếp:
228
+ node /path/to/opencode-account-manager/dist/cli.js
229
+ ```
230
+
231
+ ### Lỗi "Cannot find module"
232
+
233
+ ```bash
234
+ # Rebuild project
235
+ npm run build
236
+ ```
237
+
238
+ ### Lỗi "Plugin accounts file not found"
239
+
240
+ Cần đăng nhập ít nhất 1 account trong OpenCode trước:
241
+ ```bash
242
+ opencode auth login
243
+ ```
244
+
245
+ ---
246
+
247
+ ## Documentation
248
+
249
+ - [ROADMAP.md](./docs/ROADMAP.md) - Lịch sử phiên bản và kế hoạch
250
+ - [BLUEPRINT.md](./docs/BLUEPRINT.md) - Kiến trúc kỹ thuật
251
+
252
+ ---
253
+
254
+ ## Contributing
255
+
256
+ 1. Fork repo
257
+ 2. Tạo branch: `git checkout -b feature/ten-tinh-nang`
258
+ 3. Commit: `git commit -m "feat: mô tả"`
259
+ 4. Push: `git push origin feature/ten-tinh-nang`
260
+ 5. Tạo Pull Request
261
+
262
+ ---
263
+
264
+ ## License
265
+
266
+ MIT
package/dist/cli.d.ts ADDED
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env node
2
+ export {};
3
+ //# sourceMappingURL=cli.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":""}
package/dist/cli.js ADDED
@@ -0,0 +1,183 @@
1
+ #!/usr/bin/env node
2
+ "use strict";
3
+ var __importDefault = (this && this.__importDefault) || function (mod) {
4
+ return (mod && mod.__esModule) ? mod : { "default": mod };
5
+ };
6
+ Object.defineProperty(exports, "__esModule", { value: true });
7
+ const fs_1 = __importDefault(require("fs"));
8
+ const commander_1 = require("commander");
9
+ const chalk_1 = __importDefault(require("chalk"));
10
+ const accounts_1 = require("./core/accounts");
11
+ const paths_1 = require("./core/paths");
12
+ const amJson_1 = require("./core/importers/amJson");
13
+ const utils_1 = require("./core/utils");
14
+ const tui_1 = require("./tui");
15
+ function formatTimestamp(timestamp) {
16
+ if (!timestamp)
17
+ return "-";
18
+ return new Date(timestamp).toLocaleString();
19
+ }
20
+ function isLimited(rateLimitResetTimes) {
21
+ if (!rateLimitResetTimes)
22
+ return false;
23
+ const now = Date.now();
24
+ return Object.values(rateLimitResetTimes).some((value) => value > now);
25
+ }
26
+ function safeReadPluginFile(pluginPath) {
27
+ try {
28
+ return (0, accounts_1.readPluginAccountsFile)(pluginPath);
29
+ }
30
+ catch {
31
+ return (0, accounts_1.createEmptyPluginAccountsFile)();
32
+ }
33
+ }
34
+ const program = new commander_1.Command();
35
+ program
36
+ .name("ocam")
37
+ .description("OpenCode Account Manager - TUI dashboard and CLI for managing accounts")
38
+ .version("0.4.0");
39
+ // Default command - show dashboard
40
+ program
41
+ .command("dashboard", { isDefault: true })
42
+ .description("Start the TUI dashboard (default)")
43
+ .option("--plugin-path <path>", "Path to plugin accounts file")
44
+ .action((options) => {
45
+ (0, tui_1.startTuiDashboard)({
46
+ pluginPath: options.pluginPath,
47
+ });
48
+ });
49
+ program
50
+ .command("list")
51
+ .description("List plugin accounts")
52
+ .option("--plugin-path <path>", "Path to plugin accounts file")
53
+ .action((options) => {
54
+ const pluginPath = (0, paths_1.getPluginAccountsPath)(options.pluginPath);
55
+ const file = safeReadPluginFile(pluginPath);
56
+ const summary = (0, accounts_1.summarizeAccounts)(file.accounts);
57
+ console.log(chalk_1.default.bold("=== Account List ===\n"));
58
+ console.log(`Total: ${summary.total} | Available: ${chalk_1.default.green(summary.available)} | Limited: ${chalk_1.default.yellow(summary.limited)}\n`);
59
+ for (const account of file.accounts) {
60
+ const limited = isLimited(account.rateLimitResetTimes);
61
+ const status = limited ? chalk_1.default.yellow("[LIMITED]") : chalk_1.default.green("[ OK ]");
62
+ console.log(`${status} ${account.email}`);
63
+ if (limited && account.rateLimitResetTimes) {
64
+ const now = Date.now();
65
+ for (const [model, resetTime] of Object.entries(account.rateLimitResetTimes)) {
66
+ if (resetTime > now) {
67
+ const hours = ((resetTime - now) / 3600000).toFixed(1);
68
+ console.log(chalk_1.default.gray(` └─ ${model}: ${hours}h`));
69
+ }
70
+ }
71
+ }
72
+ }
73
+ });
74
+ program
75
+ .command("export")
76
+ .description("Export accounts to a portable JSON file")
77
+ .option("--plugin-path <path>", "Path to plugin accounts file")
78
+ .option("-o, --out <path>", "Output file path", `antigravity-export-${Date.now()}.json`)
79
+ .action((options) => {
80
+ const pluginPath = (0, paths_1.getPluginAccountsPath)(options.pluginPath);
81
+ const file = safeReadPluginFile(pluginPath);
82
+ if (file.accounts.length === 0) {
83
+ console.log(chalk_1.default.yellow("No accounts to export."));
84
+ return;
85
+ }
86
+ const exportFile = (0, accounts_1.buildPortableExport)(file.accounts);
87
+ (0, utils_1.writeJsonFile)(options.out, exportFile);
88
+ console.log(chalk_1.default.green(`Exported ${file.accounts.length} accounts to ${options.out}`));
89
+ });
90
+ program
91
+ .command("import")
92
+ .description("Import accounts from file or AM folder")
93
+ .argument("<source>", "Path to JSON file or AM folder (~/.antigravity_tools)")
94
+ .option("--plugin-path <path>", "Path to plugin accounts file")
95
+ .option("-m, --mode <merge|replace>", "Import mode", "merge")
96
+ .action((source, options) => {
97
+ const pluginPath = (0, paths_1.getPluginAccountsPath)(options.pluginPath);
98
+ const mode = options.mode === "replace" ? "replace" : "merge";
99
+ const existingFile = safeReadPluginFile(pluginPath);
100
+ const beforeCount = existingFile.accounts.length;
101
+ let incomingAccounts = [];
102
+ let sourceType = "";
103
+ // Check if source is AM folder
104
+ if (fs_1.default.existsSync(source) && fs_1.default.statSync(source).isDirectory()) {
105
+ if ((0, amJson_1.isAmFolder)(source)) {
106
+ sourceType = "AM folder";
107
+ const result = (0, amJson_1.importFromAmFolder)(source);
108
+ if (result.errors.length > 0) {
109
+ console.log(chalk_1.default.red(`Error: ${result.errors.join(", ")}`));
110
+ return;
111
+ }
112
+ incomingAccounts = result.accounts;
113
+ if (result.skipped.length > 0) {
114
+ console.log(chalk_1.default.gray(`Skipped: ${result.skipped.length} accounts`));
115
+ }
116
+ }
117
+ else {
118
+ console.log(chalk_1.default.red("Directory is not a valid AM folder"));
119
+ return;
120
+ }
121
+ }
122
+ else if (fs_1.default.existsSync(source)) {
123
+ // It's a file
124
+ sourceType = "JSON file";
125
+ try {
126
+ const raw = fs_1.default.readFileSync(source, "utf8");
127
+ const data = JSON.parse(raw);
128
+ incomingAccounts = (0, accounts_1.extractAccountsFromImport)(data);
129
+ }
130
+ catch (err) {
131
+ console.log(chalk_1.default.red(`Failed to parse file: ${err}`));
132
+ return;
133
+ }
134
+ }
135
+ else {
136
+ console.log(chalk_1.default.red(`Source not found: ${source}`));
137
+ return;
138
+ }
139
+ if (incomingAccounts.length === 0) {
140
+ console.log(chalk_1.default.yellow("No valid accounts found in source."));
141
+ return;
142
+ }
143
+ const merged = (0, accounts_1.mergeAccounts)(existingFile, incomingAccounts, mode);
144
+ (0, accounts_1.writePluginAccountsFile)(pluginPath, merged);
145
+ const added = merged.accounts.length - beforeCount;
146
+ console.log(chalk_1.default.green(`\nImport complete!`));
147
+ console.log(`Source: ${sourceType}`);
148
+ console.log(`Mode: ${mode}`);
149
+ console.log(`Found: ${incomingAccounts.length} accounts`);
150
+ console.log(`Added: ${added} new`);
151
+ console.log(`Total: ${merged.accounts.length} accounts`);
152
+ });
153
+ program
154
+ .command("import-am")
155
+ .description("Import accounts from Antigravity Manager")
156
+ .option("--am-path <path>", "Path to AM folder", (0, paths_1.getAmFolderPath)())
157
+ .option("--plugin-path <path>", "Path to plugin accounts file")
158
+ .option("-m, --mode <merge|replace>", "Import mode", "merge")
159
+ .action((options) => {
160
+ const pluginPath = (0, paths_1.getPluginAccountsPath)(options.pluginPath);
161
+ const result = (0, amJson_1.importFromAmFolder)(options.amPath);
162
+ if (result.errors.length > 0) {
163
+ console.log(chalk_1.default.red(`Error: ${result.errors.join(", ")}`));
164
+ return;
165
+ }
166
+ if (result.accounts.length === 0) {
167
+ console.log(chalk_1.default.yellow("No accounts found in AM."));
168
+ if (result.skipped.length > 0) {
169
+ console.log(chalk_1.default.gray(`Skipped: ${result.skipped.join(", ")}`));
170
+ }
171
+ return;
172
+ }
173
+ const mode = options.mode === "replace" ? "replace" : "merge";
174
+ const existingFile = safeReadPluginFile(pluginPath);
175
+ const merged = (0, accounts_1.mergeAccounts)(existingFile, result.accounts, mode);
176
+ (0, accounts_1.writePluginAccountsFile)(pluginPath, merged);
177
+ console.log(chalk_1.default.green(`\nImported from AM!`));
178
+ console.log(`Found: ${result.accounts.length} accounts`);
179
+ console.log(`Skipped: ${result.skipped.length}`);
180
+ console.log(`Total: ${merged.accounts.length} accounts`);
181
+ });
182
+ program.parse();
183
+ //# sourceMappingURL=cli.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";;;;;;AACA,4CAAoB;AAEpB,yCAAoC;AACpC,kDAA0B;AAC1B,8CAQyB;AACzB,wCAAsE;AACtE,oDAAyE;AACzE,wCAA6C;AAC7C,+BAA0C;AAE1C,SAAS,eAAe,CAAC,SAAkB;IACzC,IAAI,CAAC,SAAS;QAAE,OAAO,GAAG,CAAC;IAC3B,OAAO,IAAI,IAAI,CAAC,SAAS,CAAC,CAAC,cAAc,EAAE,CAAC;AAC9C,CAAC;AAED,SAAS,SAAS,CAAC,mBAA4C;IAC7D,IAAI,CAAC,mBAAmB;QAAE,OAAO,KAAK,CAAC;IACvC,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;IACvB,OAAO,MAAM,CAAC,MAAM,CAAC,mBAAmB,CAAC,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,GAAG,GAAG,CAAC,CAAC;AACzE,CAAC;AAED,SAAS,kBAAkB,CAAC,UAAkB;IAC5C,IAAI,CAAC;QACH,OAAO,IAAA,iCAAsB,EAAC,UAAU,CAAC,CAAC;IAC5C,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAA,wCAA6B,GAAE,CAAC;IACzC,CAAC;AACH,CAAC;AAED,MAAM,OAAO,GAAG,IAAI,mBAAO,EAAE,CAAC;AAE9B,OAAO;KACJ,IAAI,CAAC,MAAM,CAAC;KACZ,WAAW,CAAC,wEAAwE,CAAC;KACrF,OAAO,CAAC,OAAO,CAAC,CAAC;AAEpB,mCAAmC;AACnC,OAAO;KACJ,OAAO,CAAC,WAAW,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC;KACzC,WAAW,CAAC,mCAAmC,CAAC;KAChD,MAAM,CAAC,sBAAsB,EAAE,8BAA8B,CAAC;KAC9D,MAAM,CAAC,CAAC,OAAO,EAAE,EAAE;IAClB,IAAA,uBAAiB,EAAC;QAChB,UAAU,EAAE,OAAO,CAAC,UAAU;KAC/B,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEL,OAAO;KACJ,OAAO,CAAC,MAAM,CAAC;KACf,WAAW,CAAC,sBAAsB,CAAC;KACnC,MAAM,CAAC,sBAAsB,EAAE,8BAA8B,CAAC;KAC9D,MAAM,CAAC,CAAC,OAAO,EAAE,EAAE;IAClB,MAAM,UAAU,GAAG,IAAA,6BAAqB,EAAC,OAAO,CAAC,UAAU,CAAC,CAAC;IAC7D,MAAM,IAAI,GAAG,kBAAkB,CAAC,UAAU,CAAC,CAAC;IAC5C,MAAM,OAAO,GAAG,IAAA,4BAAiB,EAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;IAEjD,OAAO,CAAC,GAAG,CAAC,eAAK,CAAC,IAAI,CAAC,wBAAwB,CAAC,CAAC,CAAC;IAClD,OAAO,CAAC,GAAG,CAAC,UAAU,OAAO,CAAC,KAAK,iBAAiB,eAAK,CAAC,KAAK,CAAC,OAAO,CAAC,SAAS,CAAC,eAAe,eAAK,CAAC,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;IAEpI,KAAK,MAAM,OAAO,IAAI,IAAI,CAAC,QAAQ,EAAE,CAAC;QACpC,MAAM,OAAO,GAAG,SAAS,CAAC,OAAO,CAAC,mBAAmB,CAAC,CAAC;QACvD,MAAM,MAAM,GAAG,OAAO,CAAC,CAAC,CAAC,eAAK,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,eAAK,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC;QAC7E,OAAO,CAAC,GAAG,CAAC,GAAG,MAAM,IAAI,OAAO,CAAC,KAAK,EAAE,CAAC,CAAC;QAE1C,IAAI,OAAO,IAAI,OAAO,CAAC,mBAAmB,EAAE,CAAC;YAC3C,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;YACvB,KAAK,MAAM,CAAC,KAAK,EAAE,SAAS,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,mBAAmB,CAAC,EAAE,CAAC;gBAC7E,IAAI,SAAS,GAAG,GAAG,EAAE,CAAC;oBACpB,MAAM,KAAK,GAAG,CAAC,CAAC,SAAS,GAAG,GAAG,CAAC,GAAG,OAAO,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;oBACvD,OAAO,CAAC,GAAG,CAAC,eAAK,CAAC,IAAI,CAAC,gBAAgB,KAAK,KAAK,KAAK,GAAG,CAAC,CAAC,CAAC;gBAC9D,CAAC;YACH,CAAC;QACH,CAAC;IACH,CAAC;AACH,CAAC,CAAC,CAAC;AAEL,OAAO;KACJ,OAAO,CAAC,QAAQ,CAAC;KACjB,WAAW,CAAC,yCAAyC,CAAC;KACtD,MAAM,CAAC,sBAAsB,EAAE,8BAA8B,CAAC;KAC9D,MAAM,CAAC,kBAAkB,EAAE,kBAAkB,EAAE,sBAAsB,IAAI,CAAC,GAAG,EAAE,OAAO,CAAC;KACvF,MAAM,CAAC,CAAC,OAAO,EAAE,EAAE;IAClB,MAAM,UAAU,GAAG,IAAA,6BAAqB,EAAC,OAAO,CAAC,UAAU,CAAC,CAAC;IAC7D,MAAM,IAAI,GAAG,kBAAkB,CAAC,UAAU,CAAC,CAAC;IAE5C,IAAI,IAAI,CAAC,QAAQ,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC/B,OAAO,CAAC,GAAG,CAAC,eAAK,CAAC,MAAM,CAAC,wBAAwB,CAAC,CAAC,CAAC;QACpD,OAAO;IACT,CAAC;IAED,MAAM,UAAU,GAAG,IAAA,8BAAmB,EAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;IACtD,IAAA,qBAAa,EAAC,OAAO,CAAC,GAAG,EAAE,UAAU,CAAC,CAAC;IACvC,OAAO,CAAC,GAAG,CAAC,eAAK,CAAC,KAAK,CAAC,YAAY,IAAI,CAAC,QAAQ,CAAC,MAAM,gBAAgB,OAAO,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC;AAC1F,CAAC,CAAC,CAAC;AAEL,OAAO;KACJ,OAAO,CAAC,QAAQ,CAAC;KACjB,WAAW,CAAC,wCAAwC,CAAC;KACrD,QAAQ,CAAC,UAAU,EAAE,uDAAuD,CAAC;KAC7E,MAAM,CAAC,sBAAsB,EAAE,8BAA8B,CAAC;KAC9D,MAAM,CAAC,4BAA4B,EAAE,aAAa,EAAE,OAAO,CAAC;KAC5D,MAAM,CAAC,CAAC,MAAM,EAAE,OAAO,EAAE,EAAE;IAC1B,MAAM,UAAU,GAAG,IAAA,6BAAqB,EAAC,OAAO,CAAC,UAAU,CAAC,CAAC;IAC7D,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,OAAO,CAAC;IAC9D,MAAM,YAAY,GAAG,kBAAkB,CAAC,UAAU,CAAC,CAAC;IACpD,MAAM,WAAW,GAAG,YAAY,CAAC,QAAQ,CAAC,MAAM,CAAC;IAEjD,IAAI,gBAAgB,GAAU,EAAE,CAAC;IACjC,IAAI,UAAU,GAAG,EAAE,CAAC;IAEpB,+BAA+B;IAC/B,IAAI,YAAE,CAAC,UAAU,CAAC,MAAM,CAAC,IAAI,YAAE,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,WAAW,EAAE,EAAE,CAAC;QAC/D,IAAI,IAAA,mBAAU,EAAC,MAAM,CAAC,EAAE,CAAC;YACvB,UAAU,GAAG,WAAW,CAAC;YACzB,MAAM,MAAM,GAAG,IAAA,2BAAkB,EAAC,MAAM,CAAC,CAAC;YAE1C,IAAI,MAAM,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBAC7B,OAAO,CAAC,GAAG,CAAC,eAAK,CAAC,GAAG,CAAC,UAAU,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC;gBAC7D,OAAO;YACT,CAAC;YAED,gBAAgB,GAAG,MAAM,CAAC,QAAQ,CAAC;YAEnC,IAAI,MAAM,CAAC,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBAC9B,OAAO,CAAC,GAAG,CAAC,eAAK,CAAC,IAAI,CAAC,YAAY,MAAM,CAAC,OAAO,CAAC,MAAM,WAAW,CAAC,CAAC,CAAC;YACxE,CAAC;QACH,CAAC;aAAM,CAAC;YACN,OAAO,CAAC,GAAG,CAAC,eAAK,CAAC,GAAG,CAAC,oCAAoC,CAAC,CAAC,CAAC;YAC7D,OAAO;QACT,CAAC;IACH,CAAC;SAAM,IAAI,YAAE,CAAC,UAAU,CAAC,MAAM,CAAC,EAAE,CAAC;QACjC,cAAc;QACd,UAAU,GAAG,WAAW,CAAC;QACzB,IAAI,CAAC;YACH,MAAM,GAAG,GAAG,YAAE,CAAC,YAAY,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;YAC5C,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;YAC7B,gBAAgB,GAAG,IAAA,oCAAyB,EAAC,IAAI,CAAC,CAAC;QACrD,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,OAAO,CAAC,GAAG,CAAC,eAAK,CAAC,GAAG,CAAC,yBAAyB,GAAG,EAAE,CAAC,CAAC,CAAC;YACvD,OAAO;QACT,CAAC;IACH,CAAC;SAAM,CAAC;QACN,OAAO,CAAC,GAAG,CAAC,eAAK,CAAC,GAAG,CAAC,qBAAqB,MAAM,EAAE,CAAC,CAAC,CAAC;QACtD,OAAO;IACT,CAAC;IAED,IAAI,gBAAgB,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAClC,OAAO,CAAC,GAAG,CAAC,eAAK,CAAC,MAAM,CAAC,oCAAoC,CAAC,CAAC,CAAC;QAChE,OAAO;IACT,CAAC;IAED,MAAM,MAAM,GAAG,IAAA,wBAAa,EAAC,YAAY,EAAE,gBAAgB,EAAE,IAAI,CAAC,CAAC;IACnE,IAAA,kCAAuB,EAAC,UAAU,EAAE,MAAM,CAAC,CAAC;IAE5C,MAAM,KAAK,GAAG,MAAM,CAAC,QAAQ,CAAC,MAAM,GAAG,WAAW,CAAC;IACnD,OAAO,CAAC,GAAG,CAAC,eAAK,CAAC,KAAK,CAAC,oBAAoB,CAAC,CAAC,CAAC;IAC/C,OAAO,CAAC,GAAG,CAAC,WAAW,UAAU,EAAE,CAAC,CAAC;IACrC,OAAO,CAAC,GAAG,CAAC,SAAS,IAAI,EAAE,CAAC,CAAC;IAC7B,OAAO,CAAC,GAAG,CAAC,UAAU,gBAAgB,CAAC,MAAM,WAAW,CAAC,CAAC;IAC1D,OAAO,CAAC,GAAG,CAAC,UAAU,KAAK,MAAM,CAAC,CAAC;IACnC,OAAO,CAAC,GAAG,CAAC,UAAU,MAAM,CAAC,QAAQ,CAAC,MAAM,WAAW,CAAC,CAAC;AAC3D,CAAC,CAAC,CAAC;AAEL,OAAO;KACJ,OAAO,CAAC,WAAW,CAAC;KACpB,WAAW,CAAC,0CAA0C,CAAC;KACvD,MAAM,CAAC,kBAAkB,EAAE,mBAAmB,EAAE,IAAA,uBAAe,GAAE,CAAC;KAClE,MAAM,CAAC,sBAAsB,EAAE,8BAA8B,CAAC;KAC9D,MAAM,CAAC,4BAA4B,EAAE,aAAa,EAAE,OAAO,CAAC;KAC5D,MAAM,CAAC,CAAC,OAAO,EAAE,EAAE;IAClB,MAAM,UAAU,GAAG,IAAA,6BAAqB,EAAC,OAAO,CAAC,UAAU,CAAC,CAAC;IAC7D,MAAM,MAAM,GAAG,IAAA,2BAAkB,EAAC,OAAO,CAAC,MAAM,CAAC,CAAC;IAElD,IAAI,MAAM,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC7B,OAAO,CAAC,GAAG,CAAC,eAAK,CAAC,GAAG,CAAC,UAAU,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC;QAC7D,OAAO;IACT,CAAC;IAED,IAAI,MAAM,CAAC,QAAQ,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACjC,OAAO,CAAC,GAAG,CAAC,eAAK,CAAC,MAAM,CAAC,0BAA0B,CAAC,CAAC,CAAC;QACtD,IAAI,MAAM,CAAC,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAC9B,OAAO,CAAC,GAAG,CAAC,eAAK,CAAC,IAAI,CAAC,YAAY,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC;QACnE,CAAC;QACD,OAAO;IACT,CAAC;IAED,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,OAAO,CAAC;IAC9D,MAAM,YAAY,GAAG,kBAAkB,CAAC,UAAU,CAAC,CAAC;IACpD,MAAM,MAAM,GAAG,IAAA,wBAAa,EAAC,YAAY,EAAE,MAAM,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAC;IAClE,IAAA,kCAAuB,EAAC,UAAU,EAAE,MAAM,CAAC,CAAC;IAE5C,OAAO,CAAC,GAAG,CAAC,eAAK,CAAC,KAAK,CAAC,qBAAqB,CAAC,CAAC,CAAC;IAChD,OAAO,CAAC,GAAG,CAAC,UAAU,MAAM,CAAC,QAAQ,CAAC,MAAM,WAAW,CAAC,CAAC;IACzD,OAAO,CAAC,GAAG,CAAC,YAAY,MAAM,CAAC,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC;IACjD,OAAO,CAAC,GAAG,CAAC,UAAU,MAAM,CAAC,QAAQ,CAAC,MAAM,WAAW,CAAC,CAAC;AAC3D,CAAC,CAAC,CAAC;AAEL,OAAO,CAAC,KAAK,EAAE,CAAC"}
@@ -0,0 +1,19 @@
1
+ import { Account, PluginAccountsFile, PortableExportFile } from "./types";
2
+ export type MergeMode = "merge" | "replace";
3
+ export type ImportFormat = "portable" | "plugin";
4
+ export declare function normalizePluginAccounts(data: PluginAccountsFile): PluginAccountsFile;
5
+ export declare function createEmptyPluginAccountsFile(): PluginAccountsFile;
6
+ export declare function readPluginAccountsFile(filePath?: string): PluginAccountsFile;
7
+ export declare function writePluginAccountsFile(filePath: string | undefined, data: PluginAccountsFile): void;
8
+ export declare function mergeAccount(existing: Account, incoming: Account): Account;
9
+ export declare function mergeAccounts(existingFile: PluginAccountsFile, incomingAccounts: Account[], mode: MergeMode): PluginAccountsFile;
10
+ export declare function buildPortableExport(accounts: Account[]): PortableExportFile;
11
+ export declare function detectImportFormat(data: unknown): ImportFormat | "unknown";
12
+ export declare function extractAccountsFromImport(data: unknown, format?: ImportFormat): Account[];
13
+ export declare function sanitizeAccountForPublic(account: Account): Account;
14
+ export declare function summarizeAccounts(accounts: Account[]): {
15
+ total: number;
16
+ limited: number;
17
+ available: number;
18
+ };
19
+ //# sourceMappingURL=accounts.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"accounts.d.ts","sourceRoot":"","sources":["../../src/core/accounts.ts"],"names":[],"mappings":"AAEA,OAAO,EACL,OAAO,EACP,kBAAkB,EAClB,kBAAkB,EAEnB,MAAM,SAAS,CAAC;AAIjB,MAAM,MAAM,SAAS,GAAG,OAAO,GAAG,SAAS,CAAC;AAC5C,MAAM,MAAM,YAAY,GAAG,UAAU,GAAG,QAAQ,CAAC;AAmBjD,wBAAgB,uBAAuB,CAAC,IAAI,EAAE,kBAAkB,GAAG,kBAAkB,CAcpF;AAED,wBAAgB,6BAA6B,IAAI,kBAAkB,CAOlE;AAED,wBAAgB,sBAAsB,CAAC,QAAQ,CAAC,EAAE,MAAM,GAAG,kBAAkB,CAU5E;AAED,wBAAgB,uBAAuB,CACrC,QAAQ,EAAE,MAAM,GAAG,SAAS,EAC5B,IAAI,EAAE,kBAAkB,GACvB,IAAI,CAQN;AAmBD,wBAAgB,YAAY,CAAC,QAAQ,EAAE,OAAO,EAAE,QAAQ,EAAE,OAAO,GAAG,OAAO,CAgB1E;AAED,wBAAgB,aAAa,CAC3B,YAAY,EAAE,kBAAkB,EAChC,gBAAgB,EAAE,OAAO,EAAE,EAC3B,IAAI,EAAE,SAAS,GACd,kBAAkB,CAkCpB;AAED,wBAAgB,mBAAmB,CAAC,QAAQ,EAAE,OAAO,EAAE,GAAG,kBAAkB,CAO3E;AAED,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,OAAO,GAAG,YAAY,GAAG,SAAS,CAO1E;AAED,wBAAgB,yBAAyB,CACvC,IAAI,EAAE,OAAO,EACb,MAAM,CAAC,EAAE,YAAY,GACpB,OAAO,EAAE,CAaX;AAED,wBAAgB,wBAAwB,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO,CAGlE;AAED,wBAAgB,iBAAiB,CAAC,QAAQ,EAAE,OAAO,EAAE,GAAG;IACtD,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;CACnB,CAaA"}