@npm7381/agent-doc-generator 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.
Files changed (47) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +75 -0
  3. package/dist/index.d.ts +3 -0
  4. package/dist/index.d.ts.map +1 -0
  5. package/dist/index.js +299 -0
  6. package/dist/index.js.map +1 -0
  7. package/dist/src/aiClient.d.ts +38 -0
  8. package/dist/src/aiClient.d.ts.map +1 -0
  9. package/dist/src/aiClient.js +180 -0
  10. package/dist/src/aiClient.js.map +1 -0
  11. package/dist/src/cache.d.ts +7 -0
  12. package/dist/src/cache.d.ts.map +1 -0
  13. package/dist/src/cache.js +50 -0
  14. package/dist/src/cache.js.map +1 -0
  15. package/dist/src/configLoader.d.ts +15 -0
  16. package/dist/src/configLoader.d.ts.map +1 -0
  17. package/dist/src/configLoader.js +26 -0
  18. package/dist/src/configLoader.js.map +1 -0
  19. package/dist/src/docGenerator.d.ts +7 -0
  20. package/dist/src/docGenerator.d.ts.map +1 -0
  21. package/dist/src/docGenerator.js +68 -0
  22. package/dist/src/docGenerator.js.map +1 -0
  23. package/dist/src/fileProcessor.d.ts +10 -0
  24. package/dist/src/fileProcessor.d.ts.map +1 -0
  25. package/dist/src/fileProcessor.js +115 -0
  26. package/dist/src/fileProcessor.js.map +1 -0
  27. package/dist/src/htmlFormatter.d.ts +2 -0
  28. package/dist/src/htmlFormatter.d.ts.map +1 -0
  29. package/dist/src/htmlFormatter.js +54 -0
  30. package/dist/src/htmlFormatter.js.map +1 -0
  31. package/dist/src/pdfFormatter.d.ts +2 -0
  32. package/dist/src/pdfFormatter.d.ts.map +1 -0
  33. package/dist/src/pdfFormatter.js +44 -0
  34. package/dist/src/pdfFormatter.js.map +1 -0
  35. package/dist/src/prompts.d.ts +3 -0
  36. package/dist/src/prompts.d.ts.map +1 -0
  37. package/dist/src/prompts.js +83 -0
  38. package/dist/src/prompts.js.map +1 -0
  39. package/dist/src/providerDetector.d.ts +20 -0
  40. package/dist/src/providerDetector.d.ts.map +1 -0
  41. package/dist/src/providerDetector.js +145 -0
  42. package/dist/src/providerDetector.js.map +1 -0
  43. package/dist/src/types.d.ts +35 -0
  44. package/dist/src/types.d.ts.map +1 -0
  45. package/dist/src/types.js +2 -0
  46. package/dist/src/types.js.map +1 -0
  47. package/package.json +45 -0
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Marcelo Adán
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,75 @@
1
+ # agent-doc-generator
2
+
3
+ Genera documentación JSDoc automática usando IA.
4
+
5
+ ## Instalación
6
+
7
+ ```bash
8
+ # Global
9
+ npm install -g agent-doc-generator
10
+
11
+ # O sin instalar
12
+ npx agent-doc-generator --path ./src
13
+ ```
14
+
15
+ ## Uso
16
+
17
+ ```bash
18
+ agent-doc-generator --path ./src # documentación de todo src/
19
+ agent-doc-generator --path ./src/utils.ts # un solo archivo
20
+ agent-doc-generator --path ./src --split # un DOCS.md por archivo
21
+ agent-doc-generator --path ./src --format html # salida HTML
22
+ agent-doc-generator --path ./src --extensions .ts,.prisma # solo archivos .ts y .prisma
23
+ agent-doc-generator --path ./src --dry-run # preview sin escribir
24
+ agent-doc-generator --path ./src --verbose # logs detallados
25
+ ```
26
+
27
+ ## Proveedores
28
+
29
+ | Provider | Modelo Default | Auth | Notas |
30
+ |----------|---------------|------|-------|
31
+ | gemini | `gemini-2.5-flash` | `GEMINI_API_KEY` | Free tier disponible |
32
+ | openai | `gpt-4o` | `OPENAI_API_KEY` | GPT-4o, GPT-4o-mini |
33
+ | anthropic | `claude-sonnet-4-20250514` | `ANTHROPIC_API_KEY` | Claude |
34
+ | deepseek | `deepseek-chat` | `DEEPSEEK_API_KEY` | El más barato |
35
+ | ollama | modelo instalado | Sin key | Local, gratis, privacidad |
36
+
37
+ **Auto-detección**: Si no especificas `--provider`, detecta automáticamente qué tienes configurado (keys en `.env` o Ollama corriendo).
38
+
39
+ ## Flags
40
+
41
+ | Flag | Descripción | Default |
42
+ |------|-------------|---------|
43
+ | `--path` | Archivo o carpeta a procesar | (requerido) |
44
+ | `--provider` | `gemini` \| `openai` \| `anthropic` \| `deepseek` \| `ollama` | auto-detectado |
45
+ | `--model` | Modelo a usar | según provider |
46
+ | `--base-url` | URL del servidor (Ollama) | `http://localhost:11434` |
47
+ | `--api-key` | API key (opcional para Ollama) | .env |
48
+ | `--max-chars` | Límite de chars por archivo | 15000 |
49
+ | `--output` | Carpeta/archivo de salida | junto al archivo |
50
+ | `--extensions` | Extensiones a procesar (CSV: `.ts,.prisma`) | todas |
51
+ | `--split` | Un archivo por cada fuente | false |
52
+ | `--format` | Formato de salida `terminal` \| `markdown` \| `html` \| `pdf` | terminal |
53
+ | `--dry-run` | Solo preview, no escribir | false |
54
+ | `--verbose` | Logs detallados | false |
55
+
56
+ ## Features
57
+
58
+ - **Modo single** (default): genera un único `DOCS.md`
59
+ - **Modo split** (`--split`): genera `.docs.md` por cada fuente
60
+ - **Cache**: hash MD5 para no regenerar archivos sin cambios
61
+ - **Auto-detección**: detecta provider disponible al iniciar
62
+ - **Resiliencia**: 3 reintentos con backoff ante errores de API
63
+ - **Truncado**: archivos > `--max-chars` se recortan con aviso
64
+ - **Filtro por extensión**: `--extensions .ts,.prisma` para limitar tipos de archivo
65
+
66
+ ## Requisitos
67
+
68
+ - Node.js >= 18
69
+ - Un proveedor de IA configurado (API key o Ollama local)
70
+
71
+ ## Licencia
72
+
73
+ MIT
74
+
75
+ Parte de [AI Agent Toolkit](https://github.com/MarceloAdan73/ai-agent-toolkit).
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env node
2
+ export {};
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../index.ts"],"names":[],"mappings":""}
package/dist/index.js ADDED
@@ -0,0 +1,299 @@
1
+ #!/usr/bin/env node
2
+ import { Command } from 'commander';
3
+ import dotenv from 'dotenv';
4
+ import fs from 'fs';
5
+ import path from 'path';
6
+ import { fileURLToPath } from 'url';
7
+ import ora from 'ora';
8
+ import { collectFiles, readFile, writeDocFile, writeSingleDocFile, shouldSkipContent } from './src/fileProcessor.js';
9
+ import { createAIClient, generateDocumentation, extractDocContent } from './src/docGenerator.js';
10
+ import { loadCache, saveCache, computeFileHash, isFileCached, updateCache } from './src/cache.js';
11
+ import { detectProvider, loadConfig, saveConfig, printDetectionResult } from './src/providerDetector.js';
12
+ import { loadConfigFile, mergeConfig } from './src/configLoader.js';
13
+ import { generateHtmlFromContent } from './src/htmlFormatter.js';
14
+ import { generatePdfFromContent } from './src/pdfFormatter.js';
15
+ const __dirname = path.dirname(fileURLToPath(import.meta.url));
16
+ dotenv.config({ path: path.join(__dirname, '.env') });
17
+ const program = new Command();
18
+ program
19
+ .name('agent-doc-generator')
20
+ .description('AI-powered documentation generator')
21
+ .version('2.1.0')
22
+ .requiredOption('--path <path>', 'Path to file or directory to document')
23
+ .option('--model <model>', 'AI model to use (auto-detected if not set)')
24
+ .option('--provider <provider>', 'AI provider: gemini | openai | anthropic | deepseek | ollama')
25
+ .option('--base-url <url>', 'Base URL for Ollama provider')
26
+ .option('--api-key <key>', 'API key (optional for Ollama)')
27
+ .option('--max-chars <n>', 'Maximum characters per file (default: 15000)', (val) => parseInt(val, 10))
28
+ .option('--output <dir>', 'Output directory for documentation files')
29
+ .option('--format <format>', 'Output format: markdown | html | pdf', 'markdown')
30
+ .option('--split', 'Generate one .docs.md file per source file (default: single DOCS.md)')
31
+ .option('--dry-run', 'Preview what would be generated without writing files')
32
+ .option('--extensions <extensions>', 'File extensions to process (comma-separated, e.g. .ts,.prisma)')
33
+ .option('--verbose', 'Show detailed logs')
34
+ .parse(process.argv);
35
+ const options = program.opts();
36
+ const rcConfig = loadConfigFile(process.cwd());
37
+ async function resolveProvider() {
38
+ if (options.provider) {
39
+ return {
40
+ provider: options.provider,
41
+ model: options.model ?? getDefaultModelForProvider(options.provider),
42
+ apiKey: options.apiKey,
43
+ baseUrl: options.baseUrl,
44
+ };
45
+ }
46
+ if (rcConfig?.provider) {
47
+ return {
48
+ provider: rcConfig.provider,
49
+ model: options.model ?? rcConfig.model ?? getDefaultModelForProvider(rcConfig.provider),
50
+ baseUrl: options.baseUrl ?? rcConfig.baseUrl,
51
+ };
52
+ }
53
+ const projectRoot = process.cwd();
54
+ const savedConfig = loadConfig(projectRoot);
55
+ if (savedConfig) {
56
+ return {
57
+ provider: savedConfig.provider,
58
+ model: options.model ?? savedConfig.model,
59
+ baseUrl: savedConfig.baseUrl,
60
+ };
61
+ }
62
+ const detected = await detectProvider({ projectRoot });
63
+ if (detected) {
64
+ saveConfig(projectRoot, detected);
65
+ return {
66
+ provider: detected.provider,
67
+ model: options.model ?? detected.model,
68
+ baseUrl: detected.baseUrl,
69
+ };
70
+ }
71
+ return { provider: 'gemini', model: options.model ?? 'gemini-2.5-flash' };
72
+ }
73
+ function getDefaultModelForProvider(provider) {
74
+ const defaults = {
75
+ gemini: 'gemini-2.5-flash',
76
+ openai: 'gpt-4o',
77
+ anthropic: 'claude-sonnet-4-20250514',
78
+ deepseek: 'deepseek-chat',
79
+ ollama: 'llama3',
80
+ };
81
+ return defaults[provider] ?? 'gemini-2.5-flash';
82
+ }
83
+ function getApiKeyForProvider(provider) {
84
+ const envKeyMap = {
85
+ gemini: 'GEMINI_API_KEY',
86
+ openai: 'OPENAI_API_KEY',
87
+ anthropic: 'ANTHROPIC_API_KEY',
88
+ deepseek: 'DEEPSEEK_API_KEY',
89
+ };
90
+ const envKey = envKeyMap[provider];
91
+ return envKey ? process.env[envKey] : undefined;
92
+ }
93
+ async function main() {
94
+ const verbose = mergeConfig(options.verbose, rcConfig?.verbose, false);
95
+ const dryRun = mergeConfig(options.dryRun, rcConfig?.dryRun, false);
96
+ const splitMode = mergeConfig(options.split, rcConfig?.split, false);
97
+ const maxChars = mergeConfig(options.maxChars, rcConfig?.maxChars, 15000);
98
+ console.log('=== Agent Doc Generator v2.1.0 ===\n');
99
+ if (dryRun) {
100
+ console.log('[DRY-RUN] Modo preview activo - no se escribirán archivos\n');
101
+ }
102
+ const scanSpinner = ora('🔍 Resolviendo provider...').start();
103
+ const resolved = await resolveProvider();
104
+ const apiKey = options.apiKey || getApiKeyForProvider(resolved.provider);
105
+ scanSpinner.succeed(`Provider: ${resolved.provider} | Model: ${resolved.model}`);
106
+ const ai = createAIClient({
107
+ provider: resolved.provider,
108
+ apiKey,
109
+ baseUrl: resolved.baseUrl,
110
+ model: resolved.model,
111
+ verbose,
112
+ });
113
+ if (!ai) {
114
+ printDetectionResult(null, verbose);
115
+ process.exit(1);
116
+ }
117
+ if (verbose) {
118
+ console.log(`[INFO] Provider: ${resolved.provider}`);
119
+ console.log(`[INFO] Modelo: ${resolved.model}`);
120
+ console.log(`[INFO] Max chars: ${maxChars}`);
121
+ console.log(`[INFO] Modo: ${splitMode ? 'split (archivo por archivo)' : 'single (DOCS.md único)'}`);
122
+ }
123
+ const extensions = options.extensions
124
+ ? options.extensions.split(',').map((e) => e.trim())
125
+ : rcConfig?.extensions;
126
+ const filesSpinner = ora('🔍 Escaneando archivos...').start();
127
+ const files = collectFiles(options.path, verbose, extensions);
128
+ if (files.length === 0) {
129
+ filesSpinner.warn('No se encontraron archivos soportados para procesar.');
130
+ process.exit(0);
131
+ }
132
+ filesSpinner.succeed(`Encontrados ${files.length} archivo(s) para procesar.`);
133
+ const projectRoot = process.cwd();
134
+ const cache = loadCache(projectRoot);
135
+ let cacheHits = 0;
136
+ const docEntries = [];
137
+ let succeeded = 0;
138
+ let failed = 0;
139
+ let skipped = 0;
140
+ for (let i = 0; i < files.length; i++) {
141
+ const filePath = files[i];
142
+ const relativePath = path.relative(projectRoot, filePath);
143
+ const fileSpinner = ora({ text: `[${i + 1}/${files.length}] ${relativePath}`, spinner: 'dots' }).start();
144
+ try {
145
+ const fileData = readFile(filePath);
146
+ if (!fileData || shouldSkipContent(fileData.content)) {
147
+ fileSpinner.warn(`Saltado (archivo vacío o no procesable)`);
148
+ skipped++;
149
+ continue;
150
+ }
151
+ const currentHash = computeFileHash(filePath);
152
+ if (isFileCached(filePath, cache, currentHash)) {
153
+ const cachedEntry = cache[filePath];
154
+ fileSpinner.info(`[${i + 1}/${files.length}] ${relativePath} → Cache hit`);
155
+ if (splitMode) {
156
+ if (cachedEntry?.docPath) {
157
+ succeeded++;
158
+ cacheHits++;
159
+ }
160
+ }
161
+ else if (cachedEntry?.content) {
162
+ docEntries.push({
163
+ relativePath,
164
+ filePath,
165
+ content: cachedEntry.content,
166
+ summary: cachedEntry.content.split('\n').slice(0, 3).join(' ').replace(/\/\*[\s\S]*?\*\//, '').trim().slice(0, 200),
167
+ });
168
+ succeeded++;
169
+ cacheHits++;
170
+ }
171
+ continue;
172
+ }
173
+ if (verbose) {
174
+ fileSpinner.text = `[${i + 1}/${files.length}] ${relativePath} - Generando documentación...`;
175
+ }
176
+ const docRaw = await generateDocumentation(ai, filePath, fileData.content, verbose, resolved.model, maxChars);
177
+ if (docRaw) {
178
+ const docContent = extractDocContent(docRaw);
179
+ if (dryRun) {
180
+ const preview = docContent.split('\n').slice(0, 5).join('\n');
181
+ fileSpinner.succeed(`[${i + 1}/${files.length}] ${relativePath} → [DRY-RUN] Preview:\n ${preview.replace(/\n/g, '\n ')}`);
182
+ succeeded++;
183
+ }
184
+ else {
185
+ if (splitMode) {
186
+ const outputDir = mergeConfig(options.output ? path.resolve(options.output) : undefined, rcConfig?.output, undefined);
187
+ const docFilePath = writeDocFile(filePath, docContent, outputDir);
188
+ if (docFilePath) {
189
+ const docRelative = path.relative(projectRoot, docFilePath);
190
+ fileSpinner.succeed(`[${i + 1}/${files.length}] ${relativePath} → ${docRelative}`);
191
+ updateCache(filePath, docFilePath, currentHash, cache);
192
+ succeeded++;
193
+ }
194
+ else {
195
+ fileSpinner.fail(`[${i + 1}/${files.length}] ${relativePath} - Error al escribir doc`);
196
+ failed++;
197
+ }
198
+ }
199
+ else {
200
+ fileSpinner.succeed(`[${i + 1}/${files.length}] ${relativePath} → [DOC]`);
201
+ docEntries.push({
202
+ relativePath,
203
+ filePath,
204
+ content: docContent,
205
+ summary: docContent.split('\n').slice(0, 3).join(' ').replace(/\/\*[\s\S]*?\*\//, '').trim().slice(0, 200),
206
+ });
207
+ updateCache(filePath, '', currentHash, cache, docContent);
208
+ succeeded++;
209
+ }
210
+ }
211
+ }
212
+ else {
213
+ fileSpinner.fail(`[${i + 1}/${files.length}] ${relativePath} - No se pudo generar documentación`);
214
+ failed++;
215
+ }
216
+ }
217
+ catch (err) {
218
+ const error = err;
219
+ fileSpinner.fail(`[${i + 1}/${files.length}] ${relativePath} - Error inesperado`);
220
+ if (verbose) {
221
+ console.error(` ${error.message}`);
222
+ }
223
+ failed++;
224
+ }
225
+ }
226
+ if (!dryRun && !splitMode && docEntries.length > 0) {
227
+ const format = mergeConfig(options.format, rcConfig?.format, 'markdown');
228
+ const targetDir = resolveTargetDir(options.path, options.output);
229
+ if (format === 'html') {
230
+ const writeSpinner = ora('📄 Escribiendo DOCS.html...').start();
231
+ const htmlPath = path.join(targetDir, 'DOCS.html');
232
+ const content = buildSingleDocContent(docEntries);
233
+ const html = generateHtmlFromContent(content, 'Documentación del Proyecto', 'Agent Doc Generator');
234
+ fs.writeFileSync(htmlPath, html, 'utf-8');
235
+ writeSpinner.succeed(`Documentación HTML generada: ${path.relative(projectRoot, htmlPath)}`);
236
+ }
237
+ else if (format === 'pdf') {
238
+ const writeSpinner = ora('📄 Escribiendo DOCS.pdf...').start();
239
+ const pdfPath = path.join(targetDir, 'DOCS.pdf');
240
+ const content = buildSingleDocContent(docEntries);
241
+ await generatePdfFromContent(content, pdfPath, 'Documentación del Proyecto', 'Agent Doc Generator');
242
+ writeSpinner.succeed(`Documentación PDF generada: ${path.relative(projectRoot, pdfPath)}`);
243
+ }
244
+ else {
245
+ const writeSpinner = ora('📄 Escribiendo DOCS.md...').start();
246
+ const docPath = writeSingleDocFile(targetDir, docEntries);
247
+ if (docPath) {
248
+ const docRelative = path.relative(projectRoot, docPath);
249
+ writeSpinner.succeed(`Documentación generada: ${docRelative}`);
250
+ }
251
+ else {
252
+ writeSpinner.fail('Error al escribir DOCS.md');
253
+ }
254
+ }
255
+ }
256
+ if (!dryRun) {
257
+ saveCache(projectRoot, cache);
258
+ }
259
+ console.log('\n=== Resumen ===');
260
+ console.log(` Total: ${files.length}`);
261
+ console.log(` ✅ OK: ${succeeded}`);
262
+ console.log(` ⚠️ Skip: ${skipped}`);
263
+ console.log(` ❌ Error: ${failed}`);
264
+ if (cacheHits > 0) {
265
+ console.log(` 💾 Cache: ${cacheHits}`);
266
+ }
267
+ console.log('');
268
+ if (failed > 0) {
269
+ process.exit(1);
270
+ }
271
+ }
272
+ main().catch((err) => {
273
+ const error = err;
274
+ console.error(`[FATAL] Error inesperado: ${error.message}`);
275
+ process.exit(1);
276
+ });
277
+ function resolveTargetDir(targetPath, output) {
278
+ const resolvedOutput = output ?? rcConfig?.output;
279
+ if (resolvedOutput)
280
+ return path.resolve(resolvedOutput);
281
+ const resolved = path.resolve(targetPath);
282
+ try {
283
+ return fs.statSync(resolved).isDirectory() ? resolved : path.dirname(resolved);
284
+ }
285
+ catch {
286
+ return resolved;
287
+ }
288
+ }
289
+ function buildSingleDocContent(entries) {
290
+ const lines = ['# Documentación del Proyecto', '', `Generado: ${new Date().toLocaleDateString('es-AR')}`, '', '---', ''];
291
+ for (const entry of entries) {
292
+ lines.push(`## ${entry.relativePath}`, '');
293
+ lines.push(entry.content);
294
+ lines.push('');
295
+ lines.push('---', '');
296
+ }
297
+ return lines.join('\n');
298
+ }
299
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../index.ts"],"names":[],"mappings":";AAEA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,MAAM,MAAM,QAAQ,CAAC;AAC5B,OAAO,EAAE,MAAM,IAAI,CAAC;AACpB,OAAO,IAAI,MAAM,MAAM,CAAC;AACxB,OAAO,EAAE,aAAa,EAAE,MAAM,KAAK,CAAC;AACpC,OAAO,GAAG,MAAM,KAAK,CAAC;AAEtB,OAAO,EAAE,YAAY,EAAE,QAAQ,EAAE,YAAY,EAAE,kBAAkB,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AACrH,OAAO,EAAE,cAAc,EAAE,qBAAqB,EAAE,iBAAiB,EAAE,MAAM,uBAAuB,CAAC;AACjG,OAAO,EAAE,SAAS,EAAE,SAAS,EAAE,eAAe,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAClG,OAAO,EAAE,cAAc,EAAE,UAAU,EAAE,UAAU,EAAE,oBAAoB,EAAE,MAAM,2BAA2B,CAAC;AACzG,OAAO,EAAE,cAAc,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AACpE,OAAO,EAAE,uBAAuB,EAAE,MAAM,wBAAwB,CAAC;AACjE,OAAO,EAAE,sBAAsB,EAAE,MAAM,uBAAuB,CAAC;AAG/D,MAAM,SAAS,GAAG,IAAI,CAAC,OAAO,CAAC,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;AAC/D,MAAM,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,MAAM,CAAC,EAAE,CAAC,CAAC;AAEtD,MAAM,OAAO,GAAG,IAAI,OAAO,EAAE,CAAC;AAE9B,OAAO;KACJ,IAAI,CAAC,qBAAqB,CAAC;KAC3B,WAAW,CAAC,oCAAoC,CAAC;KACjD,OAAO,CAAC,OAAO,CAAC;KAChB,cAAc,CAAC,eAAe,EAAE,uCAAuC,CAAC;KACxE,MAAM,CAAC,iBAAiB,EAAE,4CAA4C,CAAC;KACvE,MAAM,CAAC,uBAAuB,EAAE,8DAA8D,CAAC;KAC/F,MAAM,CAAC,kBAAkB,EAAE,8BAA8B,CAAC;KAC1D,MAAM,CAAC,iBAAiB,EAAE,+BAA+B,CAAC;KAC1D,MAAM,CAAC,iBAAiB,EAAE,8CAA8C,EAAE,CAAC,GAAG,EAAE,EAAE,CAAC,QAAQ,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC;KACrG,MAAM,CAAC,gBAAgB,EAAE,0CAA0C,CAAC;KACpE,MAAM,CAAC,mBAAmB,EAAE,sCAAsC,EAAE,UAAU,CAAC;KAC/E,MAAM,CAAC,SAAS,EAAE,sEAAsE,CAAC;KACzF,MAAM,CAAC,WAAW,EAAE,uDAAuD,CAAC;KAC5E,MAAM,CAAC,2BAA2B,EAAE,gEAAgE,CAAC;KACrG,MAAM,CAAC,WAAW,EAAE,oBAAoB,CAAC;KACzC,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;AAEvB,MAAM,OAAO,GAAG,OAAO,CAAC,IAAI,EAAc,CAAC;AAC3C,MAAM,QAAQ,GAAG,cAAc,CAAC,OAAO,CAAC,GAAG,EAAE,CAAC,CAAC;AAS/C,KAAK,UAAU,eAAe;IAC5B,IAAI,OAAO,CAAC,QAAQ,EAAE,CAAC;QACrB,OAAO;YACL,QAAQ,EAAE,OAAO,CAAC,QAAQ;YAC1B,KAAK,EAAE,OAAO,CAAC,KAAK,IAAI,0BAA0B,CAAC,OAAO,CAAC,QAAQ,CAAC;YACpE,MAAM,EAAE,OAAO,CAAC,MAAM;YACtB,OAAO,EAAE,OAAO,CAAC,OAAO;SACzB,CAAC;IACJ,CAAC;IAED,IAAI,QAAQ,EAAE,QAAQ,EAAE,CAAC;QACvB,OAAO;YACL,QAAQ,EAAE,QAAQ,CAAC,QAAQ;YAC3B,KAAK,EAAE,OAAO,CAAC,KAAK,IAAI,QAAQ,CAAC,KAAK,IAAI,0BAA0B,CAAC,QAAQ,CAAC,QAAQ,CAAC;YACvF,OAAO,EAAE,OAAO,CAAC,OAAO,IAAI,QAAQ,CAAC,OAAO;SAC7C,CAAC;IACJ,CAAC;IAED,MAAM,WAAW,GAAG,OAAO,CAAC,GAAG,EAAE,CAAC;IAClC,MAAM,WAAW,GAAG,UAAU,CAAC,WAAW,CAAC,CAAC;IAC5C,IAAI,WAAW,EAAE,CAAC;QAChB,OAAO;YACL,QAAQ,EAAE,WAAW,CAAC,QAAQ;YAC9B,KAAK,EAAE,OAAO,CAAC,KAAK,IAAI,WAAW,CAAC,KAAK;YACzC,OAAO,EAAE,WAAW,CAAC,OAAO;SAC7B,CAAC;IACJ,CAAC;IAED,MAAM,QAAQ,GAAG,MAAM,cAAc,CAAC,EAAE,WAAW,EAAE,CAAC,CAAC;IACvD,IAAI,QAAQ,EAAE,CAAC;QACb,UAAU,CAAC,WAAW,EAAE,QAAQ,CAAC,CAAC;QAClC,OAAO;YACL,QAAQ,EAAE,QAAQ,CAAC,QAAQ;YAC3B,KAAK,EAAE,OAAO,CAAC,KAAK,IAAI,QAAQ,CAAC,KAAK;YACtC,OAAO,EAAE,QAAQ,CAAC,OAAO;SAC1B,CAAC;IACJ,CAAC;IAED,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,KAAK,EAAE,OAAO,CAAC,KAAK,IAAI,kBAAkB,EAAE,CAAC;AAC5E,CAAC;AAED,SAAS,0BAA0B,CAAC,QAAgB;IAClD,MAAM,QAAQ,GAA2B;QACvC,MAAM,EAAE,kBAAkB;QAC1B,MAAM,EAAE,QAAQ;QAChB,SAAS,EAAE,0BAA0B;QACrC,QAAQ,EAAE,eAAe;QACzB,MAAM,EAAE,QAAQ;KACjB,CAAC;IACF,OAAO,QAAQ,CAAC,QAAQ,CAAC,IAAI,kBAAkB,CAAC;AAClD,CAAC;AAED,SAAS,oBAAoB,CAAC,QAAgB;IAC5C,MAAM,SAAS,GAA2B;QACxC,MAAM,EAAE,gBAAgB;QACxB,MAAM,EAAE,gBAAgB;QACxB,SAAS,EAAE,mBAAmB;QAC9B,QAAQ,EAAE,kBAAkB;KAC7B,CAAC;IACF,MAAM,MAAM,GAAG,SAAS,CAAC,QAAQ,CAAC,CAAC;IACnC,OAAO,MAAM,CAAC,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;AAClD,CAAC;AAED,KAAK,UAAU,IAAI;IACjB,MAAM,OAAO,GAAG,WAAW,CAAC,OAAO,CAAC,OAAO,EAAE,QAAQ,EAAE,OAAO,EAAE,KAAK,CAAC,CAAC;IACvE,MAAM,MAAM,GAAG,WAAW,CAAC,OAAO,CAAC,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,KAAK,CAAC,CAAC;IACpE,MAAM,SAAS,GAAG,WAAW,CAAC,OAAO,CAAC,KAAK,EAAE,QAAQ,EAAE,KAAK,EAAE,KAAK,CAAC,CAAC;IACrE,MAAM,QAAQ,GAAG,WAAW,CAAC,OAAO,CAAC,QAAQ,EAAE,QAAQ,EAAE,QAAQ,EAAE,KAAK,CAAC,CAAC;IAE1E,OAAO,CAAC,GAAG,CAAC,sCAAsC,CAAC,CAAC;IAEpD,IAAI,MAAM,EAAE,CAAC;QACX,OAAO,CAAC,GAAG,CAAC,6DAA6D,CAAC,CAAC;IAC7E,CAAC;IAED,MAAM,WAAW,GAAG,GAAG,CAAC,4BAA4B,CAAC,CAAC,KAAK,EAAE,CAAC;IAE9D,MAAM,QAAQ,GAAG,MAAM,eAAe,EAAE,CAAC;IACzC,MAAM,MAAM,GAAG,OAAO,CAAC,MAAM,IAAI,oBAAoB,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;IAEzE,WAAW,CAAC,OAAO,CAAC,aAAa,QAAQ,CAAC,QAAQ,aAAa,QAAQ,CAAC,KAAK,EAAE,CAAC,CAAC;IAEjF,MAAM,EAAE,GAAG,cAAc,CAAC;QACxB,QAAQ,EAAE,QAAQ,CAAC,QAAQ;QAC3B,MAAM;QACN,OAAO,EAAE,QAAQ,CAAC,OAAO;QACzB,KAAK,EAAE,QAAQ,CAAC,KAAK;QACrB,OAAO;KACR,CAAC,CAAC;IAEH,IAAI,CAAC,EAAE,EAAE,CAAC;QACR,oBAAoB,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;QACpC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,IAAI,OAAO,EAAE,CAAC;QACZ,OAAO,CAAC,GAAG,CAAC,oBAAoB,QAAQ,CAAC,QAAQ,EAAE,CAAC,CAAC;QACrD,OAAO,CAAC,GAAG,CAAC,kBAAkB,QAAQ,CAAC,KAAK,EAAE,CAAC,CAAC;QAChD,OAAO,CAAC,GAAG,CAAC,qBAAqB,QAAQ,EAAE,CAAC,CAAC;QAC7C,OAAO,CAAC,GAAG,CAAC,gBAAgB,SAAS,CAAC,CAAC,CAAC,6BAA6B,CAAC,CAAC,CAAC,wBAAwB,EAAE,CAAC,CAAC;IACtG,CAAC;IAED,MAAM,UAAU,GAAG,OAAO,CAAC,UAAU;QACnC,CAAC,CAAC,OAAO,CAAC,UAAU,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAS,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;QAC5D,CAAC,CAAC,QAAQ,EAAE,UAAU,CAAC;IAEzB,MAAM,YAAY,GAAG,GAAG,CAAC,2BAA2B,CAAC,CAAC,KAAK,EAAE,CAAC;IAC9D,MAAM,KAAK,GAAG,YAAY,CAAC,OAAO,CAAC,IAAI,EAAE,OAAO,EAAE,UAAU,CAAC,CAAC;IAE9D,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACvB,YAAY,CAAC,IAAI,CAAC,sDAAsD,CAAC,CAAC;QAC1E,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,YAAY,CAAC,OAAO,CAAC,eAAe,KAAK,CAAC,MAAM,4BAA4B,CAAC,CAAC;IAE9E,MAAM,WAAW,GAAG,OAAO,CAAC,GAAG,EAAE,CAAC;IAClC,MAAM,KAAK,GAAG,SAAS,CAAC,WAAW,CAAC,CAAC;IACrC,IAAI,SAAS,GAAG,CAAC,CAAC;IAElB,MAAM,UAAU,GAAe,EAAE,CAAC;IAClC,IAAI,SAAS,GAAG,CAAC,CAAC;IAClB,IAAI,MAAM,GAAG,CAAC,CAAC;IACf,IAAI,OAAO,GAAG,CAAC,CAAC;IAEhB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QACtC,MAAM,QAAQ,GAAG,KAAK,CAAC,CAAC,CAAE,CAAC;QAC3B,MAAM,YAAY,GAAG,IAAI,CAAC,QAAQ,CAAC,WAAW,EAAE,QAAQ,CAAC,CAAC;QAC1D,MAAM,WAAW,GAAG,GAAG,CAAC,EAAE,IAAI,EAAE,IAAI,CAAC,GAAG,CAAC,IAAI,KAAK,CAAC,MAAM,KAAK,YAAY,EAAE,EAAE,OAAO,EAAE,MAAM,EAAE,CAAC,CAAC,KAAK,EAAE,CAAC;QAEzG,IAAI,CAAC;YACH,MAAM,QAAQ,GAAG,QAAQ,CAAC,QAAQ,CAAC,CAAC;YACpC,IAAI,CAAC,QAAQ,IAAI,iBAAiB,CAAC,QAAQ,CAAC,OAAO,CAAC,EAAE,CAAC;gBACrD,WAAW,CAAC,IAAI,CAAC,yCAAyC,CAAC,CAAC;gBAC5D,OAAO,EAAE,CAAC;gBACV,SAAS;YACX,CAAC;YAED,MAAM,WAAW,GAAG,eAAe,CAAC,QAAQ,CAAC,CAAC;YAC9C,IAAI,YAAY,CAAC,QAAQ,EAAE,KAAK,EAAE,WAAW,CAAC,EAAE,CAAC;gBAC/C,MAAM,WAAW,GAAG,KAAK,CAAC,QAAQ,CAAC,CAAC;gBACpC,WAAW,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,KAAK,CAAC,MAAM,KAAK,YAAY,cAAc,CAAC,CAAC;gBAC3E,IAAI,SAAS,EAAE,CAAC;oBACd,IAAI,WAAW,EAAE,OAAO,EAAE,CAAC;wBACzB,SAAS,EAAE,CAAC;wBACZ,SAAS,EAAE,CAAC;oBACd,CAAC;gBACH,CAAC;qBAAM,IAAI,WAAW,EAAE,OAAO,EAAE,CAAC;oBAChC,UAAU,CAAC,IAAI,CAAC;wBACd,YAAY;wBACZ,QAAQ;wBACR,OAAO,EAAE,WAAW,CAAC,OAAO;wBAC5B,OAAO,EAAE,WAAW,CAAC,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,OAAO,CAAC,kBAAkB,EAAE,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC;qBACpH,CAAC,CAAC;oBACH,SAAS,EAAE,CAAC;oBACZ,SAAS,EAAE,CAAC;gBACd,CAAC;gBACD,SAAS;YACX,CAAC;YAED,IAAI,OAAO,EAAE,CAAC;gBACZ,WAAW,CAAC,IAAI,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,KAAK,CAAC,MAAM,KAAK,YAAY,+BAA+B,CAAC;YAC/F,CAAC;YAED,MAAM,MAAM,GAAG,MAAM,qBAAqB,CAAC,EAAE,EAAE,QAAQ,EAAE,QAAQ,CAAC,OAAO,EAAE,OAAO,EAAE,QAAQ,CAAC,KAAK,EAAE,QAAQ,CAAC,CAAC;YAE9G,IAAI,MAAM,EAAE,CAAC;gBACX,MAAM,UAAU,GAAG,iBAAiB,CAAC,MAAM,CAAC,CAAC;gBAE7C,IAAI,MAAM,EAAE,CAAC;oBACX,MAAM,OAAO,GAAG,UAAU,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;oBAC9D,WAAW,CAAC,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,KAAK,CAAC,MAAM,KAAK,YAAY,8BAA8B,OAAO,CAAC,OAAO,CAAC,KAAK,EAAE,QAAQ,CAAC,EAAE,CAAC,CAAC;oBAChI,SAAS,EAAE,CAAC;gBACd,CAAC;qBAAM,CAAC;oBACN,IAAI,SAAS,EAAE,CAAC;wBACd,MAAM,SAAS,GAAG,WAAW,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,SAAS,EAAE,QAAQ,EAAE,MAAM,EAAE,SAAS,CAAC,CAAC;wBACtH,MAAM,WAAW,GAAG,YAAY,CAAC,QAAQ,EAAE,UAAU,EAAE,SAAS,CAAC,CAAC;wBAClE,IAAI,WAAW,EAAE,CAAC;4BAChB,MAAM,WAAW,GAAG,IAAI,CAAC,QAAQ,CAAC,WAAW,EAAE,WAAW,CAAC,CAAC;4BAC5D,WAAW,CAAC,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,KAAK,CAAC,MAAM,KAAK,YAAY,MAAM,WAAW,EAAE,CAAC,CAAC;4BACnF,WAAW,CAAC,QAAQ,EAAE,WAAW,EAAE,WAAW,EAAE,KAAK,CAAC,CAAC;4BACvD,SAAS,EAAE,CAAC;wBACd,CAAC;6BAAM,CAAC;4BACN,WAAW,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,KAAK,CAAC,MAAM,KAAK,YAAY,0BAA0B,CAAC,CAAC;4BACvF,MAAM,EAAE,CAAC;wBACX,CAAC;oBACH,CAAC;yBAAM,CAAC;wBACN,WAAW,CAAC,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,KAAK,CAAC,MAAM,KAAK,YAAY,UAAU,CAAC,CAAC;wBAC1E,UAAU,CAAC,IAAI,CAAC;4BACd,YAAY;4BACZ,QAAQ;4BACR,OAAO,EAAE,UAAU;4BACnB,OAAO,EAAE,UAAU,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,OAAO,CAAC,kBAAkB,EAAE,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC;yBAC3G,CAAC,CAAC;wBACH,WAAW,CAAC,QAAQ,EAAE,EAAE,EAAE,WAAW,EAAE,KAAK,EAAE,UAAU,CAAC,CAAC;wBAC1D,SAAS,EAAE,CAAC;oBACd,CAAC;gBACH,CAAC;YACH,CAAC;iBAAM,CAAC;gBACN,WAAW,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,KAAK,CAAC,MAAM,KAAK,YAAY,qCAAqC,CAAC,CAAC;gBAClG,MAAM,EAAE,CAAC;YACX,CAAC;QACH,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,MAAM,KAAK,GAAG,GAAY,CAAC;YAC3B,WAAW,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,KAAK,CAAC,MAAM,KAAK,YAAY,qBAAqB,CAAC,CAAC;YAClF,IAAI,OAAO,EAAE,CAAC;gBACZ,OAAO,CAAC,KAAK,CAAC,OAAO,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC;YACxC,CAAC;YACD,MAAM,EAAE,CAAC;QACX,CAAC;IACH,CAAC;IAED,IAAI,CAAC,MAAM,IAAI,CAAC,SAAS,IAAI,UAAU,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACnD,MAAM,MAAM,GAAG,WAAW,CAAC,OAAO,CAAC,MAAM,EAAE,QAAQ,EAAE,MAAiD,EAAE,UAAU,CAAC,CAAC;QACpH,MAAM,SAAS,GAAG,gBAAgB,CAAC,OAAO,CAAC,IAAI,EAAE,OAAO,CAAC,MAAM,CAAC,CAAC;QAEjE,IAAI,MAAM,KAAK,MAAM,EAAE,CAAC;YACtB,MAAM,YAAY,GAAG,GAAG,CAAC,6BAA6B,CAAC,CAAC,KAAK,EAAE,CAAC;YAChE,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,WAAW,CAAC,CAAC;YACnD,MAAM,OAAO,GAAG,qBAAqB,CAAC,UAAU,CAAC,CAAC;YAClD,MAAM,IAAI,GAAG,uBAAuB,CAAC,OAAO,EAAE,4BAA4B,EAAE,qBAAqB,CAAC,CAAC;YACnG,EAAE,CAAC,aAAa,CAAC,QAAQ,EAAE,IAAI,EAAE,OAAO,CAAC,CAAC;YAC1C,YAAY,CAAC,OAAO,CAAC,gCAAgC,IAAI,CAAC,QAAQ,CAAC,WAAW,EAAE,QAAQ,CAAC,EAAE,CAAC,CAAC;QAC/F,CAAC;aAAM,IAAI,MAAM,KAAK,KAAK,EAAE,CAAC;YAC5B,MAAM,YAAY,GAAG,GAAG,CAAC,4BAA4B,CAAC,CAAC,KAAK,EAAE,CAAC;YAC/D,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,UAAU,CAAC,CAAC;YACjD,MAAM,OAAO,GAAG,qBAAqB,CAAC,UAAU,CAAC,CAAC;YAClD,MAAM,sBAAsB,CAAC,OAAO,EAAE,OAAO,EAAE,4BAA4B,EAAE,qBAAqB,CAAC,CAAC;YACpG,YAAY,CAAC,OAAO,CAAC,+BAA+B,IAAI,CAAC,QAAQ,CAAC,WAAW,EAAE,OAAO,CAAC,EAAE,CAAC,CAAC;QAC7F,CAAC;aAAM,CAAC;YACN,MAAM,YAAY,GAAG,GAAG,CAAC,2BAA2B,CAAC,CAAC,KAAK,EAAE,CAAC;YAC9D,MAAM,OAAO,GAAG,kBAAkB,CAAC,SAAS,EAAE,UAAU,CAAC,CAAC;YAC1D,IAAI,OAAO,EAAE,CAAC;gBACZ,MAAM,WAAW,GAAG,IAAI,CAAC,QAAQ,CAAC,WAAW,EAAE,OAAO,CAAC,CAAC;gBACxD,YAAY,CAAC,OAAO,CAAC,2BAA2B,WAAW,EAAE,CAAC,CAAC;YACjE,CAAC;iBAAM,CAAC;gBACN,YAAY,CAAC,IAAI,CAAC,2BAA2B,CAAC,CAAC;YACjD,CAAC;QACH,CAAC;IACH,CAAC;IAED,IAAI,CAAC,MAAM,EAAE,CAAC;QACZ,SAAS,CAAC,WAAW,EAAE,KAAK,CAAC,CAAC;IAChC,CAAC;IAED,OAAO,CAAC,GAAG,CAAC,mBAAmB,CAAC,CAAC;IACjC,OAAO,CAAC,GAAG,CAAC,eAAe,KAAK,CAAC,MAAM,EAAE,CAAC,CAAC;IAC3C,OAAO,CAAC,GAAG,CAAC,cAAc,SAAS,EAAE,CAAC,CAAC;IACvC,OAAO,CAAC,GAAG,CAAC,iBAAiB,OAAO,EAAE,CAAC,CAAC;IACxC,OAAO,CAAC,GAAG,CAAC,eAAe,MAAM,EAAE,CAAC,CAAC;IACrC,IAAI,SAAS,GAAG,CAAC,EAAE,CAAC;QAClB,OAAO,CAAC,GAAG,CAAC,gBAAgB,SAAS,EAAE,CAAC,CAAC;IAC3C,CAAC;IACD,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IAEhB,IAAI,MAAM,GAAG,CAAC,EAAE,CAAC;QACf,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;AACH,CAAC;AAED,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC,GAAG,EAAE,EAAE;IACnB,MAAM,KAAK,GAAG,GAAY,CAAC;IAC3B,OAAO,CAAC,KAAK,CAAC,6BAA6B,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC;IAC5D,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC,CAAC,CAAC;AAEH,SAAS,gBAAgB,CAAC,UAAkB,EAAE,MAAe;IAC3D,MAAM,cAAc,GAAG,MAAM,IAAI,QAAQ,EAAE,MAAM,CAAC;IAClD,IAAI,cAAc;QAAE,OAAO,IAAI,CAAC,OAAO,CAAC,cAAc,CAAC,CAAC;IACxD,MAAM,QAAQ,GAAG,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC;IAC1C,IAAI,CAAC;QACH,OAAO,EAAE,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;IACjF,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,QAAQ,CAAC;IAClB,CAAC;AACH,CAAC;AAED,SAAS,qBAAqB,CAAC,OAAoD;IACjF,MAAM,KAAK,GAAG,CAAC,8BAA8B,EAAE,EAAE,EAAE,aAAa,IAAI,IAAI,EAAE,CAAC,kBAAkB,CAAC,OAAO,CAAC,EAAE,EAAE,EAAE,EAAE,KAAK,EAAE,EAAE,CAAC,CAAC;IACzH,KAAK,MAAM,KAAK,IAAI,OAAO,EAAE,CAAC;QAC5B,KAAK,CAAC,IAAI,CAAC,MAAM,KAAK,CAAC,YAAY,EAAE,EAAE,EAAE,CAAC,CAAC;QAC3C,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;QAC1B,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QACf,KAAK,CAAC,IAAI,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;IACxB,CAAC;IACD,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAC1B,CAAC"}
@@ -0,0 +1,38 @@
1
+ export interface AIClient {
2
+ generate(prompt: string, model: string): Promise<string | null>;
3
+ }
4
+ export interface CreateAIClientOptions {
5
+ provider?: string;
6
+ apiKey?: string;
7
+ baseUrl?: string;
8
+ model?: string;
9
+ verbose?: boolean;
10
+ }
11
+ export declare class GeminiClient implements AIClient {
12
+ private ai;
13
+ constructor(apiKey: string);
14
+ generate(prompt: string, model: string): Promise<string | null>;
15
+ }
16
+ export declare class OpenAIClient implements AIClient {
17
+ private apiKey;
18
+ constructor(apiKey: string);
19
+ generate(prompt: string, model: string): Promise<string | null>;
20
+ }
21
+ export declare class AnthropicClient implements AIClient {
22
+ private apiKey;
23
+ constructor(apiKey: string);
24
+ generate(prompt: string, model: string): Promise<string | null>;
25
+ }
26
+ export declare class DeepSeekClient implements AIClient {
27
+ private apiKey;
28
+ constructor(apiKey: string);
29
+ generate(prompt: string, model: string): Promise<string | null>;
30
+ }
31
+ export declare class OllamaClient implements AIClient {
32
+ private baseUrl;
33
+ private apiKey?;
34
+ constructor(baseUrl: string, apiKey?: string);
35
+ generate(prompt: string, model: string): Promise<string | null>;
36
+ }
37
+ export declare function createAIClient(options?: CreateAIClientOptions): AIClient | null;
38
+ //# sourceMappingURL=aiClient.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"aiClient.d.ts","sourceRoot":"","sources":["../../src/aiClient.ts"],"names":[],"mappings":"AAEA,MAAM,WAAW,QAAQ;IACvB,QAAQ,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC;CACjE;AAED,MAAM,WAAW,qBAAqB;IACpC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAKD,qBAAa,YAAa,YAAW,QAAQ;IAC3C,OAAO,CAAC,EAAE,CAAc;gBAEZ,MAAM,EAAE,MAAM;IAIpB,QAAQ,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC;CAItE;AAED,qBAAa,YAAa,YAAW,QAAQ;IAC3C,OAAO,CAAC,MAAM,CAAS;gBAEX,MAAM,EAAE,MAAM;IAIpB,QAAQ,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC;CAwBtE;AAED,qBAAa,eAAgB,YAAW,QAAQ;IAC9C,OAAO,CAAC,MAAM,CAAS;gBAEX,MAAM,EAAE,MAAM;IAIpB,QAAQ,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC;CAyBtE;AAED,qBAAa,cAAe,YAAW,QAAQ;IAC7C,OAAO,CAAC,MAAM,CAAS;gBAEX,MAAM,EAAE,MAAM;IAIpB,QAAQ,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC;CAwBtE;AAED,qBAAa,YAAa,YAAW,QAAQ;IAC3C,OAAO,CAAC,OAAO,CAAS;IACxB,OAAO,CAAC,MAAM,CAAC,CAAS;gBAEZ,OAAO,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM;IAKtC,QAAQ,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC;CAyBtE;AAED,wBAAgB,cAAc,CAAC,OAAO,GAAE,qBAA0B,GAAG,QAAQ,GAAG,IAAI,CA8DnF"}
@@ -0,0 +1,180 @@
1
+ import { GoogleGenAI } from '@google/genai';
2
+ const PLACEHOLDER_KEY = 'your_gemini_api_key_here';
3
+ const DEFAULT_LOCAL_BASE_URL = 'http://localhost:11434';
4
+ export class GeminiClient {
5
+ ai;
6
+ constructor(apiKey) {
7
+ this.ai = new GoogleGenAI({ apiKey });
8
+ }
9
+ async generate(prompt, model) {
10
+ const result = await this.ai.models.generateContent({ model, contents: prompt });
11
+ return result.text ?? null;
12
+ }
13
+ }
14
+ export class OpenAIClient {
15
+ apiKey;
16
+ constructor(apiKey) {
17
+ this.apiKey = apiKey;
18
+ }
19
+ async generate(prompt, model) {
20
+ const res = await fetch('https://api.openai.com/v1/chat/completions', {
21
+ method: 'POST',
22
+ headers: {
23
+ 'Content-Type': 'application/json',
24
+ 'Authorization': `Bearer ${this.apiKey}`,
25
+ },
26
+ body: JSON.stringify({
27
+ model,
28
+ messages: [{ role: 'user', content: prompt }],
29
+ stream: false,
30
+ }),
31
+ });
32
+ if (!res.ok) {
33
+ const body = await res.text().catch(() => '');
34
+ throw new Error(`OpenAI API error ${res.status}: ${body}`);
35
+ }
36
+ const data = (await res.json());
37
+ return data?.choices?.[0]?.message?.content ?? null;
38
+ }
39
+ }
40
+ export class AnthropicClient {
41
+ apiKey;
42
+ constructor(apiKey) {
43
+ this.apiKey = apiKey;
44
+ }
45
+ async generate(prompt, model) {
46
+ const res = await fetch('https://api.anthropic.com/v1/messages', {
47
+ method: 'POST',
48
+ headers: {
49
+ 'Content-Type': 'application/json',
50
+ 'x-api-key': this.apiKey,
51
+ 'anthropic-version': '2023-06-01',
52
+ },
53
+ body: JSON.stringify({
54
+ model,
55
+ messages: [{ role: 'user', content: prompt }],
56
+ max_tokens: 8096,
57
+ }),
58
+ });
59
+ if (!res.ok) {
60
+ const body = await res.text().catch(() => '');
61
+ throw new Error(`Anthropic API error ${res.status}: ${body}`);
62
+ }
63
+ const data = (await res.json());
64
+ return data?.content?.[0]?.text ?? null;
65
+ }
66
+ }
67
+ export class DeepSeekClient {
68
+ apiKey;
69
+ constructor(apiKey) {
70
+ this.apiKey = apiKey;
71
+ }
72
+ async generate(prompt, model) {
73
+ const res = await fetch('https://api.deepseek.com/v1/chat/completions', {
74
+ method: 'POST',
75
+ headers: {
76
+ 'Content-Type': 'application/json',
77
+ 'Authorization': `Bearer ${this.apiKey}`,
78
+ },
79
+ body: JSON.stringify({
80
+ model,
81
+ messages: [{ role: 'user', content: prompt }],
82
+ stream: false,
83
+ }),
84
+ });
85
+ if (!res.ok) {
86
+ const body = await res.text().catch(() => '');
87
+ throw new Error(`DeepSeek API error ${res.status}: ${body}`);
88
+ }
89
+ const data = (await res.json());
90
+ return data?.choices?.[0]?.message?.content ?? null;
91
+ }
92
+ }
93
+ export class OllamaClient {
94
+ baseUrl;
95
+ apiKey;
96
+ constructor(baseUrl, apiKey) {
97
+ this.baseUrl = baseUrl.replace(/\/+$/, '');
98
+ this.apiKey = apiKey;
99
+ }
100
+ async generate(prompt, model) {
101
+ const url = `${this.baseUrl}/api/chat`;
102
+ const headers = { 'Content-Type': 'application/json' };
103
+ if (this.apiKey)
104
+ headers['Authorization'] = `Bearer ${this.apiKey}`;
105
+ const res = await fetch(url, {
106
+ method: 'POST',
107
+ headers,
108
+ body: JSON.stringify({
109
+ model,
110
+ messages: [{ role: 'user', content: prompt }],
111
+ stream: false,
112
+ }),
113
+ });
114
+ if (!res.ok) {
115
+ const body = await res.text().catch(() => '');
116
+ throw new Error(`Ollama API error ${res.status}: ${body}`);
117
+ }
118
+ const data = (await res.json());
119
+ return data?.message?.content ?? null;
120
+ }
121
+ }
122
+ export function createAIClient(options = {}) {
123
+ const provider = options.provider ?? 'gemini';
124
+ switch (provider) {
125
+ case 'gemini': {
126
+ const apiKey = options.apiKey;
127
+ if (!apiKey || apiKey === PLACEHOLDER_KEY) {
128
+ console.error('[ERROR] GEMINI_API_KEY is not set or is invalid.');
129
+ console.error(' Create a .env file with: GEMINI_API_KEY=your_key');
130
+ console.error(' Get key at: https://aistudio.google.com/apikey');
131
+ console.error(' Or use: --provider openai | anthropic | deepseek | ollama');
132
+ return null;
133
+ }
134
+ try {
135
+ return new GeminiClient(apiKey);
136
+ }
137
+ catch (err) {
138
+ const error = err;
139
+ console.error(`[ERROR] Failed to initialize Gemini client: ${error.message}`);
140
+ return null;
141
+ }
142
+ }
143
+ case 'openai': {
144
+ const apiKey = options.apiKey;
145
+ if (!apiKey) {
146
+ console.error('[ERROR] OPENAI_API_KEY is not set.');
147
+ console.error(' Create a .env file with: OPENAI_API_KEY=sk-...');
148
+ return null;
149
+ }
150
+ return new OpenAIClient(apiKey);
151
+ }
152
+ case 'anthropic': {
153
+ const apiKey = options.apiKey;
154
+ if (!apiKey) {
155
+ console.error('[ERROR] ANTHROPIC_API_KEY is not set.');
156
+ console.error(' Create a .env file with: ANTHROPIC_API_KEY=sk-ant-...');
157
+ return null;
158
+ }
159
+ return new AnthropicClient(apiKey);
160
+ }
161
+ case 'deepseek': {
162
+ const apiKey = options.apiKey;
163
+ if (!apiKey) {
164
+ console.error('[ERROR] DEEPSEEK_API_KEY is not set.');
165
+ console.error(' Create a .env file with: DEEPSEEK_API_KEY=sk-...');
166
+ return null;
167
+ }
168
+ return new DeepSeekClient(apiKey);
169
+ }
170
+ case 'ollama': {
171
+ const baseUrl = options.baseUrl ?? DEFAULT_LOCAL_BASE_URL;
172
+ return new OllamaClient(baseUrl, options.apiKey);
173
+ }
174
+ default:
175
+ console.error(`[ERROR] Unknown provider: "${provider}"`);
176
+ console.error(' Valid providers: gemini, openai, anthropic, deepseek, ollama');
177
+ return null;
178
+ }
179
+ }
180
+ //# sourceMappingURL=aiClient.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"aiClient.js","sourceRoot":"","sources":["../../src/aiClient.ts"],"names":[],"mappings":"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"}