codeguard-testgen 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/LICENSE +22 -0
- package/README.md +300 -0
- package/bin/testgen.js +17 -0
- package/dist/codebaseIndexer.d.ts +102 -0
- package/dist/codebaseIndexer.d.ts.map +1 -0
- package/dist/codebaseIndexer.js +291 -0
- package/dist/codebaseIndexer.js.map +1 -0
- package/dist/config.d.ts +35 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +104 -0
- package/dist/config.js.map +1 -0
- package/dist/index.d.ts +42 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +2720 -0
- package/dist/index.js.map +1 -0
- package/package.json +57 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 CodeGuard Test Generator
|
|
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.
|
|
22
|
+
|
package/README.md
ADDED
|
@@ -0,0 +1,300 @@
|
|
|
1
|
+
# CodeGuard Test Generator
|
|
2
|
+
|
|
3
|
+
AI-powered unit test generator with AST analysis for TypeScript/JavaScript projects. Automatically generates comprehensive Jest tests using Claude, OpenAI, or Gemini.
|
|
4
|
+
|
|
5
|
+
## Features
|
|
6
|
+
|
|
7
|
+
- 🤖 **AI-Powered**: Uses Claude, OpenAI GPT, or Google Gemini to generate intelligent tests
|
|
8
|
+
- 🔍 **AST Analysis**: Deep code analysis using Babel parser for accurate test generation
|
|
9
|
+
- 📦 **Codebase Indexing**: Optional caching for 100x faster analysis on large projects
|
|
10
|
+
- 🎯 **Multiple Modes**: File-wise, folder-wise, or function-wise test generation
|
|
11
|
+
- ✅ **Smart Validation**: Detects incomplete tests, missing assertions, and legitimate failures
|
|
12
|
+
- 🔄 **Iterative Fixing**: Automatically fixes import errors, missing mocks, and test issues
|
|
13
|
+
- 📋 **TypeScript Support**: Full support for TypeScript types, interfaces, and decorators
|
|
14
|
+
|
|
15
|
+
## Installation
|
|
16
|
+
|
|
17
|
+
### Global Installation (Recommended)
|
|
18
|
+
|
|
19
|
+
```bash
|
|
20
|
+
npm install -g codeguard-testgen
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
### Local Installation
|
|
24
|
+
|
|
25
|
+
```bash
|
|
26
|
+
npm install --save-dev codeguard-testgen
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
## Configuration
|
|
30
|
+
|
|
31
|
+
Create a `codeguard.json` file in your project root:
|
|
32
|
+
|
|
33
|
+
```json
|
|
34
|
+
{
|
|
35
|
+
"aiProvider": "claude",
|
|
36
|
+
"apiKeys": {
|
|
37
|
+
"claude": "sk-ant-api03-...",
|
|
38
|
+
"openai": "sk-...",
|
|
39
|
+
"gemini": "..."
|
|
40
|
+
},
|
|
41
|
+
"models": {
|
|
42
|
+
"claude": "claude-sonnet-4-5-20250929",
|
|
43
|
+
"openai": "gpt-5-mini",
|
|
44
|
+
"gemini": "gemini-2.0-flash-lite"
|
|
45
|
+
},
|
|
46
|
+
"testDir": "src/tests",
|
|
47
|
+
"extensions": [".ts", ".tsx", ".js", ".jsx"],
|
|
48
|
+
"excludeDirs": ["node_modules", "dist", "build", ".git", "coverage"]
|
|
49
|
+
}
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
### Configuration Options
|
|
53
|
+
|
|
54
|
+
| Option | Required | Description |
|
|
55
|
+
|--------|----------|-------------|
|
|
56
|
+
| `aiProvider` | Yes | AI provider to use: `claude`, `openai`, or `gemini` |
|
|
57
|
+
| `apiKeys` | Yes | API keys for the AI providers |
|
|
58
|
+
| `models` | No | Custom model names (uses defaults if not specified) |
|
|
59
|
+
| `testDir` | No | Directory for test files (default: `src/tests`) |
|
|
60
|
+
| `extensions` | No | File extensions to process (default: `.ts`, `.tsx`, `.js`, `.jsx`) |
|
|
61
|
+
| `excludeDirs` | No | Directories to exclude from scanning |
|
|
62
|
+
|
|
63
|
+
### Getting API Keys
|
|
64
|
+
|
|
65
|
+
- **Claude (Anthropic)**: https://console.anthropic.com/
|
|
66
|
+
- **OpenAI**: https://platform.openai.com/api-keys
|
|
67
|
+
- **Gemini (Google)**: https://makersuite.google.com/app/apikey
|
|
68
|
+
|
|
69
|
+
## Usage
|
|
70
|
+
|
|
71
|
+
### Interactive Mode
|
|
72
|
+
|
|
73
|
+
Simply run the command and follow the prompts:
|
|
74
|
+
|
|
75
|
+
```bash
|
|
76
|
+
testgen
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
or
|
|
80
|
+
|
|
81
|
+
```bash
|
|
82
|
+
codeguard
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
You'll be guided through:
|
|
86
|
+
1. Selecting test generation mode (file/folder/function-wise)
|
|
87
|
+
2. Choosing files or functions to test
|
|
88
|
+
3. Optional codebase indexing for faster processing
|
|
89
|
+
|
|
90
|
+
### Test Generation Modes
|
|
91
|
+
|
|
92
|
+
#### 1. File-wise Mode
|
|
93
|
+
Generate tests for a single file:
|
|
94
|
+
- Select from a list of source files
|
|
95
|
+
- Generates comprehensive tests for all exported functions
|
|
96
|
+
- Creates test file with proper structure and mocks
|
|
97
|
+
|
|
98
|
+
#### 2. Folder-wise Mode
|
|
99
|
+
Generate tests for all files in a directory:
|
|
100
|
+
- Select a folder from your project
|
|
101
|
+
- Processes all matching files recursively
|
|
102
|
+
- Batch generates tests with progress tracking
|
|
103
|
+
|
|
104
|
+
#### 3. Function-wise Mode
|
|
105
|
+
Generate tests for specific functions:
|
|
106
|
+
- Select a file
|
|
107
|
+
- Choose which functions to test
|
|
108
|
+
- Preserves existing tests for other functions
|
|
109
|
+
- Ideal for incremental test development
|
|
110
|
+
|
|
111
|
+
## How It Works
|
|
112
|
+
|
|
113
|
+
1. **AST Analysis**: Parses your code using Babel to understand structure
|
|
114
|
+
2. **Dependency Resolution**: Analyzes imports and calculates correct paths
|
|
115
|
+
3. **AI Generation**: Uses AI to generate comprehensive test cases
|
|
116
|
+
4. **Validation**: Checks for completeness, assertions, and coverage
|
|
117
|
+
5. **Execution**: Runs tests with Jest to verify correctness
|
|
118
|
+
6. **Iterative Fixing**: Automatically fixes common issues like:
|
|
119
|
+
- Import path errors
|
|
120
|
+
- Missing mocks
|
|
121
|
+
- Database initialization errors
|
|
122
|
+
- Type mismatches
|
|
123
|
+
7. **Failure Detection**: Distinguishes between test bugs and source code bugs
|
|
124
|
+
|
|
125
|
+
## Generated Test Features
|
|
126
|
+
|
|
127
|
+
The AI generates tests with:
|
|
128
|
+
|
|
129
|
+
- ✅ Proper imports and type definitions
|
|
130
|
+
- ✅ Jest mocks for dependencies
|
|
131
|
+
- ✅ Multiple test cases per function:
|
|
132
|
+
- Happy path scenarios
|
|
133
|
+
- Edge cases (null, undefined, empty arrays)
|
|
134
|
+
- Error conditions
|
|
135
|
+
- Async behavior testing
|
|
136
|
+
- ✅ Clear, descriptive test names
|
|
137
|
+
- ✅ Complete implementations (no placeholder comments)
|
|
138
|
+
- ✅ Real assertions with expect() statements
|
|
139
|
+
|
|
140
|
+
## Advanced Features
|
|
141
|
+
|
|
142
|
+
### Codebase Indexing
|
|
143
|
+
|
|
144
|
+
On first run, you'll be prompted to enable codebase indexing:
|
|
145
|
+
|
|
146
|
+
```
|
|
147
|
+
Enable codebase indexing? (y/n)
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
Benefits:
|
|
151
|
+
- 100x+ faster analysis on subsequent runs
|
|
152
|
+
- Instant dependency lookups
|
|
153
|
+
- Cached AST parsing
|
|
154
|
+
- Automatic update detection
|
|
155
|
+
|
|
156
|
+
The index is stored in `.codeguard-cache/` and automatically updates when files change.
|
|
157
|
+
|
|
158
|
+
### Legitimate Failure Detection
|
|
159
|
+
|
|
160
|
+
The tool distinguishes between:
|
|
161
|
+
|
|
162
|
+
**Fixable Test Issues** (automatically fixed):
|
|
163
|
+
- Wrong import paths
|
|
164
|
+
- Missing mocks
|
|
165
|
+
- Incorrect assertions
|
|
166
|
+
- TypeScript errors
|
|
167
|
+
|
|
168
|
+
**Legitimate Source Code Bugs** (reported, not fixed):
|
|
169
|
+
- Function returns wrong type
|
|
170
|
+
- Missing null checks
|
|
171
|
+
- Logic errors
|
|
172
|
+
- Unhandled edge cases
|
|
173
|
+
|
|
174
|
+
When legitimate bugs are found, they're reported with details for you to fix in the source code.
|
|
175
|
+
|
|
176
|
+
## Examples
|
|
177
|
+
|
|
178
|
+
### Example: Testing a User Service
|
|
179
|
+
|
|
180
|
+
```typescript
|
|
181
|
+
// src/services/user.service.ts
|
|
182
|
+
export class UserService {
|
|
183
|
+
async getUser(id: string): Promise<User> {
|
|
184
|
+
return await this.db.findUser(id);
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
```
|
|
188
|
+
|
|
189
|
+
Generated test:
|
|
190
|
+
|
|
191
|
+
```typescript
|
|
192
|
+
// src/tests/services/user.service.test.ts
|
|
193
|
+
import { UserService } from '../../services/user.service';
|
|
194
|
+
|
|
195
|
+
jest.mock('../../database');
|
|
196
|
+
|
|
197
|
+
describe('UserService', () => {
|
|
198
|
+
describe('getUser', () => {
|
|
199
|
+
test('should return user when id exists', async () => {
|
|
200
|
+
const mockUser = { id: '123', name: 'John' };
|
|
201
|
+
const service = new UserService();
|
|
202
|
+
service.db.findUser = jest.fn().mockResolvedValue(mockUser);
|
|
203
|
+
|
|
204
|
+
const result = await service.getUser('123');
|
|
205
|
+
|
|
206
|
+
expect(result).toEqual(mockUser);
|
|
207
|
+
expect(service.db.findUser).toHaveBeenCalledWith('123');
|
|
208
|
+
});
|
|
209
|
+
|
|
210
|
+
test('should handle null id', async () => {
|
|
211
|
+
const service = new UserService();
|
|
212
|
+
await expect(service.getUser(null)).rejects.toThrow();
|
|
213
|
+
});
|
|
214
|
+
});
|
|
215
|
+
});
|
|
216
|
+
```
|
|
217
|
+
|
|
218
|
+
## Troubleshooting
|
|
219
|
+
|
|
220
|
+
### "Configuration Error: codeguard.json not found"
|
|
221
|
+
|
|
222
|
+
Create a `codeguard.json` file in your project root. See Configuration section above.
|
|
223
|
+
|
|
224
|
+
### "API key not configured"
|
|
225
|
+
|
|
226
|
+
Ensure your `codeguard.json` has the correct API key for your selected provider:
|
|
227
|
+
|
|
228
|
+
```json
|
|
229
|
+
{
|
|
230
|
+
"aiProvider": "claude",
|
|
231
|
+
"apiKeys": {
|
|
232
|
+
"claude": "sk-ant-..."
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
```
|
|
236
|
+
|
|
237
|
+
### Tests fail with import errors
|
|
238
|
+
|
|
239
|
+
The tool automatically detects and fixes import path errors. If issues persist:
|
|
240
|
+
1. Check that all dependencies are installed
|
|
241
|
+
2. Verify your project structure matches expected paths
|
|
242
|
+
3. Ensure TypeScript is configured correctly
|
|
243
|
+
|
|
244
|
+
### "Missing required packages"
|
|
245
|
+
|
|
246
|
+
Install Babel dependencies:
|
|
247
|
+
|
|
248
|
+
```bash
|
|
249
|
+
npm install --save-dev @babel/parser @babel/traverse
|
|
250
|
+
```
|
|
251
|
+
|
|
252
|
+
## Programmatic Usage
|
|
253
|
+
|
|
254
|
+
You can also use CodeGuard as a library:
|
|
255
|
+
|
|
256
|
+
```typescript
|
|
257
|
+
import { generateTests, analyzeFileAST } from 'codeguard-testgen';
|
|
258
|
+
|
|
259
|
+
// Generate tests for a file
|
|
260
|
+
await generateTests('src/services/user.service.ts');
|
|
261
|
+
|
|
262
|
+
// Analyze a file's AST
|
|
263
|
+
const analysis = analyzeFileAST('src/utils/helpers.ts');
|
|
264
|
+
console.log(analysis.functions);
|
|
265
|
+
```
|
|
266
|
+
|
|
267
|
+
## Project Structure
|
|
268
|
+
|
|
269
|
+
After installation, your project will have:
|
|
270
|
+
|
|
271
|
+
```
|
|
272
|
+
your-project/
|
|
273
|
+
├── codeguard.json # Configuration file
|
|
274
|
+
├── src/
|
|
275
|
+
│ ├── services/
|
|
276
|
+
│ │ └── user.service.ts
|
|
277
|
+
│ └── tests/ # Generated tests
|
|
278
|
+
│ └── services/
|
|
279
|
+
│ └── user.service.test.ts
|
|
280
|
+
└── .codeguard-cache/ # Optional index cache
|
|
281
|
+
```
|
|
282
|
+
|
|
283
|
+
## Requirements
|
|
284
|
+
|
|
285
|
+
- Node.js >= 16.0.0
|
|
286
|
+
- Jest (for running generated tests)
|
|
287
|
+
- TypeScript (for TypeScript projects)
|
|
288
|
+
|
|
289
|
+
## License
|
|
290
|
+
|
|
291
|
+
MIT
|
|
292
|
+
|
|
293
|
+
## Contributing
|
|
294
|
+
|
|
295
|
+
Contributions welcome! Please open an issue or submit a pull request.
|
|
296
|
+
|
|
297
|
+
## Support
|
|
298
|
+
|
|
299
|
+
For issues, questions, or feature requests, please open an issue on GitHub.
|
|
300
|
+
|
package/bin/testgen.js
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* CodeGuard Test Generator CLI Entry Point
|
|
5
|
+
*
|
|
6
|
+
* This is the executable entry point for the npm package.
|
|
7
|
+
* It loads the compiled TypeScript code from dist/ and runs the main function.
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
const { main } = require('../dist/index.js');
|
|
11
|
+
|
|
12
|
+
// Run the main function and handle errors
|
|
13
|
+
main().catch((error) => {
|
|
14
|
+
console.error('Error:', error.message);
|
|
15
|
+
process.exit(1);
|
|
16
|
+
});
|
|
17
|
+
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Codebase Indexer - Caches AST analysis for faster test generation
|
|
3
|
+
*
|
|
4
|
+
* This is completely optional. Test generation works fine without it,
|
|
5
|
+
* but indexing provides significant speed improvements.
|
|
6
|
+
*/
|
|
7
|
+
interface FunctionInfo {
|
|
8
|
+
name: string;
|
|
9
|
+
type: string;
|
|
10
|
+
exported: boolean;
|
|
11
|
+
async: boolean;
|
|
12
|
+
params: any[];
|
|
13
|
+
returnType: string | null;
|
|
14
|
+
line: number;
|
|
15
|
+
}
|
|
16
|
+
interface ClassInfo {
|
|
17
|
+
name: string;
|
|
18
|
+
exported: boolean;
|
|
19
|
+
methods: any[];
|
|
20
|
+
line: number;
|
|
21
|
+
}
|
|
22
|
+
interface ImportInfo {
|
|
23
|
+
source: string;
|
|
24
|
+
imported: any[];
|
|
25
|
+
line: number;
|
|
26
|
+
}
|
|
27
|
+
interface FileAnalysis {
|
|
28
|
+
functions: FunctionInfo[];
|
|
29
|
+
classes: ClassInfo[];
|
|
30
|
+
imports: ImportInfo[];
|
|
31
|
+
exports: any[];
|
|
32
|
+
types: any[];
|
|
33
|
+
constants: any[];
|
|
34
|
+
}
|
|
35
|
+
export declare class CodebaseIndexer {
|
|
36
|
+
private indexPath;
|
|
37
|
+
private indexFile;
|
|
38
|
+
private index;
|
|
39
|
+
private version;
|
|
40
|
+
constructor();
|
|
41
|
+
/**
|
|
42
|
+
* Check if index exists and is valid
|
|
43
|
+
*/
|
|
44
|
+
hasIndex(): boolean;
|
|
45
|
+
/**
|
|
46
|
+
* Load index from disk
|
|
47
|
+
*/
|
|
48
|
+
loadIndex(): Promise<boolean>;
|
|
49
|
+
/**
|
|
50
|
+
* Build complete index from scratch
|
|
51
|
+
*/
|
|
52
|
+
buildIndex(rootDir: string, analyzeFileFn: (filePath: string) => any, progressCallback?: (current: number, total: number, file: string) => void): Promise<void>;
|
|
53
|
+
/**
|
|
54
|
+
* Update index for changed files only
|
|
55
|
+
*/
|
|
56
|
+
updateIndex(changedFiles: string[], analyzeFileFn: (filePath: string) => any): Promise<void>;
|
|
57
|
+
/**
|
|
58
|
+
* Save index to disk
|
|
59
|
+
*/
|
|
60
|
+
private saveIndex;
|
|
61
|
+
/**
|
|
62
|
+
* Get cached file analysis
|
|
63
|
+
*/
|
|
64
|
+
getFileAnalysis(filePath: string): FileAnalysis | null;
|
|
65
|
+
/**
|
|
66
|
+
* Check if file needs re-indexing
|
|
67
|
+
*/
|
|
68
|
+
isFileStale(filePath: string): boolean;
|
|
69
|
+
/**
|
|
70
|
+
* Get files that need re-indexing
|
|
71
|
+
*/
|
|
72
|
+
getStaleFiles(): string[];
|
|
73
|
+
/**
|
|
74
|
+
* Get index statistics
|
|
75
|
+
*/
|
|
76
|
+
getStats(): {
|
|
77
|
+
version: string;
|
|
78
|
+
fileCount: number;
|
|
79
|
+
functionCount: number;
|
|
80
|
+
testCount: number;
|
|
81
|
+
createdAt: string;
|
|
82
|
+
lastUpdated: string;
|
|
83
|
+
};
|
|
84
|
+
/**
|
|
85
|
+
* Clear index cache
|
|
86
|
+
*/
|
|
87
|
+
clearCache(): Promise<void>;
|
|
88
|
+
/**
|
|
89
|
+
* Get all source files recursively
|
|
90
|
+
*/
|
|
91
|
+
private getAllSourceFiles;
|
|
92
|
+
/**
|
|
93
|
+
* Find corresponding test file for a source file
|
|
94
|
+
*/
|
|
95
|
+
private findTestFile;
|
|
96
|
+
/**
|
|
97
|
+
* Calculate file hash
|
|
98
|
+
*/
|
|
99
|
+
private calculateHash;
|
|
100
|
+
}
|
|
101
|
+
export {};
|
|
102
|
+
//# sourceMappingURL=codebaseIndexer.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"codebaseIndexer.d.ts","sourceRoot":"","sources":["../src/codebaseIndexer.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAcH,UAAU,YAAY;IACpB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,OAAO,CAAC;IAClB,KAAK,EAAE,OAAO,CAAC;IACf,MAAM,EAAE,GAAG,EAAE,CAAC;IACd,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,IAAI,EAAE,MAAM,CAAC;CACd;AAED,UAAU,SAAS;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,OAAO,CAAC;IAClB,OAAO,EAAE,GAAG,EAAE,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;CACd;AAED,UAAU,UAAU;IAClB,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,GAAG,EAAE,CAAC;IAChB,IAAI,EAAE,MAAM,CAAC;CACd;AAED,UAAU,YAAY;IACpB,SAAS,EAAE,YAAY,EAAE,CAAC;IAC1B,OAAO,EAAE,SAAS,EAAE,CAAC;IACrB,OAAO,EAAE,UAAU,EAAE,CAAC;IACtB,OAAO,EAAE,GAAG,EAAE,CAAC;IACf,KAAK,EAAE,GAAG,EAAE,CAAC;IACb,SAAS,EAAE,GAAG,EAAE,CAAC;CAClB;AAiBD,qBAAa,eAAe;IAC1B,OAAO,CAAC,SAAS,CAA8B;IAC/C,OAAO,CAAC,SAAS,CAAyC;IAC1D,OAAO,CAAC,KAAK,CAA8B;IAC3C,OAAO,CAAC,OAAO,CAAmB;;IASlC;;OAEG;IACH,QAAQ,IAAI,OAAO;IAInB;;OAEG;IACG,SAAS,IAAI,OAAO,CAAC,OAAO,CAAC;IAwBnC;;OAEG;IACG,UAAU,CACd,OAAO,EAAE,MAAM,EACf,aAAa,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,GAAG,EACxC,gBAAgB,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,KAAK,IAAI,GACxE,OAAO,CAAC,IAAI,CAAC;IA8DhB;;OAEG;IACG,WAAW,CACf,YAAY,EAAE,MAAM,EAAE,EACtB,aAAa,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,GAAG,GACvC,OAAO,CAAC,IAAI,CAAC;IAqChB;;OAEG;YACW,SAAS;IAYvB;;OAEG;IACH,eAAe,CAAC,QAAQ,EAAE,MAAM,GAAG,YAAY,GAAG,IAAI;IAQtD;;OAEG;IACH,WAAW,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO;IAgBtC;;OAEG;IACH,aAAa,IAAI,MAAM,EAAE;IAezB;;OAEG;IACH,QAAQ;;;;;;;;IAsBR;;OAEG;IACG,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;IAQjC;;OAEG;YACW,iBAAiB;IAgC/B;;OAEG;IACH,OAAO,CAAC,YAAY;IAkCpB;;OAEG;IACH,OAAO,CAAC,aAAa;CAGtB"}
|