@dbcube/core 5.2.2 → 5.2.4

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.
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts","../src/lib/Engine.ts","../src/lib/Arquitecture.ts","../src/lib/Donwloader.ts","../src/lib/Binary.ts","../src/lib/Config.ts","../src/lib/DaemonClient.ts","../src/lib/QueryEngine.ts","../src/lib/SqliteExecutor.ts","../src/lib/DbConfig.ts","../src/lib/FileLogger.ts","../src/lib/Processors.ts"],"sourcesContent":["import { Engine } from './lib/Engine';\r\nimport { QueryEngine } from './lib/QueryEngine';\r\nimport { Arquitecture } from './lib/Arquitecture';\r\nimport { Binary } from './lib/Binary';\r\nimport { DbConfig } from './lib/DbConfig';\r\nimport { Config } from './lib/Config';\r\nimport { DaemonClient } from './lib/DaemonClient';\r\nimport { FileLogger, InterceptController } from './lib/FileLogger';\r\nimport { ComputedFieldProcessor, TableProcessor, TriggerProcessor } from './lib/Processors';\r\n\r\nexport { Config, Engine, QueryEngine, Arquitecture, Binary, DbConfig, DaemonClient, ComputedFieldProcessor, TableProcessor, TriggerProcessor, FileLogger, InterceptController };","import path from \"path\";\r\nimport { Binary } from \"./Binary\";\r\nimport { Config as ConfigClass } from './Config';\r\nimport { spawn } from \"child_process\";\r\nimport { ProcessResponse, ResponseEngine } from \"../@types/Engine\";\r\nimport { BinaryType } from \"../@types/Binary\";\r\nimport { createRequire } from 'module';\r\nimport { DaemonClient } from './DaemonClient';\r\n\r\nclass Engine {\r\n private name: string;\r\n private config: any;\r\n private arguments: any;\r\n private binary: BinaryType | null = null;\r\n private timeout: number;\r\n private daemonFailed = false;\r\n\r\n constructor(name: string, timeout = 30000) {\r\n this.name = name;\r\n this.config = this.setConfig(name);\r\n this.arguments = this.setArguments();\r\n this.timeout = timeout;\r\n }\r\n\r\n async initializeBinary(): Promise<void> {\r\n if (!this.binary) {\r\n this.binary = await Binary.get();\r\n }\r\n }\r\n\r\n /**\r\n * Returns a connected DaemonClient for this database, or null when\r\n * daemon mode is disabled/unavailable (then callers use spawn mode).\r\n */\r\n private async getDaemon(): Promise<DaemonClient | null> {\r\n if (this.daemonFailed || !DaemonClient.isEnabled()) return null;\r\n await this.initializeBinary();\r\n if (!this.binary) return null;\r\n\r\n const binaryPath = this.binary['query_engine' as keyof BinaryType];\r\n if (!binaryPath) return null;\r\n\r\n const client = DaemonClient.get(this.name, binaryPath, this.arguments);\r\n const ok = await client.ensure();\r\n if (!ok) {\r\n this.daemonFailed = true; // don't retry on every query\r\n return null;\r\n }\r\n return client;\r\n }\r\n\r\n /**\r\n * Executes a DML plan. Uses the persistent daemon (sub-millisecond\r\n * overhead) when available; falls back to one-shot spawn otherwise.\r\n */\r\n async executeDml(dml: object, txId?: string): Promise<ResponseEngine> {\r\n const daemon = await this.getDaemon();\r\n if (daemon) {\r\n try {\r\n return await daemon.execute(dml, txId);\r\n } catch (error: any) {\r\n if (txId) throw error; // a transaction can't change transport mid-flight\r\n // fall through to spawn mode\r\n }\r\n }\r\n if (txId) {\r\n throw new Error('Transactions require daemon mode. Make sure the query-engine binary is up to date (npx dbcube update).');\r\n }\r\n return this.run('query_engine', ['--action', 'execute', '--dml', JSON.stringify(dml)] as any);\r\n }\r\n\r\n /**\r\n * Executes raw SQL (or a MongoDB command document) with bound parameters.\r\n */\r\n async rawQuery(query: string, params: any[] = [], txId?: string): Promise<ResponseEngine> {\r\n const daemon = await this.getDaemon();\r\n if (daemon) {\r\n try {\r\n return await daemon.raw(query, params, txId);\r\n } catch (error: any) {\r\n if (txId) throw error;\r\n }\r\n }\r\n if (txId) {\r\n throw new Error('Transactions require daemon mode. Make sure the query-engine binary is up to date (npx dbcube update).');\r\n }\r\n return this.run('query_engine', ['--action', 'raw', '--query', query, '--params', JSON.stringify(params)] as any);\r\n }\r\n\r\n /** Starts a transaction (daemon mode only). Returns the transaction id. */\r\n async beginTransaction(): Promise<string> {\r\n const daemon = await this.getDaemon();\r\n if (!daemon) {\r\n throw new Error('Transactions require daemon mode. Make sure the query-engine binary is up to date (npx dbcube update).');\r\n }\r\n return daemon.begin();\r\n }\r\n\r\n async commitTransaction(txId: string): Promise<void> {\r\n const daemon = await this.getDaemon();\r\n if (!daemon) throw new Error('Daemon connection lost during transaction');\r\n return daemon.commit(txId);\r\n }\r\n\r\n async rollbackTransaction(txId: string): Promise<void> {\r\n const daemon = await this.getDaemon();\r\n if (!daemon) throw new Error('Daemon connection lost during transaction');\r\n return daemon.rollback(txId);\r\n }\r\n\r\n setArguments() {\r\n let args = [];\r\n if (this.config.type == 'sqlite') {\r\n args = [\r\n '--id', 'dbcube-' + this.name,\r\n '--database-ref', this.name,\r\n '--database', this.config.config.DATABASE + \".db\",\r\n '--motor', this.config.type\r\n ];\r\n } else {\r\n args = [\r\n '--id', 'dbcube-' + this.name,\r\n '--database-ref', this.name,\r\n '--database', this.config.config.DATABASE,\r\n '--host', this.config.config.HOST,\r\n '--port', String(this.config.config.PORT),\r\n '--motor', this.config.type\r\n ];\r\n // Credenciales opcionales (p. ej. MongoDB local sin auth)\r\n if (this.config.config.USER != null && this.config.config.USER !== '') {\r\n args.push('--user', this.config.config.USER);\r\n }\r\n if (this.config.config.PASSWORD != null && this.config.config.PASSWORD !== '') {\r\n args.push('--password', this.config.config.PASSWORD);\r\n }\r\n }\r\n return args;\r\n }\r\n\r\n setConfig(name: string) {\r\n const configInstance = new ConfigClass();\r\n\r\n try {\r\n const configFilePath = path.resolve(process.cwd(), 'dbcube.config.js');\r\n // Use __filename for CJS, process.cwd() for ESM\r\n const requireUrl = typeof __filename !== 'undefined' ? __filename : process.cwd();\r\n const require = createRequire(requireUrl);\r\n // Clear require cache to ensure fresh load (safe check for bundled environments)\r\n if (require.cache && require.resolve) {\r\n try {\r\n delete require.cache[require.resolve(configFilePath)];\r\n } catch (e) {\r\n // Ignore errors in bundled environments\r\n }\r\n }\r\n const configModule = require(configFilePath);\r\n const configFn = configModule.default || configModule;\r\n\r\n if (typeof configFn === 'function') {\r\n configFn(configInstance);\r\n } else {\r\n console.error('❌ El archivo dbcube.config.js no exporta una función.');\r\n }\r\n } catch (error: any) {\r\n console.error('❌ Error loading config file:', error.message);\r\n if (error.code === 'MODULE_NOT_FOUND') {\r\n console.error('❌ Config file not found, please create a dbcube.config.js file');\r\n }\r\n }\r\n\r\n return configInstance.getDatabase(name);\r\n\r\n }\r\n\r\n getConfig() {\r\n return this.config;\r\n }\r\n\r\n async run(binary: string, args: []) {\r\n await this.initializeBinary();\r\n\r\n if (!this.binary) {\r\n throw new Error('Binary not initialized');\r\n }\r\n\r\n return new Promise<ResponseEngine>((resolve, reject) => {\r\n const child = spawn(this.binary![binary as keyof BinaryType], [...this.arguments, ...args]);\r\n\r\n let stdoutBuffer = '';\r\n let stderrBuffer = '';\r\n let isResolved = false;\r\n\r\n const timeoutId = setTimeout(() => {\r\n if (!isResolved) {\r\n isResolved = true;\r\n child.kill();\r\n reject(new Error('Process timeout'));\r\n }\r\n }, this.timeout);\r\n\r\n const resolveOnce = (response: ResponseEngine) => {\r\n if (!isResolved) {\r\n isResolved = true;\r\n clearTimeout(timeoutId);\r\n resolve(response);\r\n }\r\n };\r\n\r\n // Framing por línea (la respuesta termina en '\\n'): un regex sobre\r\n // el buffer parcial fallaría con respuestas grandes fragmentadas\r\n const tryParseLines = (buffer: string): string => {\r\n let idx: number;\r\n while ((idx = buffer.indexOf('\\n')) !== -1) {\r\n const line = buffer.slice(0, idx);\r\n buffer = buffer.slice(idx + 1);\r\n const marker = line.indexOf('PROCESS_RESPONSE:');\r\n if (marker === -1) continue;\r\n try {\r\n const response: ProcessResponse = JSON.parse(line.slice(marker + 'PROCESS_RESPONSE:'.length));\r\n resolveOnce({\r\n status: response.status,\r\n message: response.message,\r\n data: response.data\r\n });\r\n } catch (error) {\r\n resolveOnce({\r\n status: 500,\r\n message: 'Failed to parse response JSON',\r\n data: null\r\n });\r\n }\r\n }\r\n return buffer;\r\n };\r\n\r\n child.stdout.on('data', (data) => {\r\n const text = data.toString();\r\n // Mostrar solo el chunk nuevo, sin la línea de protocolo\r\n const visible = text.split('\\n').filter((l: string) => l.trim() && !l.includes('PROCESS_RESPONSE:')).join('\\n');\r\n if (visible) console.log(visible);\r\n stdoutBuffer = tryParseLines(stdoutBuffer + text);\r\n });\r\n\r\n child.stderr.on('data', (data) => {\r\n const text = data.toString();\r\n // Logs de usuario del engine van por stderr\r\n const visible = text.split('\\n').filter((l: string) => l.trim() && !l.includes('PROCESS_RESPONSE:')).join('\\n');\r\n if (visible) console.log(visible);\r\n stderrBuffer = tryParseLines(stderrBuffer + text);\r\n });\r\n\r\n\r\n child.on('close', (code) => {\r\n clearTimeout(timeoutId);\r\n if (!isResolved) {\r\n resolveOnce({\r\n status: code === 0 ? 200 : 500,\r\n message: code === 0 ? 'Process completed' : `Process exited with code ${code}`,\r\n data: null\r\n });\r\n }\r\n });\r\n\r\n child.on('error', (error) => {\r\n clearTimeout(timeoutId);\r\n if (!isResolved) {\r\n resolveOnce({\r\n status: 500,\r\n message: `Process error: ${error.message}`,\r\n data: null\r\n });\r\n }\r\n });\r\n\r\n child.unref();\r\n });\r\n }\r\n}\r\n\r\nexport { Engine }","import * as os from 'os';\r\nimport * as path from 'path';\r\nimport * as fs from 'fs';\r\n\r\ninterface SystemInfo {\r\n platform: string;\r\n arch: string;\r\n release: string;\r\n type: string;\r\n endianness: string;\r\n cpus: number;\r\n}\r\n\r\ninterface BinaryInfo {\r\n name: string;\r\n path: string;\r\n exists: boolean;\r\n executable: boolean;\r\n}\r\n\r\nclass Arquitecture {\r\n private systemInfo: SystemInfo;\r\n\r\n constructor() {\r\n this.systemInfo = this.detectSystemInfo();\r\n }\r\n\r\n /**\r\n * Detecta información completa del sistema\r\n */\r\n private detectSystemInfo(): SystemInfo {\r\n return {\r\n platform: os.platform(),\r\n arch: os.arch(),\r\n release: os.release(),\r\n type: os.type(),\r\n endianness: os.endianness(),\r\n cpus: os.cpus().length\r\n };\r\n }\r\n\r\n /**\r\n * Obtiene la plataforma normalizada\r\n */\r\n getPlatform(): string {\r\n const platform = this.systemInfo.platform;\r\n \r\n switch (platform) {\r\n case 'win32':\r\n return 'windows';\r\n case 'darwin':\r\n return 'macos';\r\n case 'linux':\r\n return 'linux';\r\n case 'freebsd':\r\n return 'freebsd';\r\n case 'openbsd':\r\n return 'openbsd';\r\n case 'sunos':\r\n return 'solaris';\r\n default:\r\n return platform;\r\n }\r\n }\r\n\r\n /**\r\n * Obtiene la arquitectura normalizada\r\n */\r\n getArchitecture(): string {\r\n const arch = this.systemInfo.arch;\r\n \r\n switch (arch) {\r\n case 'x64':\r\n return 'x86_64';\r\n case 'x32':\r\n case 'ia32':\r\n return 'i686';\r\n case 'arm64':\r\n return 'aarch64';\r\n case 'arm':\r\n return 'armv7';\r\n case 'ppc64':\r\n return 'powerpc64';\r\n case 'ppc':\r\n return 'powerpc';\r\n case 's390x':\r\n return 's390x';\r\n case 'mips':\r\n return 'mips';\r\n case 'mipsel':\r\n return 'mipsel';\r\n default:\r\n return arch;\r\n }\r\n }\r\n\r\n /**\r\n * Genera el nombre del binario basado en la arquitectura\r\n */\r\n getBinaryName(baseName: string): string {\r\n const platform = this.getPlatform();\r\n const arch = this.getArchitecture();\r\n const extension = platform === 'windows' ? '.exe' : '';\r\n \r\n return `${baseName}-${platform}-${arch}${extension}`;\r\n }\r\n\r\n /**\r\n * Obtiene información completa del sistema\r\n */\r\n getSystemInfo(): SystemInfo {\r\n return { ...this.systemInfo };\r\n }\r\n\r\n /**\r\n * Obtiene el triple de destino (target triple) para Rust\r\n */\r\n getRustTargetTriple(): string {\r\n const platform = this.getPlatform();\r\n const arch = this.getArchitecture();\r\n \r\n // Mapeo de plataformas y arquitecturas a target triples de Rust\r\n const targetMap: { [key: string]: string } = {\r\n 'linux-x86_64': 'x86_64-unknown-linux-gnu',\r\n 'linux-i686': 'i686-unknown-linux-gnu',\r\n 'linux-aarch64': 'aarch64-unknown-linux-gnu',\r\n 'linux-armv7': 'armv7-unknown-linux-gnueabihf',\r\n 'macos-x86_64': 'x86_64-apple-darwin',\r\n 'macos-aarch64': 'aarch64-apple-darwin',\r\n 'windows-x86_64': 'x86_64-pc-windows-msvc',\r\n 'windows-i686': 'i686-pc-windows-msvc',\r\n 'windows-aarch64': 'aarch64-pc-windows-msvc',\r\n 'freebsd-x86_64': 'x86_64-unknown-freebsd',\r\n };\r\n \r\n const key = `${platform}-${arch}`;\r\n return targetMap[key] || `${arch}-unknown-${platform}`;\r\n }\r\n\r\n /**\r\n * Muestra información detallada del sistema\r\n */\r\n printSystemInfo(): void {\r\n console.log('🖥️ System Information:');\r\n console.log('├─ Platform:', this.getPlatform());\r\n console.log('├─ Arquitecture:', this.getArchitecture());\r\n console.log('├─ OS Type:', this.systemInfo.type);\r\n console.log('├─ OS Release:', this.systemInfo.release);\r\n console.log('├─ Endianness:', this.systemInfo.endianness);\r\n console.log('├─ CPUs:', this.systemInfo.cpus);\r\n console.log('└─ Rust Target:', this.getRustTargetTriple());\r\n }\r\n}\r\n\r\nexport { \r\n Arquitecture, \r\n SystemInfo,\r\n BinaryInfo\r\n};","import { BinaryType } from \"../@types/Binary\";\r\nimport { Arquitecture } from \"./Arquitecture\";\r\nimport * as fs from \"fs\";\r\nimport * as path from \"path\";\r\nimport * as os from \"os\";\r\nimport followRedirects from 'follow-redirects';\r\nconst { https } = followRedirects;\r\nimport * as unzipper from \"unzipper\";\r\nimport { IncomingMessage } from 'http';\r\nimport ora from \"ora\";\r\nimport chalk from \"chalk\";\r\nimport { fileURLToPath } from \"url\";\r\nimport { dirname } from \"path\";\r\n\r\ninterface DownloadProgress {\r\n downloaded: number;\r\n total: number;\r\n percentage: number;\r\n}\r\n\r\ninterface BinaryVersion {\r\n date_published: string;\r\n name: string;\r\n version: string;\r\n platforms: string[];\r\n download_url: string;\r\n}\r\n\r\nclass Downloader {\r\n private static mainSpinner: any = null;\r\n private static currentSpinner: any = null;\r\n private static readonly VERSION_URLS = {\r\n query: 'https://raw.githubusercontent.com/Dbcube/binaries/main/query-engines.json',\r\n schema: 'https://raw.githubusercontent.com/Dbcube/binaries/main/schema-engines.json',\r\n sqlite: 'https://raw.githubusercontent.com/Dbcube/binaries/main/sqlite-engines.json'\r\n };\r\n\r\n /**\r\n * Fetch latest version from GitHub\r\n */\r\n private static async fetchLatestVersion(prefix: 'query' | 'schema' | 'sqlite'): Promise<string> {\r\n const url = this.VERSION_URLS[prefix];\r\n\r\n return new Promise((resolve, reject) => {\r\n https.get(url, (response: IncomingMessage) => {\r\n let data = '';\r\n\r\n response.on('data', (chunk) => {\r\n data += chunk;\r\n });\r\n\r\n response.on('end', () => {\r\n try {\r\n const versions: BinaryVersion[] = JSON.parse(data);\r\n if (versions && versions.length > 0) {\r\n // Get the latest version (first in array)\r\n resolve(versions[0].version);\r\n } else {\r\n reject(new Error('No versions found'));\r\n }\r\n } catch (error) {\r\n reject(error);\r\n }\r\n });\r\n\r\n response.on('error', reject);\r\n }).on('error', reject);\r\n });\r\n }\r\n\r\n /**\r\n * Extract version from binary filename\r\n * Example: schema-engine-v1.0.0-windows-x64.exe -> v1.0.0\r\n */\r\n private static extractVersionFromFilename(filename: string): string | null {\r\n const match = filename.match(/-(v\\d+\\.\\d+\\.\\d+)-/);\r\n return match ? match[1] : null;\r\n }\r\n\r\n /**\r\n * Get local version of installed binary\r\n */\r\n private static getLocalVersion(binDir: string, prefix: string): string | null {\r\n try {\r\n const files = fs.readdirSync(binDir);\r\n const binaryPattern = new RegExp(`^${prefix}-engine-v`);\r\n const binaryFile = files.find(f => binaryPattern.test(f));\r\n\r\n if (binaryFile) {\r\n return this.extractVersionFromFilename(binaryFile);\r\n }\r\n } catch (error) {\r\n // Directory doesn't exist or can't read\r\n }\r\n return null;\r\n }\r\n\r\n /**\r\n * Compare versions (returns true if remote is newer)\r\n */\r\n private static isNewerVersion(localVersion: string | null, remoteVersion: string): boolean {\r\n if (!localVersion) return true; // No local version, download\r\n\r\n // Remove 'v' prefix if exists\r\n const cleanLocal = localVersion.replace(/^v/, '');\r\n const cleanRemote = remoteVersion.replace(/^v/, '');\r\n\r\n const localParts = cleanLocal.split('.').map(Number);\r\n const remoteParts = cleanRemote.split('.').map(Number);\r\n\r\n for (let i = 0; i < 3; i++) {\r\n if (remoteParts[i] > localParts[i]) return true;\r\n if (remoteParts[i] < localParts[i]) return false;\r\n }\r\n\r\n return false; // Versions are equal\r\n }\r\n\r\n /**\r\n * Delete old binary files\r\n */\r\n private static deleteOldBinary(binDir: string, prefix: string): void {\r\n try {\r\n const files = fs.readdirSync(binDir);\r\n const binaryPattern = new RegExp(`^${prefix}-engine-`);\r\n\r\n files.forEach(file => {\r\n if (binaryPattern.test(file)) {\r\n const filePath = path.join(binDir, file);\r\n try {\r\n fs.unlinkSync(filePath);\r\n console.log(`🗑️ Deleted old binary: ${file}`);\r\n } catch (err) {\r\n console.warn(`⚠️ Could not delete: ${file}`);\r\n }\r\n }\r\n });\r\n } catch (error) {\r\n // Ignore errors\r\n }\r\n }\r\n\r\n static get(prefix: string): BinaryType & { name: string; url: string; version: string } {\r\n const arch = new Arquitecture();\r\n const platform = arch.getPlatform();\r\n const architecture = arch.getArchitecture();\r\n\r\n const platformMap: Record<string, string> = {\r\n windows: \"windows\",\r\n linux: \"linux\",\r\n darwin: \"macos\"\r\n };\r\n\r\n const archMap: Record<string, string> = {\r\n x86_64: \"x64\",\r\n aarch64: \"arm64\"\r\n };\r\n\r\n const plat = platformMap[platform];\r\n const archSuffix = archMap[architecture];\r\n\r\n if (plat && archSuffix) {\r\n // Note: This is a sync method, version will be \"latest\" placeholder\r\n // The actual version will be resolved during download\r\n const baseName = `${prefix}-engine-${plat}-${archSuffix}`;\r\n const binaryName = platform === \"windows\" ? `${baseName}.exe` : baseName;\r\n\r\n const url = `https://github.com/Dbcube/binaries/releases/download/${prefix}-engine/${prefix}-engine-latest-${plat}-${archSuffix}.zip`;\r\n return {\r\n name: binaryName,\r\n url,\r\n version: \"latest\",\r\n query_engine: binaryName,\r\n schema_engine: `${prefix}-engine-${plat}-${archSuffix}${platform === \"windows\" ? \".exe\" : \"\"}`\r\n };\r\n }\r\n\r\n return {\r\n name: \"\",\r\n url: \"\",\r\n version: \"\",\r\n query_engine: \"\",\r\n schema_engine: \"\"\r\n };\r\n }\r\n\r\n /**\r\n * Get binary info with actual version from GitHub\r\n */\r\n static async getWithVersion(prefix: 'query' | 'schema' | 'sqlite'): Promise<BinaryType & { name: string; url: string; version: string }> {\r\n const arch = new Arquitecture();\r\n const platform = arch.getPlatform();\r\n const architecture = arch.getArchitecture();\r\n\r\n const platformMap: Record<string, string> = {\r\n windows: \"windows\",\r\n linux: \"linux\",\r\n darwin: \"macos\"\r\n };\r\n\r\n const archMap: Record<string, string> = {\r\n x86_64: \"x64\",\r\n aarch64: \"arm64\"\r\n };\r\n\r\n const plat = platformMap[platform];\r\n const archSuffix = archMap[architecture];\r\n\r\n if (plat && archSuffix) {\r\n // Fetch latest version from GitHub\r\n const version = await this.fetchLatestVersion(prefix);\r\n\r\n const baseName = `${prefix}-engine-${version}-${plat}-${archSuffix}`;\r\n const binaryName = platform === \"windows\" ? `${baseName}.exe` : baseName;\r\n\r\n const url = `https://github.com/Dbcube/binaries/releases/download/${prefix}-engine/${prefix}-engine-${version}-${plat}-${archSuffix}.zip`;\r\n return {\r\n name: binaryName,\r\n url,\r\n version,\r\n query_engine: binaryName,\r\n schema_engine: binaryName\r\n };\r\n }\r\n\r\n return {\r\n name: \"\",\r\n url: \"\",\r\n version: \"\",\r\n query_engine: \"\",\r\n schema_engine: \"\"\r\n };\r\n }\r\n\r\n static async download(targetDir?: string): Promise<void> {\r\n const binDir = targetDir || this.getDefaultBinDir();\r\n fs.mkdirSync(binDir, { recursive: true });\r\n\r\n // Initialize main spinner\r\n this.mainSpinner = ora({\r\n text: chalk.blue('Verificando versiones de binarios...'),\r\n spinner: 'dots12'\r\n }).start();\r\n\r\n const binariesToProcess: Array<{ prefix: 'query' | 'schema' | 'sqlite'; needsUpdate: boolean; localVersion: string | null; remoteVersion: string }> = [];\r\n\r\n // Check versions for all engines\r\n for (const prefix of ['query', 'schema', 'sqlite'] as const) {\r\n try {\r\n const localVersion = this.getLocalVersion(binDir, prefix);\r\n const remoteVersion = await this.fetchLatestVersion(prefix);\r\n const needsUpdate = this.isNewerVersion(localVersion, remoteVersion);\r\n\r\n binariesToProcess.push({\r\n prefix,\r\n needsUpdate,\r\n localVersion,\r\n remoteVersion\r\n });\r\n\r\n if (needsUpdate) {\r\n console.log(`\\n📦 ${prefix}-engine: ${localVersion || 'not installed'} → ${remoteVersion}`);\r\n } else if (localVersion) {\r\n console.log(`\\n✅ ${prefix}-engine: ${localVersion} (up to date)`);\r\n }\r\n } catch (error) {\r\n console.warn(`⚠️ Could not check version for ${prefix}-engine, will attempt download`);\r\n binariesToProcess.push({\r\n prefix,\r\n needsUpdate: true,\r\n localVersion: null,\r\n remoteVersion: 'latest'\r\n });\r\n }\r\n }\r\n\r\n const binariesToDownload = binariesToProcess.filter(b => b.needsUpdate);\r\n\r\n if (binariesToDownload.length === 0) {\r\n this.mainSpinner.succeed(chalk.green('All binaries are up to date'));\r\n return;\r\n }\r\n\r\n // Show update progress\r\n this.mainSpinner.text = chalk.blue(`Updating ${binariesToDownload.length} binary(ies)...`);\r\n\r\n try {\r\n // Download and update binaries in parallel. allSettled: si una\r\n // descarga falla las demás terminan igual y se reportan TODOS los\r\n // errores (Promise.all descartaba los resultados restantes).\r\n const results = await Promise.allSettled(binariesToDownload.map(async (binary) => {\r\n const maxRetries = 3;\r\n let attempt = 0;\r\n\r\n while (attempt <= maxRetries) {\r\n try {\r\n // Get binary info with version\r\n const binaryInfo = await this.getWithVersion(binary.prefix);\r\n\r\n if (!binaryInfo.name || !binaryInfo.url) {\r\n throw new Error(`Platform or architecture not supported for ${binary.prefix}`);\r\n }\r\n\r\n const tempZipPath = path.join(os.tmpdir(), `dbcube-${binary.prefix}-${Date.now()}.zip`);\r\n const finalBinaryPath = path.join(binDir, binaryInfo.name);\r\n\r\n // Delete old binary first\r\n this.deleteOldBinary(binDir, binary.prefix);\r\n\r\n // Download\r\n await this.downloadFileWithProgress(binaryInfo.url, tempZipPath, binary.prefix);\r\n\r\n // Extract\r\n await this.extractBinary(tempZipPath, finalBinaryPath, binary.prefix);\r\n\r\n console.log(`✅ ${binary.prefix}-engine updated to ${binary.remoteVersion}`);\r\n break;\r\n\r\n } catch (error: unknown) {\r\n const errorMessage = error instanceof Error ? error.message : 'Unknown error';\r\n\r\n if (attempt < maxRetries && (\r\n errorMessage.includes('ECONNRESET') ||\r\n errorMessage.includes('timeout') ||\r\n errorMessage.includes('ETIMEDOUT') ||\r\n errorMessage.includes('ENOTFOUND')\r\n )) {\r\n attempt++;\r\n console.log(`🔄 Retrying ${binary.prefix}-engine (${attempt}/${maxRetries})...`);\r\n await new Promise(resolve => setTimeout(resolve, 1000 + Math.random() * 1000));\r\n } else {\r\n throw new Error(`Error downloading ${binary.prefix}: ${errorMessage}`);\r\n }\r\n }\r\n }\r\n }));\r\n\r\n const failures = results.filter((r): r is PromiseRejectedResult => r.status === 'rejected');\r\n if (failures.length > 0) {\r\n const messages = failures.map(f => f.reason instanceof Error ? f.reason.message : String(f.reason));\r\n throw new Error(messages.join(' | '));\r\n }\r\n\r\n // Complete successfully\r\n this.mainSpinner.succeed(chalk.green('Binaries updated successfully'));\r\n } catch (error: unknown) {\r\n const errorMessage = error instanceof Error ? error.message : 'Unknown error';\r\n this.mainSpinner.fail(chalk.red(`Error updating binaries: ${errorMessage}`));\r\n throw error;\r\n }\r\n }\r\n\r\n private static updateMainProgress(binary: string, current: number, total: number, status: string, attempt?: number) {\r\n const progressBar = this.createProgressBar(current, total);\r\n const statusEmojis = {\r\n downloading: '📥',\r\n extracting: '📦',\r\n completed: '✅',\r\n exists: '✅',\r\n retrying: '🔄'\r\n };\r\n\r\n const statusMessages = {\r\n downloading: chalk.blue('descargando'),\r\n extracting: chalk.yellow('extrayendo'),\r\n completed: chalk.green('completado'),\r\n exists: chalk.gray('existe'),\r\n retrying: chalk.yellow(`reintentando (${attempt}/${3})`)\r\n };\r\n\r\n const emoji = statusEmojis[status as keyof typeof statusEmojis] || '📥';\r\n const message = statusMessages[status as keyof typeof statusMessages] || status;\r\n\r\n this.mainSpinner.text = `${progressBar} ${emoji} ${chalk.bold(binary)} - ${message}`;\r\n }\r\n\r\n private static createProgressBar(current: number, total: number, width: number = 20): string {\r\n const filled = Math.round((current / total) * width);\r\n const empty = width - filled;\r\n const filledBar = chalk.green('█'.repeat(filled));\r\n const emptyBar = chalk.gray('░'.repeat(empty));\r\n const percentage = chalk.bold(`${current}/${total}`);\r\n return `[${filledBar}${emptyBar}] ${percentage}`;\r\n }\r\n\r\n private static downloadFileWithProgress(url: string, outputPath: string, prefix: string): Promise<void> {\r\n return new Promise((resolve, reject) => {\r\n const request = https.get(url, { timeout: 0 }, (response: IncomingMessage) => {\r\n if (response.statusCode === 302 || response.statusCode === 301) {\r\n const redirectUrl = response.headers.location;\r\n if (redirectUrl) {\r\n return this.downloadFileWithProgress(redirectUrl, outputPath, prefix).then(resolve).catch(reject);\r\n }\r\n }\r\n\r\n if (response.statusCode !== 200) {\r\n reject(new Error(`HTTP ${response.statusCode} para ${prefix}`));\r\n return;\r\n }\r\n\r\n const file = fs.createWriteStream(outputPath);\r\n const totalBytes = parseInt(response.headers['content-length'] || '0', 10);\r\n let downloadedBytes = 0;\r\n\r\n response.on('data', (chunk) => {\r\n downloadedBytes += chunk.length;\r\n file.write(chunk);\r\n\r\n if (totalBytes > 0) {\r\n const progress: DownloadProgress = {\r\n downloaded: downloadedBytes,\r\n total: totalBytes,\r\n percentage: (downloadedBytes / totalBytes) * 100\r\n };\r\n this.updateDownloadProgress(prefix, progress);\r\n }\r\n });\r\n\r\n response.on('end', () => {\r\n // Resolver recién cuando el archivo está flushed a disco;\r\n // si no, extractBinary puede leer un ZIP incompleto\r\n file.end(() => resolve());\r\n });\r\n\r\n response.on('error', (err) => {\r\n file.close();\r\n this.cleanupFile(outputPath);\r\n reject(err);\r\n });\r\n\r\n file.on('error', (err) => {\r\n file.close();\r\n this.cleanupFile(outputPath);\r\n reject(err);\r\n });\r\n });\r\n\r\n request.on('error', reject);\r\n request.on('timeout', () => {\r\n request.destroy();\r\n reject(new Error(`Timeout descargando ${prefix}`));\r\n });\r\n });\r\n }\r\n\r\n private static updateDownloadProgress(binary: string, progress: DownloadProgress) {\r\n const percentage = progress.percentage.toFixed(1);\r\n const downloaded = (progress.downloaded / 1024 / 1024).toFixed(1);\r\n const total = (progress.total / 1024 / 1024).toFixed(1);\r\n\r\n // Create a mini progress bar for the binary\r\n const barWidth = 15;\r\n const filled = Math.round((progress.percentage / 100) * barWidth);\r\n const empty = barWidth - filled;\r\n const progressBar = chalk.green('█'.repeat(filled)) + chalk.gray('░'.repeat(empty));\r\n\r\n const progressText = `[${progressBar}] ${percentage}% (${downloaded}/${total}MB)`;\r\n this.mainSpinner.text = `📥 ${chalk.bold(binary)} - ${progressText}`;\r\n }\r\n\r\n private static extractBinary(zipPath: string, outputPath: string, prefix: string): Promise<void> {\r\n return new Promise((resolve, reject) => {\r\n let extracted = false;\r\n\r\n fs.createReadStream(zipPath)\r\n .pipe(unzipper.Parse())\r\n .on('entry', (entry: unzipper.Entry) => {\r\n if (entry.type === 'File' && !extracted) {\r\n extracted = true;\r\n const writeStream = fs.createWriteStream(outputPath);\r\n\r\n entry.pipe(writeStream);\r\n\r\n writeStream.on('finish', () => {\r\n if (process.platform !== 'win32') {\r\n fs.chmodSync(outputPath, 0o755);\r\n }\r\n this.cleanupFile(zipPath);\r\n resolve();\r\n });\r\n\r\n writeStream.on('error', (err: Error) => {\r\n this.cleanupFile(zipPath);\r\n reject(err);\r\n });\r\n } else {\r\n entry.autodrain();\r\n }\r\n })\r\n .on('error', (err: Error) => {\r\n this.cleanupFile(zipPath);\r\n reject(err);\r\n })\r\n .on('close', () => {\r\n if (!extracted) {\r\n this.cleanupFile(zipPath);\r\n reject(new Error(`No se encontró archivo válido en el ZIP para ${prefix}`));\r\n }\r\n });\r\n });\r\n }\r\n\r\n private static cleanupFile(filePath: string): void {\r\n try {\r\n if (fs.existsSync(filePath)) {\r\n fs.unlinkSync(filePath);\r\n }\r\n } catch {\r\n // Ignore cleanup errors\r\n }\r\n }\r\n\r\n private static getDefaultBinDir(): string {\r\n // Get __dirname equivalent for ESM\r\n const __filename = typeof import.meta !== 'undefined' && import.meta.url\r\n ? fileURLToPath(import.meta.url)\r\n : '';\r\n const __dirname = __filename ? dirname(__filename) : process.cwd();\r\n\r\n // Try to find a suitable directory for binaries in order of preference\r\n const possibleDirs = [\r\n path.resolve(process.cwd(), '.dbcube', 'bin'),\r\n path.resolve(process.cwd(), 'node_modules', '.dbcube', 'bin'),\r\n path.resolve(__dirname, '..', 'bin'),\r\n ];\r\n\r\n // Use the first one that can be created or already exists\r\n for (const dir of possibleDirs) {\r\n try {\r\n if (!fs.existsSync(dir)) {\r\n fs.mkdirSync(dir, { recursive: true });\r\n }\r\n // Test write permissions\r\n const testFile = path.join(dir, '.test');\r\n fs.writeFileSync(testFile, 'test');\r\n fs.unlinkSync(testFile);\r\n return dir;\r\n } catch {\r\n // Try next directory\r\n continue;\r\n }\r\n }\r\n\r\n // Fallback to .dbcube directory in temp\r\n const tempDir = path.join(os.tmpdir(), '.dbcube', 'bin');\r\n fs.mkdirSync(tempDir, { recursive: true });\r\n return tempDir;\r\n }\r\n}\r\n\r\nexport { Downloader };","import { BinaryType } from \"../@types/Binary\";\r\nimport { Arquitecture } from \"./Arquitecture\"\r\nimport { Downloader } from \"./Donwloader\";\r\nimport * as fs from \"fs\";\r\nimport * as path from \"path\";\r\nimport * as os from \"os\";\r\nimport { fileURLToPath } from \"url\";\r\nimport { dirname } from \"path\";\r\n\r\nclass Binary{\r\n private static isDownloading = false;\r\n private static downloadPromise: Promise<void> | null = null;\r\n private static cachedBinaries: { [key: string]: string } = {};\r\n\r\n static async ensureBinariesExist(): Promise<void> {\r\n if (this.isDownloading && this.downloadPromise) {\r\n await this.downloadPromise;\r\n return;\r\n }\r\n\r\n const binDir = this.getBinDir();\r\n\r\n // Always check and download/update binaries\r\n if (!this.isDownloading) {\r\n this.isDownloading = true;\r\n this.downloadPromise = this.downloadBinaries();\r\n\r\n try {\r\n await this.downloadPromise;\r\n } finally {\r\n this.isDownloading = false;\r\n this.downloadPromise = null;\r\n }\r\n }\r\n }\r\n\r\n private static async downloadBinaries(): Promise<void> {\r\n try {\r\n const binDir = this.getBinDir();\r\n await Downloader.download(binDir);\r\n } catch (error) {\r\n console.warn('⚠️ Dbcube: Error descargando binarios:', (error as Error).message);\r\n console.log('🔧 Los binarios se intentarán descargar en la próxima ejecución');\r\n }\r\n }\r\n\r\n private static getBinDir(): string {\r\n // Get __dirname equivalent for ESM\r\n const __filename = typeof import.meta !== 'undefined' && import.meta.url\r\n ? fileURLToPath(import.meta.url)\r\n : '';\r\n const __dirname = __filename ? dirname(__filename) : process.cwd();\r\n\r\n // Try to find a suitable directory for binaries in order of preference\r\n const possibleDirs = [\r\n path.resolve(process.cwd(), '.dbcube', 'bin'),\r\n path.resolve(process.cwd(), 'node_modules', '.dbcube', 'bin'),\r\n path.resolve(__dirname, '..', 'bin'),\r\n ];\r\n\r\n // Use the first one that can be created or already exists\r\n for (const dir of possibleDirs) {\r\n try {\r\n if (!fs.existsSync(dir)) {\r\n fs.mkdirSync(dir, { recursive: true });\r\n }\r\n \r\n \r\n return dir;\r\n } catch {\r\n // Try next directory\r\n continue;\r\n }\r\n }\r\n\r\n // Fallback to .dbcube directory in temp\r\n const tempDir = path.join(os.tmpdir(), '.dbcube', 'bin');\r\n fs.mkdirSync(tempDir, { recursive: true });\r\n return tempDir;\r\n }\r\n\r\n\r\n private static findVersionedBinary(binDir: string, prefix: string, platform: string, arch: string): string {\r\n // Check cache first\r\n const cacheKey = `${prefix}-${platform}-${arch}`;\r\n if (this.cachedBinaries[cacheKey]) {\r\n const cachedPath = path.join(binDir, this.cachedBinaries[cacheKey]);\r\n if (fs.existsSync(cachedPath)) {\r\n return cachedPath;\r\n }\r\n }\r\n\r\n try {\r\n const files = fs.readdirSync(binDir);\r\n const extension = platform === 'windows' ? '.exe' : '';\r\n const pattern = new RegExp(`^${prefix}-engine-v\\\\d+\\\\.\\\\d+\\\\.\\\\d+-${platform}-${arch}${extension.replace('.', '\\\\.')}$`);\r\n\r\n const matchingFile = files.find(f => pattern.test(f));\r\n\r\n if (matchingFile) {\r\n this.cachedBinaries[cacheKey] = matchingFile;\r\n return path.join(binDir, matchingFile);\r\n }\r\n } catch (error) {\r\n // Directory doesn't exist or can't read\r\n }\r\n\r\n // Fallback to non-versioned name (for backwards compatibility)\r\n const fallbackName = `${prefix}-engine-${platform}-${arch}${platform === 'windows' ? '.exe' : ''}`;\r\n return path.join(binDir, fallbackName);\r\n }\r\n\r\n static async get(): Promise<BinaryType> {\r\n await this.ensureBinariesExist();\r\n\r\n const arch = new Arquitecture();\r\n const platform = arch.getPlatform();\r\n const architecture = arch.getArchitecture();\r\n const binDir = this.getBinDir();\r\n\r\n const platformMap: Record<string, string> = {\r\n windows: \"windows\",\r\n linux: \"linux\",\r\n darwin: \"macos\"\r\n };\r\n\r\n const archMap: Record<string, string> = {\r\n x86_64: \"x64\",\r\n aarch64: \"arm64\"\r\n };\r\n\r\n const plat = platformMap[platform];\r\n const archSuffix = archMap[architecture];\r\n\r\n if (plat && archSuffix) {\r\n return {\r\n query_engine: this.findVersionedBinary(binDir, 'query', plat, archSuffix),\r\n schema_engine: this.findVersionedBinary(binDir, 'schema', plat, archSuffix)\r\n };\r\n }\r\n\r\n return {\r\n query_engine: \"\",\r\n schema_engine: \"\"\r\n };\r\n }\r\n}\r\n\r\nexport { Binary }","/**\n * Connection parameters for one database.\n */\nexport interface DatabaseConnectionConfig {\n /** Host name or IP (not used by SQLite) */\n HOST?: string;\n /** Database user (not used by SQLite) */\n USER?: string;\n /** Database password (not used by SQLite) */\n PASSWORD?: string;\n /** Database name (SQLite: file name without extension) */\n DATABASE: string;\n /** Port (not used by SQLite) */\n PORT?: number | string;\n}\n\n/**\n * Connection-pool tuning. Every field is optional — engine defaults apply\n * when omitted (maxConnections 5 — 10 for SQLite —, minConnections 2,\n * acquireTimeoutMs 3000, idleTimeoutMs 3600000).\n */\nexport interface DatabasePoolConfig {\n /** Max simultaneous connections held by the engine pool */\n maxConnections?: number;\n /** Connections kept warm even when idle */\n minConnections?: number;\n /** How long to wait for a free connection before failing (ms) */\n acquireTimeoutMs?: number;\n /** Close connections idle longer than this (ms) */\n idleTimeoutMs?: number;\n}\n\n/**\n * Daemon-mode tuning.\n */\nexport interface DatabaseDaemonConfig {\n /** Set to false to disable the persistent TCP daemon (one-shot mode).\n * Transactions require the daemon. Equivalent to DBCUBE_DAEMON=0. */\n enabled?: boolean;\n /** Per-request timeout against the daemon (ms, default 30000) */\n requestTimeoutMs?: number;\n}\n\nexport type DatabaseType = 'mysql' | 'postgres' | 'postgresql' | 'sqlite' | 'mongodb';\n\n/**\n * One database entry in dbcube.config.js.\n */\nexport interface DatabaseDefinition {\n type: DatabaseType;\n config: DatabaseConnectionConfig;\n pool?: DatabasePoolConfig;\n daemon?: DatabaseDaemonConfig;\n}\n\n/**\n * Shape accepted by config.set().\n */\nexport interface ConfigData {\n databases?: Record<string, DatabaseDefinition>;\n [key: string]: unknown;\n}\n\n/**\n * Clase para manejar la configuración del ORM\n */\nexport class Config {\n private data: ConfigData = {};\n private databases: Record<string, DatabaseDefinition> = {};\n\n /**\n * Establece la configuración\n * @param configData - Datos de configuración\n */\n set(configData: ConfigData): void {\n this.data = configData;\n\n if (configData.databases) {\n this.databases = configData.databases;\n }\n }\n\n /**\n * Obtiene un valor de configuración\n * @param key - Clave de configuración\n */\n get<T = unknown>(key: string): T {\n return this.data[key] as T;\n }\n\n /**\n * Obtiene la configuración de una base de datos específica\n * @param dbName - Nombre de la base de datos\n */\n getDatabase(dbName: string): DatabaseDefinition | null {\n return this.databases[dbName] || null;\n }\n\n /**\n * Obtiene todas las bases de datos configuradas\n */\n getAllDatabases(): Record<string, DatabaseDefinition> {\n return this.databases;\n }\n}\n\nexport default Config;\n","import net from 'net';\nimport fs from 'fs';\nimport path from 'path';\nimport { spawn } from 'child_process';\n\ninterface DaemonResponse {\n status: number;\n message: string;\n data: any;\n}\n\ninterface PendingRequest {\n resolve: (r: DaemonResponse) => void;\n reject: (e: Error) => void;\n timer: NodeJS.Timeout;\n}\n\n/**\n * TCP client for the query-engine daemon (server mode).\n *\n * Instead of spawning a new engine process per query (30-80ms overhead),\n * the daemon keeps the engine alive with warm connection pools and serves\n * requests over a local TCP socket in <1ms. One daemon per database name.\n */\nexport class DaemonClient {\n private static registry: Map<string, DaemonClient> = new Map();\n\n private name: string;\n private binaryPath: string;\n private engineArgs: string[];\n private socket: net.Socket | null = null;\n private buffer = '';\n private pending: PendingRequest[] = [];\n private starting: Promise<boolean> | null = null;\n private requestTimeout: number;\n\n private constructor(name: string, binaryPath: string, engineArgs: string[], requestTimeout = 30000) {\n this.name = name;\n this.binaryPath = binaryPath;\n this.engineArgs = engineArgs;\n this.requestTimeout = requestTimeout;\n }\n\n static get(name: string, binaryPath: string, engineArgs: string[]): DaemonClient {\n let client = this.registry.get(name);\n if (!client) {\n client = new DaemonClient(name, binaryPath, engineArgs);\n this.registry.set(name, client);\n }\n return client;\n }\n\n static isEnabled(): boolean {\n const flag = process.env.DBCUBE_DAEMON;\n if (flag === '0' || flag === 'false') return false;\n return true; // ON by default — fastest path with automatic fallback\n }\n\n private portfilePath(): string {\n return path.join(process.cwd(), '.dbcube', 'daemon', `${this.name}.json`);\n }\n\n private lockfilePath(): string {\n return path.join(process.cwd(), '.dbcube', 'daemon', `${this.name}.lock`);\n }\n\n /**\n * Exclusive-create lock so two processes never spawn two daemons for the\n * same database at once. Stale locks (crashed starter) expire after 15s.\n */\n private acquireSpawnLock(): boolean {\n const lockPath = this.lockfilePath();\n try {\n fs.mkdirSync(path.dirname(lockPath), { recursive: true });\n const fd = fs.openSync(lockPath, 'wx');\n fs.writeSync(fd, String(process.pid));\n fs.closeSync(fd);\n return true;\n } catch {\n try {\n const age = Date.now() - fs.statSync(lockPath).mtimeMs;\n if (age > 15000) {\n fs.unlinkSync(lockPath);\n return this.acquireSpawnLock();\n }\n } catch { /* lock vanished between checks */ }\n return false;\n }\n }\n\n private releaseSpawnLock(): void {\n try { fs.unlinkSync(this.lockfilePath()); } catch { /* already gone */ }\n }\n\n /**\n * Ensures a usable daemon connection. Returns false when the daemon\n * can't be used (old binary, startup failure) so callers fall back\n * to one-shot spawn mode.\n */\n async ensure(): Promise<boolean> {\n if (this.socket && !this.socket.destroyed) return true;\n if (this.starting) return this.starting;\n\n this.starting = this.connectOrStart().catch(() => false);\n const result = await this.starting;\n this.starting = null;\n return result;\n }\n\n private async connectOrStart(): Promise<boolean> {\n // 1. Try an existing daemon via portfile\n const port = this.readPortfile();\n if (port && await this.tryConnect(port)) return true;\n\n // 2. Stale portfile — remove and start a fresh daemon. The spawn lock\n // ensures only one process boots the daemon; the rest just wait for\n // the new portfile to appear.\n const gotLock = this.acquireSpawnLock();\n try {\n if (gotLock) {\n try { fs.unlinkSync(this.portfilePath()); } catch { /* not there */ }\n this.spawnDaemon();\n }\n\n // 3. Poll the portfile while the daemon boots (up to 10s)\n const deadline = Date.now() + 10000;\n while (Date.now() < deadline) {\n await new Promise(r => setTimeout(r, 150));\n const newPort = this.readPortfile();\n if (newPort && await this.tryConnect(newPort)) return true;\n }\n return false;\n } finally {\n if (gotLock) this.releaseSpawnLock();\n }\n }\n\n private readPortfile(): number | null {\n try {\n const raw = fs.readFileSync(this.portfilePath(), 'utf8');\n const info = JSON.parse(raw);\n const port = info?.port;\n return Number.isInteger(port) && port > 0 && port <= 65535 ? port : null;\n } catch {\n return null;\n }\n }\n\n private spawnDaemon(): void {\n const child = spawn(this.binaryPath, [...this.engineArgs, '--action', 'server', '--tcp-port', '9944'], {\n detached: true,\n stdio: 'ignore',\n cwd: process.cwd(),\n });\n child.unref();\n }\n\n private tryConnect(port: number): Promise<boolean> {\n return new Promise((resolve) => {\n const socket = net.createConnection({ host: '127.0.0.1', port }, async () => {\n socket.setNoDelay(true);\n this.attach(socket);\n // Verify it's a current-generation daemon (supports ping).\n // Short timeout: if the port was reused by an unrelated\n // process, we must not hang the full request timeout.\n try {\n const pong = await this.send({ action: 'ping' }, 2000);\n resolve(pong.status === 200);\n } catch {\n this.detach();\n resolve(false);\n }\n });\n socket.once('error', () => resolve(false));\n socket.setTimeout(3000, () => { socket.destroy(); resolve(false); });\n });\n }\n\n private attach(socket: net.Socket): void {\n this.socket = socket;\n this.buffer = '';\n socket.setTimeout(0);\n socket.on('data', (chunk: Buffer | string) => this.onData(Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk)));\n socket.on('close', () => this.detach());\n socket.on('error', () => this.detach());\n }\n\n private detach(): void {\n if (this.socket) {\n this.socket.removeAllListeners();\n this.socket.destroy();\n this.socket = null;\n }\n // Fail anything still in flight\n for (const req of this.pending.splice(0)) {\n clearTimeout(req.timer);\n req.reject(new Error('Daemon connection lost'));\n }\n }\n\n private onData(chunk: Buffer): void {\n this.buffer += chunk.toString('utf8');\n let idx: number;\n while ((idx = this.buffer.indexOf('\\n')) !== -1) {\n const line = this.buffer.slice(0, idx).trim();\n this.buffer = this.buffer.slice(idx + 1);\n if (!line) continue;\n const marker = line.indexOf('PROCESS_RESPONSE:');\n if (marker === -1) continue; // engine log noise\n const jsonPart = line.slice(marker + 'PROCESS_RESPONSE:'.length);\n const req = this.pending.shift();\n if (!req) continue;\n clearTimeout(req.timer);\n try {\n req.resolve(JSON.parse(jsonPart));\n } catch (e: any) {\n req.reject(new Error(`Invalid daemon response: ${e.message}`));\n }\n }\n }\n\n /**\n * Sends a request to the daemon. Responses arrive in FIFO order on the\n * single socket, so pending requests resolve in send order.\n */\n send(payload: Record<string, any>, timeoutMs?: number): Promise<DaemonResponse> {\n return new Promise((resolve, reject) => {\n if (!this.socket || this.socket.destroyed) {\n reject(new Error('Daemon not connected'));\n return;\n }\n const timer = setTimeout(() => {\n const i = this.pending.findIndex(p => p.timer === timer);\n if (i !== -1) this.pending.splice(i, 1);\n reject(new Error('Daemon request timeout'));\n // La respuesta tardía de este request llegaría igual y se\n // emparejaría con el siguiente pending (FIFO desincronizado,\n // datos cruzados). La conexión ya no es confiable: descartarla.\n this.detach();\n }, timeoutMs ?? this.requestTimeout);\n\n this.pending.push({ resolve, reject, timer });\n this.socket.write(JSON.stringify(payload) + '\\n');\n });\n }\n\n async execute(dml: object, txId?: string): Promise<DaemonResponse> {\n const payload: Record<string, any> = { action: 'execute', dml: JSON.stringify(dml) };\n if (txId) payload.tx_id = txId;\n return this.send(payload);\n }\n\n async raw(query: string, params: any[] = [], txId?: string): Promise<DaemonResponse> {\n const payload: Record<string, any> = { action: 'raw', query, params };\n if (txId) payload.tx_id = txId;\n return this.send(payload);\n }\n\n async begin(): Promise<string> {\n const res = await this.send({ action: 'begin' });\n if (res.status !== 200 || !res.data?.tx_id) {\n throw new Error(res.message || 'Failed to begin transaction');\n }\n return res.data.tx_id;\n }\n\n async commit(txId: string): Promise<void> {\n const res = await this.send({ action: 'commit', tx_id: txId });\n if (res.status !== 200) throw new Error(res.message || 'Failed to commit transaction');\n }\n\n async rollback(txId: string): Promise<void> {\n const res = await this.send({ action: 'rollback', tx_id: txId });\n if (res.status !== 200) throw new Error(res.message || 'Failed to rollback transaction');\n }\n\n async shutdown(): Promise<void> {\n try { await this.send({ action: 'shutdown' }); } catch { /* daemon exits mid-response */ }\n this.detach();\n try { fs.unlinkSync(this.portfilePath()); } catch { /* already gone */ }\n }\n}\n\nexport default DaemonClient;\n","import path from \"path\";\r\nimport { Binary } from \"./Binary\";\r\nimport { Config as ConfigClass } from './Config';\r\nimport { ProcessResponse, ResponseEngine } from \"../@types/Engine\";\r\nimport { BinaryType } from \"../@types/Binary\";\r\nimport { createRequire } from 'module';\r\nimport * as net from 'net';\r\nimport { spawn, ChildProcess } from \"child_process\";\r\n\r\n// Almacén global de servidores TCP y conexiones persistentes\r\nconst globalTcpServers = new Map<string, { port: number, process: ChildProcess | null }>();\r\nconst globalTcpConnections = new Map<string, net.Socket | null>();\r\n\r\n// Cola de peticiones para cada conexión (evita race conditions)\r\nconst connectionQueues = new Map<string, Array<{\r\n command: Record<string, any>,\r\n resolve: (value: any) => void,\r\n reject: (reason: any) => void\r\n}>>();\r\nconst connectionProcessing = new Map<string, boolean>();\r\n\r\n// Query Cache para evitar JSON.parse repetido\r\nconst queryCache = new Map<string, any>();\r\nconst MAX_CACHE_SIZE = 500;\r\n\r\nclass QueryEngine {\r\n private name: string;\r\n private config: any;\r\n private arguments: any;\r\n private binary: BinaryType | null = null;\r\n private timeout: number;\r\n private connectionId: string;\r\n private tcpPort: number;\r\n\r\n constructor(name: string, timeout = 30000) {\r\n this.name = name;\r\n this.config = this.setConfig(name);\r\n this.arguments = this.setArguments();\r\n // daemon.requestTimeoutMs de dbcube.config.js manda sobre el default\r\n this.timeout = this.config?.daemon?.requestTimeoutMs ?? timeout;\r\n this.connectionId = `${name}_query_engine_${this.config.type}_${this.config.config.DATABASE}_${this.config.config.HOST || 'localhost'}`;\r\n this.tcpPort = this.generatePort();\r\n }\r\n\r\n private generatePort(): number {\r\n // Empezar desde el puerto 9944 y buscar hacia abajo\r\n return 9944;\r\n }\r\n\r\n private async findAvailablePort(startPort: number): Promise<number> {\r\n for (let port = startPort; port >= 9900; port--) {\r\n if (await this.isPortAvailable(port)) {\r\n return port;\r\n }\r\n }\r\n throw new Error('No available ports found in range 9900-9944');\r\n }\r\n\r\n private isPortAvailable(port: number): Promise<boolean> {\r\n return new Promise((resolve) => {\r\n const tester = net.createServer();\r\n\r\n tester.once('error', () => resolve(false));\r\n tester.once('listening', () => {\r\n tester.close();\r\n resolve(true);\r\n });\r\n\r\n tester.listen(port, '127.0.0.1');\r\n });\r\n }\r\n\r\n async initializeBinary(): Promise<void> {\r\n if (!this.binary) {\r\n this.binary = await Binary.get();\r\n }\r\n }\r\n\r\n setArguments() {\r\n let args = [];\r\n if (this.config.type == 'sqlite') {\r\n args = [\r\n '--id', 'dbcube-' + this.name,\r\n '--database-ref', this.name,\r\n '--database', this.config.config.DATABASE + \".db\",\r\n '--motor', this.config.type\r\n ];\r\n } else {\r\n args = [\r\n '--id', 'dbcube-' + this.name,\r\n '--database-ref', this.name,\r\n '--database', this.config.config.DATABASE,\r\n '--host', this.config.config.HOST,\r\n '--port', String(this.config.config.PORT),\r\n '--motor', this.config.type\r\n ];\r\n // Credenciales opcionales (p. ej. MongoDB local sin auth)\r\n if (this.config.config.USER != null && this.config.config.USER !== '') {\r\n args.push('--user', this.config.config.USER);\r\n }\r\n if (this.config.config.PASSWORD != null && this.config.config.PASSWORD !== '') {\r\n args.push('--password', this.config.config.PASSWORD);\r\n }\r\n }\r\n\r\n // Tuning de pool desde la sección `pool` de dbcube.config.js\r\n const pool = this.config.pool ?? {};\r\n if (pool.maxConnections != null) args.push('--max-connections', String(pool.maxConnections));\r\n if (pool.minConnections != null) args.push('--min-connections', String(pool.minConnections));\r\n if (pool.acquireTimeoutMs != null) args.push('--acquire-timeout-ms', String(pool.acquireTimeoutMs));\r\n if (pool.idleTimeoutMs != null) args.push('--idle-timeout-ms', String(pool.idleTimeoutMs));\r\n\r\n return args;\r\n }\r\n\r\n /** El daemon puede desactivarse por config (daemon.enabled=false) o por env (DBCUBE_DAEMON=0). */\r\n private daemonEnabled(): boolean {\r\n const flag = process.env.DBCUBE_DAEMON;\r\n if (flag === '0' || flag === 'false') return false;\r\n return this.config?.daemon?.enabled !== false;\r\n }\r\n\r\n setConfig(name: string) {\r\n const configInstance = new ConfigClass();\r\n\r\n try {\r\n const configFilePath = path.resolve(process.cwd(), 'dbcube.config.js');\r\n const requireUrl = typeof __filename !== 'undefined' ? __filename : process.cwd();\r\n const require = createRequire(requireUrl);\r\n // Clear require cache to ensure fresh load (safe check for bundled environments)\r\n if (require.cache && require.resolve) {\r\n try {\r\n delete require.cache[require.resolve(configFilePath)];\r\n } catch (e) {\r\n // Ignore errors in bundled environments\r\n }\r\n }\r\n const configModule = require(configFilePath);\r\n const configFn = configModule.default || configModule;\r\n\r\n if (typeof configFn === 'function') {\r\n configFn(configInstance);\r\n } else {\r\n console.error('❌ El archivo dbcube.config.js no exporta una función.');\r\n }\r\n } catch (error: any) {\r\n console.error('❌ Error loading config file:', error.message);\r\n if (error.code === 'MODULE_NOT_FOUND') {\r\n console.error('❌ Config file not found, please create a dbcube.config.js file');\r\n }\r\n }\r\n\r\n return configInstance.getDatabase(name);\r\n }\r\n\r\n getConfig() {\r\n return this.config;\r\n }\r\n\r\n async run(binary: string, args: string[]): Promise<ResponseEngine> {\r\n // Detectar si es una acción execute de query_engine\r\n const actionIndex = args.findIndex(arg => arg === '--action');\r\n const isExecuteAction = actionIndex !== -1 && args[actionIndex + 1] === 'execute';\r\n const isQueryEngine = binary === 'query_engine';\r\n\r\n if (isQueryEngine && isExecuteAction) {\r\n // Solo query_engine con execute usa servidor TCP con cola\r\n return this.executeWithTcpServer(this.argsToCommand(args));\r\n } else {\r\n // Para otras acciones, usar método normal\r\n return this.createProcess(binary, args);\r\n }\r\n }\r\n\r\n private argsToCommand(args: string[]): Record<string, any> {\r\n const command: Record<string, any> = {};\r\n for (let i = 0; i < args.length; i += 2) {\r\n if (args[i].startsWith('--')) {\r\n command[args[i].substring(2)] = args[i + 1];\r\n }\r\n }\r\n return command;\r\n }\r\n\r\n /**\r\n * Executes a DML plan over the persistent TCP server.\r\n * Pass txId to run it inside an active transaction.\r\n */\r\n async executeDml(dml: object, txId?: string): Promise<ResponseEngine> {\r\n const command: Record<string, any> = { action: 'execute', dml: JSON.stringify(dml) };\r\n if (txId) command.tx_id = txId;\r\n return this.executeWithTcpServer(command);\r\n }\r\n\r\n /**\r\n * Executes raw SQL (or a MongoDB command document) with bound parameters\r\n * over the persistent TCP server.\r\n */\r\n async rawQuery(query: string, params: any[] = [], txId?: string): Promise<ResponseEngine> {\r\n const command: Record<string, any> = { action: 'raw', query, params };\r\n if (txId) command.tx_id = txId;\r\n return this.executeWithTcpServer(command);\r\n }\r\n\r\n /** Starts a server-side transaction and returns its id. */\r\n async beginTransaction(): Promise<string> {\r\n const res = await this.executeWithTcpServer({ action: 'begin' });\r\n if (res.status !== 200 || !res.data?.tx_id) {\r\n throw new Error(String(res.message || 'Failed to begin transaction (update the query-engine binary: npx dbcube update)'));\r\n }\r\n return res.data.tx_id;\r\n }\r\n\r\n async commitTransaction(txId: string): Promise<void> {\r\n const res = await this.executeWithTcpServer({ action: 'commit', tx_id: txId });\r\n if (res.status !== 200) throw new Error(String(res.message || 'Failed to commit transaction'));\r\n }\r\n\r\n async rollbackTransaction(txId: string): Promise<void> {\r\n const res = await this.executeWithTcpServer({ action: 'rollback', tx_id: txId });\r\n if (res.status !== 200) throw new Error(String(res.message || 'Failed to rollback transaction'));\r\n }\r\n\r\n private async executeWithTcpServer(command: Record<string, any>): Promise<ResponseEngine> {\r\n // Daemon desactivado: ejecutar one-shot por spawn. Las transacciones\r\n // requieren el daemon (la TX vive en su memoria entre requests).\r\n if (!this.daemonEnabled()) {\r\n if (command.tx_id || ['begin', 'commit', 'rollback'].includes(command.action)) {\r\n throw new Error('Transactions require daemon mode. Remove daemon.enabled=false from dbcube.config.js (or unset DBCUBE_DAEMON=0).');\r\n }\r\n const args: string[] = [];\r\n for (const [key, value] of Object.entries(command)) {\r\n args.push(`--${key.replace(/_/g, '-')}`, typeof value === 'string' ? value : JSON.stringify(value));\r\n }\r\n return this.createProcess('query_engine', args);\r\n }\r\n\r\n const serverInfo = globalTcpServers.get(this.connectionId);\r\n\r\n // Si no hay servidor TCP, iniciarlo\r\n if (!serverInfo || !serverInfo.process || serverInfo.process.killed) {\r\n await this.startTcpServer();\r\n // Solo verificar la primera vez\r\n await this.waitForServerReady();\r\n }\r\n\r\n // Enviar consulta via TCP con sistema de cola\r\n return this.sendTcpRequestFast(command);\r\n }\r\n\r\n private async waitForServerReady(): Promise<void> {\r\n const maxRetries = 10;\r\n const retryDelay = 500; // 500ms entre intentos\r\n\r\n const serverInfo = globalTcpServers.get(this.connectionId);\r\n if (!serverInfo) {\r\n throw new Error('Server not found');\r\n }\r\n\r\n for (let i = 0; i < maxRetries; i++) {\r\n if (await this.isServerResponding(serverInfo.port)) {\r\n return;\r\n }\r\n await this.sleep(retryDelay);\r\n }\r\n throw new Error('TCP server failed to become ready within timeout');\r\n }\r\n\r\n private async isServerResponding(port: number): Promise<boolean> {\r\n return new Promise((resolve) => {\r\n const client = new net.Socket();\r\n const timeout = setTimeout(() => {\r\n client.destroy();\r\n resolve(false);\r\n }, 1000);\r\n\r\n client.connect(port, '127.0.0.1', () => {\r\n clearTimeout(timeout);\r\n client.destroy();\r\n resolve(true);\r\n });\r\n\r\n client.on('error', () => {\r\n clearTimeout(timeout);\r\n resolve(false);\r\n });\r\n });\r\n }\r\n\r\n private sleep(ms: number): Promise<void> {\r\n return new Promise(resolve => setTimeout(resolve, ms));\r\n }\r\n\r\n private getCachedDML(dmlJson: string): any {\r\n // Buscar en cache primero\r\n if (queryCache.has(dmlJson)) {\r\n return queryCache.get(dmlJson);\r\n }\r\n\r\n // Parse y guardar en cache, desalojando la entrada más vieja si está\r\n // lleno (Map conserva orden de inserción)\r\n const parsed = JSON.parse(dmlJson);\r\n\r\n if (queryCache.size >= MAX_CACHE_SIZE) {\r\n const oldest = queryCache.keys().next().value;\r\n if (oldest !== undefined) queryCache.delete(oldest);\r\n }\r\n queryCache.set(dmlJson, parsed);\r\n\r\n return parsed;\r\n }\r\n\r\n private async startTcpServer(): Promise<void> {\r\n await this.initializeBinary();\r\n\r\n if (!this.binary) {\r\n throw new Error('Binary not initialized');\r\n }\r\n\r\n // Buscar puerto disponible\r\n this.tcpPort = await this.findAvailablePort(this.tcpPort);\r\n\r\n return new Promise((resolve, reject) => {\r\n // Iniciar el query_engine como servidor TCP\r\n const serverArgs = [...this.arguments, '--action', 'server', '--tcp-port', this.tcpPort.toString()];\r\n const serverProcess = spawn(this.binary!['query_engine' as keyof BinaryType], serverArgs);\r\n\r\n let started = false;\r\n\r\n const timeout = setTimeout(() => {\r\n if (!started) {\r\n serverProcess.kill();\r\n reject(new Error('TCP server startup timeout'));\r\n }\r\n }, 15000); // Aumentar timeout a 15 segundos\r\n\r\n serverProcess.stdout.on('data', (data) => {\r\n const output = data.toString();\r\n\r\n if (output.includes('TCP Server listening on')) {\r\n if (!started) {\r\n started = true;\r\n clearTimeout(timeout);\r\n globalTcpServers.set(this.connectionId, {\r\n port: this.tcpPort,\r\n process: serverProcess\r\n });\r\n resolve();\r\n }\r\n }\r\n });\r\n\r\n serverProcess.stderr.on('data', (data) => {\r\n console.error(`[query_engine TCP Server Error] ${data.toString().trim()}`);\r\n });\r\n\r\n serverProcess.on('close', (code) => {\r\n globalTcpServers.delete(this.connectionId);\r\n });\r\n\r\n serverProcess.on('error', (error) => {\r\n if (!started) {\r\n clearTimeout(timeout);\r\n reject(error);\r\n }\r\n });\r\n });\r\n }\r\n\r\n private async sendTcpRequestFast(command: Record<string, any>): Promise<ResponseEngine> {\r\n // Usar sistema de cola para serializar peticiones y evitar race conditions\r\n return new Promise((resolve, reject) => {\r\n // Agregar petición a la cola\r\n let queue = connectionQueues.get(this.connectionId);\r\n if (!queue) {\r\n queue = [];\r\n connectionQueues.set(this.connectionId, queue);\r\n }\r\n\r\n queue.push({ command, resolve, reject });\r\n\r\n // Procesar cola si no se está procesando\r\n this.processQueue();\r\n });\r\n }\r\n\r\n private async processQueue(): Promise<void> {\r\n // Si ya se está procesando esta cola, salir\r\n if (connectionProcessing.get(this.connectionId)) {\r\n return;\r\n }\r\n\r\n const queue = connectionQueues.get(this.connectionId);\r\n if (!queue || queue.length === 0) {\r\n return;\r\n }\r\n\r\n // Marcar como procesando\r\n connectionProcessing.set(this.connectionId, true);\r\n\r\n try {\r\n // Obtener información del servidor\r\n const serverInfo = globalTcpServers.get(this.connectionId);\r\n if (!serverInfo) {\r\n throw new Error('Server not initialized');\r\n }\r\n\r\n // Procesar peticiones de forma secuencial\r\n while (queue.length > 0) {\r\n const request = queue.shift();\r\n if (!request) break;\r\n\r\n try {\r\n // Verificar si hay conexión persistente\r\n let connection = globalTcpConnections.get(this.connectionId);\r\n\r\n if (!connection || connection.destroyed || connection.readyState !== 'open') {\r\n // Crear nueva conexión si no existe\r\n connection = await this.createNewConnection(serverInfo.port);\r\n globalTcpConnections.set(this.connectionId, connection);\r\n }\r\n\r\n // Ejecutar petición y esperar respuesta\r\n const result = await this.executeOnConnection(connection, request.command);\r\n request.resolve(result);\r\n } catch (error) {\r\n // Destruir el socket además de olvidarlo: si solo se borra\r\n // del Map queda abierto (leak) y su respuesta tardía podría\r\n // llegar a un listener viejo\r\n const staleConnection = globalTcpConnections.get(this.connectionId);\r\n if (staleConnection) {\r\n try { staleConnection.destroy(); } catch { /* ya cerrado */ }\r\n }\r\n globalTcpConnections.delete(this.connectionId);\r\n request.reject(error);\r\n }\r\n }\r\n } finally {\r\n // Marcar como no procesando\r\n connectionProcessing.set(this.connectionId, false);\r\n }\r\n }\r\n\r\n private async createNewConnection(port: number): Promise<net.Socket> {\r\n return new Promise((resolve, reject) => {\r\n const client = new net.Socket();\r\n client.setNoDelay(true);\r\n client.setKeepAlive(true, 60000);\r\n\r\n const timeout = setTimeout(() => {\r\n client.destroy();\r\n reject(new Error('Connection timeout'));\r\n }, 5000);\r\n\r\n client.connect(port, '127.0.0.1', () => {\r\n clearTimeout(timeout);\r\n resolve(client);\r\n });\r\n\r\n client.on('error', (error) => {\r\n clearTimeout(timeout);\r\n reject(error);\r\n });\r\n });\r\n }\r\n\r\n private async executeOnConnection(connection: net.Socket, command: Record<string, any>): Promise<ResponseEngine> {\r\n return new Promise((resolve, reject) => {\r\n let responseBuffer = '';\r\n let isResolved = false;\r\n\r\n const timeout = setTimeout(() => {\r\n if (!isResolved) {\r\n isResolved = true;\r\n connection.removeListener('data', onData);\r\n connection.removeListener('error', onError);\r\n reject(new Error('Request timeout'));\r\n }\r\n }, this.timeout);\r\n\r\n const onData = (data: Buffer) => {\r\n responseBuffer += data.toString();\r\n // Framing por línea: el server termina cada respuesta con '\\n'.\r\n // Un regex sobre el buffer parcial dispararía antes de tiempo\r\n // con respuestas grandes fragmentadas en varios chunks TCP\r\n // (matchearía hasta un '}' interno y el JSON.parse fallaría).\r\n let idx: number;\r\n while ((idx = responseBuffer.indexOf('\\n')) !== -1 && !isResolved) {\r\n const line = responseBuffer.slice(0, idx);\r\n responseBuffer = responseBuffer.slice(idx + 1);\r\n const marker = line.indexOf('PROCESS_RESPONSE:');\r\n if (marker === -1) continue; // ruido de logs del engine\r\n isResolved = true;\r\n clearTimeout(timeout);\r\n connection.removeListener('data', onData);\r\n connection.removeListener('error', onError);\r\n\r\n try {\r\n const response: ProcessResponse = JSON.parse(line.slice(marker + 'PROCESS_RESPONSE:'.length));\r\n resolve({\r\n status: response.status,\r\n message: response.message,\r\n data: response.data\r\n });\r\n } catch (error) {\r\n reject(new Error('Failed to parse response'));\r\n }\r\n }\r\n };\r\n\r\n const onError = (error: Error) => {\r\n if (!isResolved) {\r\n isResolved = true;\r\n clearTimeout(timeout);\r\n connection.removeListener('data', onData);\r\n connection.removeListener('error', onError);\r\n reject(error);\r\n }\r\n };\r\n\r\n connection.on('data', onData);\r\n connection.on('error', onError);\r\n\r\n // Enviar comando como JSON delimitado por '\\n' (framing del servidor)\r\n connection.write(JSON.stringify(command) + '\\n');\r\n });\r\n }\r\n\r\n private async createProcess(binary: string, args: string[]): Promise<ResponseEngine> {\r\n await this.initializeBinary();\r\n\r\n if (!this.binary) {\r\n throw new Error('Binary not initialized');\r\n }\r\n\r\n return new Promise<ResponseEngine>((resolve, reject) => {\r\n const child = spawn(this.binary![binary as keyof BinaryType], [...this.arguments, ...args]);\r\n\r\n let stdoutBuffer = '';\r\n let stderrBuffer = '';\r\n let isResolved = false;\r\n\r\n const timeoutId = setTimeout(() => {\r\n if (!isResolved) {\r\n isResolved = true;\r\n child.kill();\r\n reject(new Error('Process timeout'));\r\n }\r\n }, this.timeout);\r\n\r\n const resolveOnce = (response: ResponseEngine) => {\r\n if (!isResolved) {\r\n isResolved = true;\r\n clearTimeout(timeoutId);\r\n resolve(response);\r\n }\r\n };\r\n\r\n // Framing por línea (la respuesta termina en '\\n'): un regex sobre\r\n // el buffer parcial fallaría con respuestas grandes fragmentadas\r\n const tryParseLines = (buffer: string): string => {\r\n let idx: number;\r\n while ((idx = buffer.indexOf('\\n')) !== -1) {\r\n const line = buffer.slice(0, idx);\r\n buffer = buffer.slice(idx + 1);\r\n const marker = line.indexOf('PROCESS_RESPONSE:');\r\n if (marker === -1) continue;\r\n try {\r\n const response: ProcessResponse = JSON.parse(line.slice(marker + 'PROCESS_RESPONSE:'.length));\r\n resolveOnce({\r\n status: response.status,\r\n message: response.message,\r\n data: response.data\r\n });\r\n } catch (error) {\r\n resolveOnce({\r\n status: 500,\r\n message: 'Failed to parse response JSON',\r\n data: null\r\n });\r\n }\r\n }\r\n return buffer;\r\n };\r\n\r\n child.stdout.on('data', (data) => {\r\n stdoutBuffer = tryParseLines(stdoutBuffer + data.toString());\r\n });\r\n\r\n child.stderr.on('data', (data) => {\r\n stderrBuffer = tryParseLines(stderrBuffer + data.toString());\r\n });\r\n\r\n child.on('close', (code) => {\r\n clearTimeout(timeoutId);\r\n if (!isResolved) {\r\n resolveOnce({\r\n status: code === 0 ? 200 : 500,\r\n message: code === 0 ? 'Process completed' : `Process exited with code ${code}`,\r\n data: null\r\n });\r\n }\r\n });\r\n\r\n child.on('error', (error) => {\r\n clearTimeout(timeoutId);\r\n if (!isResolved) {\r\n resolveOnce({\r\n status: 500,\r\n message: `Process error: ${error.message}`,\r\n data: null\r\n });\r\n }\r\n });\r\n\r\n child.unref();\r\n });\r\n }\r\n\r\n async disconnect(): Promise<ResponseEngine> {\r\n // Cerrar conexión TCP persistente si existe\r\n const connection = globalTcpConnections.get(this.connectionId);\r\n if (connection && connection.readyState === 'open') {\r\n connection.write(JSON.stringify({ action: 'disconnect' }));\r\n connection.destroy();\r\n globalTcpConnections.delete(this.connectionId);\r\n }\r\n\r\n const serverInfo = globalTcpServers.get(this.connectionId);\r\n\r\n if (serverInfo && serverInfo.process && !serverInfo.process.killed) {\r\n serverInfo.process.kill();\r\n globalTcpServers.delete(this.connectionId);\r\n\r\n return {\r\n status: 200,\r\n message: 'TCP server and connections stopped',\r\n data: null\r\n };\r\n }\r\n\r\n return {\r\n status: 200,\r\n message: 'No TCP server to stop',\r\n data: null\r\n };\r\n }\r\n}\r\n\r\nexport { QueryEngine }","import { exec } from 'child_process';\r\nimport * as path from 'path';\r\nimport * as fs from 'fs';\r\nimport { promisify } from 'util';\r\nimport { Binary } from './Binary';\r\nimport { createRequire } from 'module';\r\nimport { fileURLToPath } from 'url';\r\nimport { dirname } from 'path';\r\n\r\nconst execAsync = promisify(exec);\r\n\r\ninterface SqliteResult {\r\n status: 'success' | 'error';\r\n message: string;\r\n data: any | null;\r\n}\r\n\r\ninterface RunResult {\r\n changes: number;\r\n lastID: number;\r\n}\r\n\r\nexport class SqliteExecutor {\r\n private binaryPath: string;\r\n private dbPath: string;\r\n\r\n constructor(dbPath: string) {\r\n this.dbPath = dbPath;\r\n this.binaryPath = this.getBinaryPath();\r\n }\r\n\r\n private findVersionedBinary(binDir: string, platform: string): string | null {\r\n try {\r\n const files = fs.readdirSync(binDir);\r\n const extension = platform === 'win32' ? '.exe' : '';\r\n const platformName = platform === 'win32' ? 'windows' : platform === 'darwin' ? 'macos' : 'linux';\r\n\r\n // Pattern to match versioned binaries: sqlite-engine-v1.0.0-windows-x64.exe\r\n const pattern = new RegExp(`^sqlite-engine-v\\\\d+\\\\.\\\\d+\\\\.\\\\d+-${platformName}-x64${extension.replace('.', '\\\\.')}$`);\r\n\r\n const matchingFile = files.find(f => pattern.test(f));\r\n\r\n if (matchingFile) {\r\n return path.join(binDir, matchingFile);\r\n }\r\n } catch (error) {\r\n // Directory doesn't exist or can't read\r\n }\r\n\r\n return null;\r\n }\r\n\r\n private getBinaryPath(): string {\r\n // Get __dirname equivalent for ESM\r\n const __filename = typeof import.meta !== 'undefined' && import.meta.url\r\n ? fileURLToPath(import.meta.url)\r\n : '';\r\n const __dirname = __filename ? dirname(__filename) : process.cwd();\r\n\r\n // Try to find the binary in the new location first\r\n const possibleDirs = [\r\n path.resolve(process.cwd(), '.dbcube', 'bin'),\r\n path.resolve(process.cwd(), 'node_modules', '.dbcube', 'bin'),\r\n path.resolve(__dirname, '..', 'bin'),\r\n ];\r\n\r\n const platform = process.platform;\r\n const extension = platform === 'win32' ? '.exe' : '';\r\n const platformName = platform === 'win32' ? 'windows' : platform === 'darwin' ? 'macos' : 'linux';\r\n\r\n // First, try to find versioned binary in all possible directories\r\n for (const dir of possibleDirs) {\r\n const versionedPath = this.findVersionedBinary(dir, platform);\r\n if (versionedPath && fs.existsSync(versionedPath)) {\r\n return versionedPath;\r\n }\r\n }\r\n\r\n // Fallback to non-versioned name\r\n const binaryName = `sqlite-engine-${platformName}-x64${extension}`;\r\n for (const dir of possibleDirs) {\r\n const fullPath = path.join(dir, binaryName);\r\n if (fs.existsSync(fullPath)) {\r\n return fullPath;\r\n }\r\n }\r\n\r\n // Fallback to old format if new format not found\r\n const fallbackName = `sqlite-engine${extension}`;\r\n for (const dir of possibleDirs) {\r\n const fullPath = path.join(dir, fallbackName);\r\n if (fs.existsSync(fullPath)) {\r\n return fullPath;\r\n }\r\n }\r\n\r\n // If nothing found, return the preferred path (will trigger download)\r\n return path.join(possibleDirs[0], binaryName);\r\n }\r\n\r\n private async executeBinary(args: string[]): Promise<SqliteResult> {\r\n const escapedArgs = args.map(arg => {\r\n if (arg.includes(' ') || arg.includes('\"') || arg.includes('(') || arg.includes(')')) {\r\n return `\"${arg.replace(/\"/g, '\\\\\"')}\"`;\r\n }\r\n return arg;\r\n });\r\n \r\n const command = `\"${this.binaryPath}\" ${escapedArgs.join(' ')}`;\r\n \r\n try {\r\n const { stdout, stderr } = await execAsync(command, {\r\n maxBuffer: 10 * 1024 * 1024, // 10MB buffer\r\n timeout: 30000 // 30s timeout\r\n });\r\n\r\n if (stderr && stderr.trim()) {\r\n console.warn('SQLite Engine Warning:', stderr);\r\n }\r\n\r\n const result = JSON.parse(stdout.trim());\r\n return result;\r\n } catch (error: any) {\r\n if (error.stdout) {\r\n try {\r\n const result = JSON.parse(error.stdout.trim());\r\n return result;\r\n } catch (parseError) {\r\n // Fall through to generic error\r\n }\r\n }\r\n \r\n throw new Error(`SQLite execution failed: ${error.message}`);\r\n }\r\n }\r\n\r\n async connect(): Promise<boolean> {\r\n try {\r\n const result = await this.executeBinary([\r\n '--action', 'connect',\r\n '--database', this.dbPath\r\n ]);\r\n return result.status === 'success';\r\n } catch (error) {\r\n return false;\r\n }\r\n }\r\n\r\n async exists(): Promise<boolean> {\r\n try {\r\n const result = await this.executeBinary([\r\n '--action', 'exists',\r\n '--database', this.dbPath\r\n ]);\r\n return result.status === 'success' && result.data === true;\r\n } catch (error) {\r\n return false;\r\n }\r\n }\r\n\r\n async query(sql: string, params?: any[]): Promise<SqliteResult> {\r\n const args = [\r\n '--action', 'query',\r\n '--database', this.dbPath,\r\n '--query', sql\r\n ];\r\n\r\n if (params && params.length > 0) {\r\n args.push('--params', JSON.stringify(params));\r\n }\r\n\r\n return this.executeBinary(args);\r\n }\r\n\r\n // Método para múltiples queries (como lo hace better-sqlite3)\r\n async queryMultiple(sql: string): Promise<SqliteResult> {\r\n return this.query(sql);\r\n }\r\n\r\n // Método prepare que simula prepared statements\r\n prepare(sql: string) {\r\n return {\r\n all: async (...params: any[]) => {\r\n const result = await this.query(sql, params);\r\n if (result.status === 'error') {\r\n throw new Error(result.message);\r\n }\r\n return Array.isArray(result.data) ? result.data : [];\r\n },\r\n run: async (...params: any[]) => {\r\n const result = await this.query(sql, params);\r\n if (result.status === 'error') {\r\n throw new Error(result.message);\r\n }\r\n \r\n // Si es un RunResult, devolverlo tal como está\r\n if (typeof result.data === 'object' && \r\n result.data.hasOwnProperty('changes') && \r\n result.data.hasOwnProperty('lastID')) {\r\n return result.data as RunResult;\r\n }\r\n \r\n return { changes: 0, lastID: 0 };\r\n }\r\n };\r\n }\r\n\r\n // Para compatibilidad con better-sqlite3 API sincrona usando deasync si es necesario\r\n prepareSync(sql: string) {\r\n // Get __filename equivalent for ESM\r\n const __filename = typeof import.meta !== 'undefined' && import.meta.url\r\n ? fileURLToPath(import.meta.url)\r\n : '';\r\n const requireUrl = __filename || import.meta.url;\r\n const require = createRequire(requireUrl);\r\n const deasync = require('deasync');\r\n \r\n return {\r\n all: (...params: any[]) => {\r\n let result: any;\r\n let done = false;\r\n let error: any;\r\n\r\n this.query(sql, params).then(res => {\r\n if (res.status === 'error') {\r\n error = new Error(res.message);\r\n } else {\r\n result = Array.isArray(res.data) ? res.data : [];\r\n }\r\n done = true;\r\n }).catch(err => {\r\n error = err;\r\n done = true;\r\n });\r\n\r\n deasync.loopWhile(() => !done);\r\n if (error) throw error;\r\n return result;\r\n },\r\n run: (...params: any[]) => {\r\n let result: any;\r\n let done = false;\r\n let error: any;\r\n\r\n this.query(sql, params).then(res => {\r\n if (res.status === 'error') {\r\n error = new Error(res.message);\r\n } else if (typeof res.data === 'object' && \r\n res.data.hasOwnProperty('changes') && \r\n res.data.hasOwnProperty('lastID')) {\r\n result = res.data;\r\n } else {\r\n result = { changes: 0, lastID: 0 };\r\n }\r\n done = true;\r\n }).catch(err => {\r\n error = err;\r\n done = true;\r\n });\r\n\r\n deasync.loopWhile(() => !done);\r\n if (error) throw error;\r\n return result;\r\n }\r\n };\r\n }\r\n}","import { SqliteExecutor } from './SqliteExecutor';\r\nimport * as path from 'path';\r\nimport fs from 'fs';\r\n\r\nconst rootPath = path.resolve(process.cwd(), '.dbcube');\r\n\r\ninterface DatabaseConfig {\r\n name?: string;\r\n HOST?: string;\r\n USER?: string;\r\n PASSWORD?: string;\r\n DATABASE?: string;\r\n PORT?: number;\r\n}\r\n\r\ninterface QueryResult {\r\n status: 'success' | 'error';\r\n message: string;\r\n data: any | null;\r\n}\r\n\r\ninterface RunResult {\r\n changes: number;\r\n lastID: number;\r\n}\r\n\r\ninterface ParametrizedQueryResult {\r\n query: string;\r\n parameters: any[];\r\n}\r\n\r\nclass SQLite {\r\n private executor: SqliteExecutor | null = null;\r\n private database?: string;\r\n \r\n constructor(config: DatabaseConfig) {\r\n this.database = config.DATABASE;\r\n }\r\n\r\n async ifExist(): Promise<Boolean> {\r\n if (this.database) {\r\n const dbPath = this.database || ':memory:';\r\n const configPath = path.join(rootPath, dbPath + \".db\");\r\n \r\n // Create .dbcube directory if it doesn't exist\r\n if (!fs.existsSync(rootPath)) {\r\n fs.mkdirSync(rootPath, { recursive: true });\r\n }\r\n \r\n if (fs.existsSync(configPath)) {\r\n return true;\r\n }\r\n \r\n // También verificar usando el executor\r\n if (!this.executor) {\r\n this.executor = new SqliteExecutor(configPath);\r\n }\r\n return await this.executor.exists();\r\n }\r\n return false;\r\n }\r\n\r\n async connect(): Promise<SqliteExecutor> {\r\n return new Promise(async (resolve, reject) => {\r\n try {\r\n if (!this.executor) {\r\n const dbPath = this.database || ':memory:';\r\n const configPath = path.join(rootPath, dbPath + \".db\");\r\n \r\n // Create .dbcube directory if it doesn't exist\r\n if (!fs.existsSync(rootPath)) {\r\n fs.mkdirSync(rootPath, { recursive: true });\r\n }\r\n \r\n this.executor = new SqliteExecutor(configPath);\r\n const connected = await this.executor.connect();\r\n \r\n if (!connected) {\r\n throw new Error('Failed to connect to SQLite database');\r\n }\r\n }\r\n resolve(this.executor);\r\n } catch (error) {\r\n reject(error);\r\n }\r\n });\r\n }\r\n\r\n async disconnect(): Promise<void> {\r\n return new Promise((resolve) => {\r\n if (this.executor) {\r\n // SQLiteExecutor no necesita cerrar conexión persistente\r\n this.executor = null;\r\n }\r\n resolve();\r\n });\r\n }\r\n\r\n async query(sqlQuery: string): Promise<QueryResult> {\r\n return new Promise(async (resolve) => {\r\n try {\r\n if (typeof sqlQuery !== 'string') {\r\n throw new Error('The SQL query must be a string.');\r\n }\r\n \r\n if (!this.executor) {\r\n await this.connect();\r\n }\r\n \r\n if (!this.executor) {\r\n throw new Error('Database connection is not available.');\r\n }\r\n \r\n // Usar queryMultiple que maneja múltiples comandos SQL\r\n const result = await this.executor.queryMultiple(sqlQuery);\r\n \r\n if (result.status === 'error') {\r\n resolve({\r\n status: 'error',\r\n message: result.message,\r\n data: null,\r\n });\r\n } else {\r\n resolve({\r\n status: 'success',\r\n message: 'Query executed successfully',\r\n data: result.data,\r\n });\r\n }\r\n } catch (error) {\r\n resolve({\r\n status: 'error',\r\n message: (error as Error).message || 'An error occurred while executing the query.',\r\n data: null,\r\n });\r\n }\r\n });\r\n }\r\n\r\n async queryWithParameters(sqlQuery: string, params: any[] = []): Promise<QueryResult> {\r\n return new Promise(async (resolve) => {\r\n try {\r\n if (typeof sqlQuery !== 'string') {\r\n throw new Error('The SQL query must be a string.');\r\n }\r\n \r\n if (!Array.isArray(params)) {\r\n throw new Error('Parameters must be an array.');\r\n }\r\n \r\n if (!this.executor) {\r\n await this.connect();\r\n }\r\n \r\n if (!this.executor) {\r\n throw new Error('Database connection is not available.');\r\n }\r\n \r\n const result = await this.executor.query(sqlQuery, params);\r\n \r\n if (result.status === 'error') {\r\n resolve({\r\n status: 'error',\r\n message: result.message,\r\n data: null,\r\n });\r\n } else {\r\n resolve({\r\n status: 'success',\r\n message: 'Query executed successfully',\r\n data: result.data,\r\n });\r\n }\r\n } catch (error) {\r\n console.log(error);\r\n resolve({\r\n status: 'error',\r\n message: (error as Error).message || 'An error occurred while executing the query.',\r\n data: null,\r\n });\r\n }\r\n });\r\n }\r\n\r\n convertToParameterizedQuery(sql: string): ParametrizedQueryResult {\r\n const normalizedSql = sql.replace(/\\s+/g, ' ').trim();\r\n \r\n const baseQueryMatch = normalizedSql.match(/^(.+?)\\s+VALUES\\s*\\(/i);\r\n if (!baseQueryMatch) {\r\n throw new Error('No se pudo encontrar la estructura VALUES en la consulta');\r\n }\r\n \r\n const baseQuery = baseQueryMatch[1];\r\n \r\n const valuesStartIndex = normalizedSql.toUpperCase().indexOf('VALUES');\r\n const valuesSection = normalizedSql.substring(valuesStartIndex);\r\n const valuesMatch = valuesSection.match(/VALUES\\s*\\((.+)\\)\\s*;?\\s*$/i);\r\n if (!valuesMatch) {\r\n throw new Error('No se pudieron extraer los valores de la consulta');\r\n }\r\n \r\n const valuesString = valuesMatch[1];\r\n \r\n function parseValues(str: string): any[] {\r\n const values: any[] = [];\r\n let currentValue = '';\r\n let inQuotes = false;\r\n let quoteChar = '';\r\n let inCompute = false;\r\n let computeDepth = 0;\r\n \r\n for (let i = 0; i < str.length; i++) {\r\n const char = str[i];\r\n const prevChar = str[i - 1];\r\n \r\n if (!inQuotes && str.substring(i, i + 8) === '@compute') {\r\n inCompute = true;\r\n }\r\n \r\n if (inCompute && char === '(') {\r\n computeDepth++;\r\n } else if (inCompute && char === ')') {\r\n computeDepth--;\r\n if (computeDepth === 0) {\r\n inCompute = false;\r\n }\r\n }\r\n \r\n if (!inCompute && (char === '\"' || char === \"'\") && prevChar !== '\\\\') {\r\n if (!inQuotes) {\r\n inQuotes = true;\r\n quoteChar = char;\r\n } else if (char === quoteChar) {\r\n if (str[i + 1] === quoteChar) {\r\n currentValue += char + char;\r\n i++;\r\n continue;\r\n } else {\r\n inQuotes = false;\r\n quoteChar = '';\r\n }\r\n }\r\n }\r\n \r\n if (!inQuotes && !inCompute && char === ',') {\r\n values.push(cleanValue(currentValue.trim()));\r\n currentValue = '';\r\n continue;\r\n }\r\n \r\n currentValue += char;\r\n }\r\n \r\n if (currentValue.trim()) {\r\n values.push(cleanValue(currentValue.trim()));\r\n }\r\n \r\n return values;\r\n }\r\n \r\n function cleanValue(value: string): any {\r\n value = value.trim();\r\n \r\n if (value.startsWith('@compute')) {\r\n return value;\r\n }\r\n \r\n if ((value.startsWith('\"') && value.endsWith('\"')) || \r\n (value.startsWith(\"'\") && value.endsWith(\"'\"))) {\r\n value = value.slice(1, -1);\r\n value = value.replace(/''/g, \"'\").replace(/\"\"/g, '\"');\r\n }\r\n \r\n return value;\r\n }\r\n \r\n const parameters = parseValues(valuesString);\r\n const placeholders = parameters.map(() => '?').join(', ');\r\n const parametrizedQuery = `${baseQuery} VALUES (${placeholders});`;\r\n \r\n return {\r\n query: parametrizedQuery,\r\n parameters: parameters\r\n };\r\n }\r\n}\r\n\r\nexport const DbConfig = new SQLite({DATABASE: \"config\"});\r\nexport default DbConfig;","import * as fs from 'fs';\r\nimport * as path from 'path';\r\nimport { EventEmitter } from 'events';\r\n\r\ninterface InterceptOptions {\r\n interceptLog?: boolean;\r\n interceptError?: boolean;\r\n interceptWarn?: boolean;\r\n keepOriginal?: boolean;\r\n useBuffer?: boolean;\r\n}\r\n\r\ninterface ReadOptions {\r\n lines?: number | null;\r\n fromEnd?: boolean;\r\n asArray?: boolean;\r\n}\r\n\r\ninterface WatchOptions {\r\n persistent?: boolean;\r\n interval?: number;\r\n fromEnd?: boolean;\r\n}\r\n\r\ninterface WatchController {\r\n id: string;\r\n stop: () => void;\r\n isWatching: () => boolean;\r\n}\r\n\r\nexport interface InterceptController {\r\n restore: () => void;\r\n commit: () => Promise<boolean>;\r\n discard: () => number;\r\n hasBuffer: () => boolean;\r\n getBufferSize: () => number;\r\n}\r\n\r\ninterface DeleteResult {\r\n filePath: string;\r\n deleted: boolean;\r\n error: string | null;\r\n}\r\n\r\ntype LogLevel = 'INFO' | 'ERROR' | 'WARN' | 'DEBUG';\r\n\r\nexport class FileLogger extends EventEmitter {\r\n private static watchers = new Map<string, (curr: fs.Stats, prev: fs.Stats) => void>(); // Store listener functions\r\n private static buffers = new Map<string, string[]>();\r\n \r\n /**\r\n * Escribe un log en el archivo especificado\r\n * @param filePath - Ruta del archivo de log\r\n * @param message - Mensaje a escribir\r\n * @param level - Nivel del log (INFO, ERROR, WARN, DEBUG)\r\n * @param append - Si debe agregar al final del archivo (default: true)\r\n */\r\n static async write(filePath: string, message: string, level: LogLevel = 'INFO', append: boolean = true): Promise<boolean> {\r\n try {\r\n // Asegurar que el directorio existe\r\n const dir = path.dirname(filePath);\r\n if (!fs.existsSync(dir)) {\r\n fs.mkdirSync(dir, { recursive: true });\r\n }\r\n \r\n // Formatear el mensaje con timestamp\r\n const timestamp = new Date().toISOString();\r\n const formattedMessage = `[${timestamp}] [${level}] ${message}\\n`;\r\n \r\n // Si existe un buffer para este archivo, agregarlo al buffer en lugar de escribir directamente\r\n if (FileLogger.buffers.has(filePath)) {\r\n FileLogger.buffers.get(filePath)!.push(formattedMessage);\r\n return true;\r\n }\r\n \r\n // Escribir al archivo normalmente\r\n if (append) {\r\n await fs.promises.appendFile(filePath, formattedMessage, 'utf8');\r\n } else {\r\n await fs.promises.writeFile(filePath, formattedMessage, 'utf8');\r\n }\r\n \r\n return true;\r\n } catch (error) {\r\n console.error('Error escribiendo log:', error);\r\n throw error;\r\n }\r\n }\r\n \r\n /**\r\n * Inicia un buffer temporal para un archivo de log\r\n * @param filePath - Ruta del archivo de log\r\n */\r\n static startBuffer(filePath: string): void {\r\n if (!FileLogger.buffers.has(filePath)) {\r\n FileLogger.buffers.set(filePath, []);\r\n }\r\n }\r\n \r\n /**\r\n * Confirma y escribe todos los logs del buffer al archivo\r\n * @param filePath - Ruta del archivo de log\r\n */\r\n static async commitBuffer(filePath: string): Promise<boolean> {\r\n const buffer = FileLogger.buffers.get(filePath);\r\n if (buffer && buffer.length > 0) {\r\n try {\r\n // Asegurar que el directorio existe\r\n const dir = path.dirname(filePath);\r\n if (!fs.existsSync(dir)) {\r\n fs.mkdirSync(dir, { recursive: true });\r\n }\r\n \r\n // Escribir todos los logs del buffer\r\n const content = buffer.join('');\r\n await fs.promises.appendFile(filePath, content, 'utf8');\r\n \r\n // Limpiar el buffer\r\n FileLogger.buffers.delete(filePath);\r\n return true;\r\n } catch (error) {\r\n console.error('Error confirmando buffer:', error);\r\n throw error;\r\n }\r\n }\r\n \r\n // Limpiar el buffer aunque esté vacío\r\n FileLogger.buffers.delete(filePath);\r\n return false;\r\n }\r\n \r\n /**\r\n * Descarta todos los logs del buffer sin escribirlos\r\n * @param filePath - Ruta del archivo de log\r\n */\r\n static discardBuffer(filePath: string): number {\r\n if (FileLogger.buffers.has(filePath)) {\r\n const discardedCount = FileLogger.buffers.get(filePath)!.length;\r\n FileLogger.buffers.delete(filePath);\r\n return discardedCount;\r\n }\r\n return 0;\r\n }\r\n \r\n /**\r\n * Verifica si existe un buffer activo para un archivo\r\n * @param filePath - Ruta del archivo de log\r\n */\r\n static hasBuffer(filePath: string): boolean {\r\n return FileLogger.buffers.has(filePath);\r\n }\r\n \r\n /**\r\n * Obtiene el número de logs en el buffer\r\n * @param filePath - Ruta del archivo de log\r\n */\r\n static getBufferSize(filePath: string): number {\r\n const buffer = FileLogger.buffers.get(filePath);\r\n return buffer ? buffer.length : 0;\r\n }\r\n \r\n /**\r\n * Intercepta console.log y console.error para escribir a archivo\r\n * @param filePath - Ruta del archivo de log\r\n * @param options - Opciones de interceptación\r\n */\r\n static interceptConsole(filePath: string, options: InterceptOptions = {}): InterceptController {\r\n const {\r\n interceptLog = true,\r\n interceptError = true,\r\n interceptWarn = true,\r\n keepOriginal = true, // Mantener el comportamiento original de console\r\n useBuffer = false // Usar buffer temporal\r\n } = options;\r\n \r\n // Iniciar buffer si se solicita\r\n if (useBuffer) {\r\n FileLogger.startBuffer(filePath);\r\n }\r\n \r\n // Guardar referencias originales\r\n const originalLog = console.log;\r\n const originalError = console.error;\r\n const originalWarn = console.warn;\r\n \r\n if (interceptLog) {\r\n console.log = function(...args: any[]) {\r\n const message = args.map(arg => \r\n typeof arg === 'object' ? JSON.stringify(arg) : String(arg)\r\n ).join(' ');\r\n \r\n FileLogger.write(filePath, message, 'INFO').catch(err => {\r\n originalError('Error escribiendo log:', err);\r\n });\r\n \r\n if (keepOriginal) {\r\n originalLog.apply(console, args);\r\n }\r\n };\r\n }\r\n \r\n if (interceptError) {\r\n console.error = function(...args: any[]) {\r\n const message = args.map(arg => \r\n typeof arg === 'object' ? JSON.stringify(arg) : String(arg)\r\n ).join(' ');\r\n \r\n FileLogger.write(filePath, message, 'ERROR').catch(err => {\r\n originalError('Error escribiendo error log:', err);\r\n });\r\n \r\n if (keepOriginal) {\r\n originalError.apply(console, args);\r\n }\r\n };\r\n }\r\n \r\n if (interceptWarn) {\r\n console.warn = function(...args: any[]) {\r\n const message = args.map(arg => \r\n typeof arg === 'object' ? JSON.stringify(arg) : String(arg)\r\n ).join(' ');\r\n \r\n FileLogger.write(filePath, message, 'WARN').catch(err => {\r\n originalError('Error escribiendo warn log:', err);\r\n });\r\n \r\n if (keepOriginal) {\r\n originalWarn.apply(console, args);\r\n }\r\n };\r\n }\r\n \r\n // Retornar función para restaurar console original\r\n return {\r\n restore: () => {\r\n if (interceptLog) console.log = originalLog;\r\n if (interceptError) console.error = originalError;\r\n if (interceptWarn) console.warn = originalWarn;\r\n },\r\n commit: async () => {\r\n if (useBuffer) {\r\n return await FileLogger.commitBuffer(filePath);\r\n }\r\n return false;\r\n },\r\n discard: () => {\r\n if (useBuffer) {\r\n return FileLogger.discardBuffer(filePath);\r\n }\r\n return 0;\r\n },\r\n hasBuffer: () => FileLogger.hasBuffer(filePath),\r\n getBufferSize: () => FileLogger.getBufferSize(filePath)\r\n };\r\n }\r\n \r\n /**\r\n * Lee el contenido completo del archivo de log\r\n * @param filePath - Ruta del archivo de log\r\n * @param options - Opciones de lectura\r\n * @returns Contenido del archivo\r\n */\r\n static async read(filePath: string, options: ReadOptions = {}): Promise<string | string[]> {\r\n const { \r\n lines = null, // Número de líneas a leer (null = todas)\r\n fromEnd = false, // Si debe leer desde el final\r\n asArray = false // Si debe retornar como array de líneas\r\n } = options;\r\n \r\n try {\r\n if (!fs.existsSync(filePath)) {\r\n return asArray ? [] : '';\r\n }\r\n \r\n let content = await fs.promises.readFile(filePath, 'utf8');\r\n \r\n if (asArray) {\r\n let linesArray = content.split('\\n').filter(line => line.trim() !== '');\r\n \r\n if (lines !== null) {\r\n if (fromEnd) {\r\n linesArray = linesArray.slice(-lines);\r\n } else {\r\n linesArray = linesArray.slice(0, lines);\r\n }\r\n }\r\n \r\n return linesArray;\r\n }\r\n \r\n // Si se especifica número de líneas y no es array\r\n if (lines !== null) {\r\n let linesArray = content.split('\\n').filter(line => line.trim() !== '');\r\n if (fromEnd) {\r\n linesArray = linesArray.slice(-lines);\r\n } else {\r\n linesArray = linesArray.slice(0, lines);\r\n }\r\n content = linesArray.join('\\n');\r\n }\r\n \r\n return content;\r\n } catch (error) {\r\n console.error('Error leyendo log:', error);\r\n throw error;\r\n }\r\n }\r\n \r\n /**\r\n * Observa un archivo de log en tiempo real\r\n * @param filePath - Ruta del archivo de log\r\n * @param callback - Función callback para nuevas líneas\r\n * @param options - Opciones del watcher\r\n * @returns Objeto con métodos para controlar el watcher\r\n */\r\n static watch(filePath: string, callback: (line: string, filePath: string) => void, options: WatchOptions = {}): WatchController {\r\n const {\r\n persistent = true,\r\n interval = 100,\r\n fromEnd = true // Empezar desde el final del archivo\r\n } = options;\r\n \r\n let lastSize = 0;\r\n let lastPosition = 0;\r\n \r\n // Inicializar posición si el archivo ya existe\r\n if (fs.existsSync(filePath)) {\r\n const stats = fs.statSync(filePath);\r\n lastSize = stats.size;\r\n lastPosition = fromEnd ? stats.size : 0;\r\n }\r\n \r\n // Fixed: Correct listener function signature for fs.watchFile\r\n const listener = async (curr: fs.Stats, prev: fs.Stats) => {\r\n try {\r\n if (curr.size > lastSize) {\r\n // El archivo ha crecido\r\n const stream = fs.createReadStream(filePath, {\r\n start: lastPosition,\r\n end: curr.size - 1,\r\n encoding: 'utf8'\r\n });\r\n \r\n let buffer = '';\r\n \r\n stream.on('data', (chunk) => {\r\n buffer += chunk;\r\n const lines = buffer.split('\\n');\r\n \r\n // Procesar líneas completas\r\n for (let i = 0; i < lines.length - 1; i++) {\r\n if (lines[i].trim()) {\r\n callback(lines[i].trim(), filePath);\r\n }\r\n }\r\n \r\n // Guardar la línea incompleta\r\n buffer = lines[lines.length - 1];\r\n });\r\n \r\n stream.on('end', () => {\r\n // Procesar la última línea si existe\r\n if (buffer.trim()) {\r\n callback(buffer.trim(), filePath);\r\n }\r\n });\r\n \r\n lastSize = curr.size;\r\n lastPosition = curr.size;\r\n }\r\n } catch (error) {\r\n console.error('Error en watcher:', error);\r\n }\r\n };\r\n \r\n // Watcher para cambios en el archivo\r\n fs.watchFile(filePath, { persistent, interval }, listener);\r\n \r\n // Guardar referencia del watcher\r\n const watcherId = `${filePath}_${Date.now()}`;\r\n // Store listener reference for cleanup\r\n FileLogger.watchers.set(watcherId, listener as any);\r\n \r\n // Retornar objeto de control\r\n return {\r\n id: watcherId,\r\n stop: () => {\r\n const storedListener = FileLogger.watchers.get(watcherId);\r\n if (storedListener) {\r\n fs.unwatchFile(filePath, storedListener);\r\n FileLogger.watchers.delete(watcherId);\r\n }\r\n },\r\n isWatching: () => FileLogger.watchers.has(watcherId)\r\n };\r\n }\r\n \r\n /**\r\n * Detiene todos los watchers activos\r\n */\r\n static stopAllWatchers(): void {\r\n for (const [watcherId] of FileLogger.watchers) {\r\n const filePath = watcherId.split('_')[0];\r\n fs.unwatchFile(filePath);\r\n }\r\n FileLogger.watchers.clear();\r\n }\r\n \r\n /**\r\n * Métodos de conveniencia para diferentes niveles de log\r\n */\r\n static async info(filePath: string, message: string): Promise<boolean> {\r\n return this.write(filePath, message, 'INFO');\r\n }\r\n \r\n static async error(filePath: string, message: string): Promise<boolean> {\r\n return this.write(filePath, message, 'ERROR');\r\n }\r\n \r\n static async warn(filePath: string, message: string): Promise<boolean> {\r\n return this.write(filePath, message, 'WARN');\r\n }\r\n \r\n static async debug(filePath: string, message: string): Promise<boolean> {\r\n return this.write(filePath, message, 'DEBUG');\r\n }\r\n \r\n /**\r\n * Limpia logs antiguos\r\n * @param filePath - Ruta del archivo de log\r\n * @param maxLines - Máximo número de líneas a mantener\r\n */\r\n static async cleanup(filePath: string, maxLines: number = 1000): Promise<number> {\r\n try {\r\n const lines = await this.read(filePath, { asArray: true }) as string[];\r\n \r\n if (lines.length > maxLines) {\r\n const keepLines = lines.slice(-maxLines);\r\n const content = keepLines.join('\\n') + '\\n';\r\n await fs.promises.writeFile(filePath, content, 'utf8');\r\n return lines.length - maxLines; // Líneas eliminadas\r\n }\r\n \r\n return 0;\r\n } catch (error) {\r\n console.error('Error limpiando logs:', error);\r\n throw error;\r\n }\r\n }\r\n \r\n /**\r\n * Elimina un archivo de log\r\n * @param filePath - Ruta del archivo de log a eliminar\r\n */\r\n static async deleteLogFile(filePath: string): Promise<boolean> {\r\n try {\r\n if (fs.existsSync(filePath)) {\r\n await fs.promises.unlink(filePath);\r\n return true;\r\n }\r\n return false;\r\n } catch (error) {\r\n console.error('Error eliminando archivo de log:', error);\r\n throw error;\r\n }\r\n }\r\n \r\n /**\r\n * Elimina múltiples archivos de log\r\n * @param filePaths - Array de rutas de archivos de log a eliminar\r\n */\r\n static async deleteLogFiles(filePaths: string[]): Promise<DeleteResult[]> {\r\n const results: DeleteResult[] = [];\r\n \r\n for (const filePath of filePaths) {\r\n try {\r\n const deleted = await this.deleteLogFile(filePath);\r\n results.push({ filePath, deleted, error: null });\r\n } catch (error) {\r\n results.push({ filePath, deleted: false, error: (error as Error).message });\r\n }\r\n }\r\n \r\n return results;\r\n }\r\n}\r\n\r\nexport default FileLogger;","import { ComputedFieldConfig, DataObject, DataType } from \"../@types/DataObject\";\r\nimport { Column, DatabaseType, TableSchema } from \"../@types/Processor\";\r\nimport DbConfig from \"./DbConfig\";\r\n\r\nexport class ComputedFieldProcessor {\r\n\r\n static async getComputedFields(name: string): Promise<any[]> {\r\n let computedFields = [];\r\n if (await DbConfig.ifExist()) {\r\n await DbConfig.connect()\r\n try {\r\n // Verificar si la tabla computes existe antes de intentar acceder a ella\r\n const tableExistsQuery = `SELECT name FROM sqlite_master WHERE type='table' AND name='dbcube_computes_config'`;\r\n const tableExistsResult = await DbConfig.query(tableExistsQuery);\r\n\r\n if (tableExistsResult.status === 'success' && tableExistsResult.data && tableExistsResult.data.length > 0) {\r\n const queryComputes = await DbConfig.queryWithParameters(`SELECT * FROM dbcube_computes_config WHERE database_ref=?`, [name]);\r\n computedFields = queryComputes.data;\r\n } else {\r\n // La tabla no existe, inicializar como array vacío\r\n computedFields = [];\r\n }\r\n } catch (error) {\r\n console.error('Error fetching computed fields:', error);\r\n computedFields = [];\r\n }\r\n await DbConfig.disconnect()\r\n }\r\n\r\n return computedFields;\r\n }\r\n\r\n /**\r\n * Processes computed field instruction and returns the computed value\r\n * @param instruction - The @compute instruction\r\n * @param rowData - The row data containing column values\r\n * @returns The computed value or null if there's an error\r\n */\r\n static processInstruction(instruction: string, rowData: Record<string, any>): any {\r\n try {\r\n // Remove @compute wrapper and extract the function content\r\n const functionMatch = instruction.match(/@compute\\s*\\(\\s*\\(\\s*\\)\\s*=>\\s*{([\\s\\S]*?)}\\s*\\)/);\r\n\r\n if (!functionMatch) {\r\n throw new Error('Invalid @compute instruction format');\r\n }\r\n\r\n let functionBody: string = functionMatch[1].trim();\r\n\r\n // Clean up the function body - remove trailing semicolon if present\r\n if (functionBody.endsWith(';')) {\r\n functionBody = functionBody.slice(0, -1).trim();\r\n }\r\n\r\n // Replace @column(columnName) with references into the row parameter.\r\n // Values are passed as data (never interpolated as code) so row content\r\n // cannot inject JavaScript into the compute function.\r\n functionBody = functionBody.replace(/@column\\(([^)]+)\\)/g, (_match, columnName: string) => {\r\n const cleanColumnName = columnName.trim().replace(/['\"]/g, '');\r\n return `__row[${JSON.stringify(cleanColumnName)}]`;\r\n });\r\n\r\n // Create and execute the function\r\n const computeFunction = new Function('__row', functionBody);\r\n return computeFunction(rowData);\r\n } catch (error) {\r\n console.error('Error processing computed field:', error);\r\n return null;\r\n }\r\n }\r\n\r\n /**\r\n * Extracts column dependencies from a computed field instruction\r\n * @param instruction - The @compute instruction\r\n * @returns Array of column names that this computed field depends on\r\n */\r\n static extractDependencies(instruction: string): string[] {\r\n const dependencies: string[] = [];\r\n const columnMatches = instruction.match(/@column\\(([^)]+)\\)/g);\r\n\r\n if (columnMatches) {\r\n for (const match of columnMatches) {\r\n const innerMatch = match.match(/@column\\(([^)]+)\\)/);\r\n if (innerMatch) {\r\n const columnName = innerMatch[1].trim().replace(/['\"]/g, '');\r\n if (!dependencies.includes(columnName)) {\r\n dependencies.push(columnName);\r\n }\r\n }\r\n }\r\n }\r\n\r\n return dependencies;\r\n }\r\n\r\n /**\r\n * Adds computed fields to an array of data objects based on configuration array\r\n * @param data - Array of data objects\r\n * @param computedConfigs - Array of computed field configurations\r\n * @returns Array with the new computed fields added\r\n */\r\n static computedFields<T extends DataObject>(\r\n data: T[],\r\n computedConfigs: ComputedFieldConfig[]\r\n ): T[] {\r\n\r\n return data.map((item, index) => {\r\n let processedItem: any = { ...item };\r\n\r\n // Procesar cada configuración de campo computado\r\n computedConfigs.forEach((config) => {\r\n try {\r\n const { column: fieldName, type, instruction } = config;\r\n\r\n // Reemplazar @column(fieldName) por referencias al parámetro de fila.\r\n // Los valores viajan como datos (nunca como código): el contenido de la\r\n // fila no puede inyectar JavaScript en la función de cómputo.\r\n let processedExpression = instruction.replace(\r\n /@column\\(([^)]+)\\)/g,\r\n (match, columnName) => {\r\n const cleanColumnName = columnName.replace(/['\"]/g, '');\r\n return `__row[${JSON.stringify(cleanColumnName)}]`;\r\n }\r\n );\r\n\r\n // Extraer la función dentro de @compute\r\n const computeMatch = processedExpression.match(/@compute\\s*\\(\\s*\\(\\s*\\)\\s*=>\\s*\\{(.*)\\}\\s*\\)/s);\r\n if (!computeMatch) {\r\n throw new Error(`Formato de @compute inválido para campo ${fieldName}`);\r\n }\r\n\r\n const functionBody = computeMatch[1];\r\n\r\n // Crear y ejecutar la función\r\n const computeFunction = new Function('__row', functionBody);\r\n let result = computeFunction(processedItem);\r\n\r\n // Aplicar conversión de tipo\r\n result = convertToType(result, type as DataType);\r\n\r\n // Agregar el nuevo campo al objeto procesado\r\n processedItem[fieldName] = result;\r\n\r\n } catch (error) {\r\n console.error(`Error procesando campo ${config.column} en item ${index}:`, error);\r\n // En caso de error, asignar null al campo\r\n processedItem[config.column] = null;\r\n }\r\n });\r\n\r\n return processedItem;\r\n });\r\n }\r\n}\r\n\r\nexport class TableProcessor {\r\n static async generateAlterQueries(\r\n nowQuery: string,\r\n dbType: DatabaseType,\r\n tableName: string,\r\n database_ref: string,\r\n ): Promise<string[]> {\r\n function parseCreateTableQuery(query: string, dbType: DatabaseType): TableSchema {\r\n // Limpiar y normalizar la query\r\n const cleanQuery = query.trim().replace(/\\s+/g, ' ');\r\n\r\n // Extraer el nombre de la tabla\r\n const tableNameMatch = cleanQuery.match(/CREATE TABLE (?:IF NOT EXISTS )?(\\w+)/i);\r\n if (!tableNameMatch) {\r\n throw new Error('No se pudo extraer el nombre de la tabla');\r\n }\r\n\r\n const tableName = tableNameMatch[1];\r\n\r\n // Extraer las definiciones de columnas\r\n const columnsMatch = cleanQuery.match(/\\((.+)\\)/);\r\n if (!columnsMatch) {\r\n throw new Error('No se pudieron extraer las definiciones de columnas');\r\n }\r\n\r\n const columnsString = columnsMatch[1];\r\n const columnDefinitions = columnsString.split(',').map(def => def.trim());\r\n\r\n const columns: Column[] = [];\r\n\r\n for (const def of columnDefinitions) {\r\n // Skip constraints that aren't column definitions\r\n if (def.toUpperCase().startsWith('PRIMARY KEY') ||\r\n def.toUpperCase().startsWith('FOREIGN KEY') ||\r\n def.toUpperCase().startsWith('CONSTRAINT')) {\r\n continue;\r\n }\r\n\r\n const parts = def.split(/\\s+/);\r\n if (parts.length < 2) continue;\r\n\r\n const columnName = parts[0];\r\n const columnType = parts[1];\r\n\r\n const column: Column = {\r\n name: columnName,\r\n type: columnType,\r\n nullable: !def.toUpperCase().includes('NOT NULL'),\r\n primaryKey: def.toUpperCase().includes('PRIMARY KEY'),\r\n autoIncrement: def.toUpperCase().includes('AUTOINCREMENT') || def.toUpperCase().includes('AUTO_INCREMENT')\r\n };\r\n\r\n columns.push(column);\r\n }\r\n\r\n return { tableName, columns };\r\n }\r\n\r\n function generateMySQLQueries(\r\n nowColumns: Map<string, Column>,\r\n oldColumns: Map<string, Column>,\r\n tableName: string\r\n ): string[] {\r\n const queries: string[] = [];\r\n\r\n // Columnas a eliminar\r\n for (const [columnName] of oldColumns) {\r\n if (!nowColumns.has(columnName)) {\r\n queries.push(`ALTER TABLE ${tableName} DROP COLUMN ${columnName};`);\r\n }\r\n }\r\n\r\n // Columnas a agregar o modificar\r\n for (const [columnName, column] of nowColumns) {\r\n const oldColumn = oldColumns.get(columnName);\r\n\r\n if (!oldColumn) {\r\n // Agregar nueva columna\r\n const columnDef = buildColumnDefinition(column, 'mysql');\r\n queries.push(`ALTER TABLE ${tableName} ADD COLUMN ${columnDef};`);\r\n } else if (!columnsEqual(column, oldColumn)) {\r\n // Modificar columna existente\r\n const columnDef = buildColumnDefinition(column, 'mysql');\r\n queries.push(`ALTER TABLE ${tableName} MODIFY COLUMN ${columnDef};`);\r\n }\r\n }\r\n\r\n return queries;\r\n }\r\n\r\n function generatePostgreSQLQueries(\r\n nowColumns: Map<string, Column>,\r\n oldColumns: Map<string, Column>,\r\n tableName: string\r\n ): string[] {\r\n const queries: string[] = [];\r\n\r\n // Columnas a eliminar\r\n for (const [columnName] of oldColumns) {\r\n if (!nowColumns.has(columnName)) {\r\n queries.push(`ALTER TABLE ${tableName} DROP COLUMN ${columnName};`);\r\n }\r\n }\r\n\r\n // Columnas a agregar o modificar\r\n for (const [columnName, column] of nowColumns) {\r\n const oldColumn = oldColumns.get(columnName);\r\n\r\n if (!oldColumn) {\r\n // Agregar nueva columna\r\n const columnDef = buildColumnDefinition(column, 'postgres');\r\n queries.push(`ALTER TABLE ${tableName} ADD COLUMN ${columnDef};`);\r\n } else if (!columnsEqual(column, oldColumn)) {\r\n // PostgreSQL requiere comandos separados para diferentes modificaciones\r\n if (column.type !== oldColumn.type) {\r\n const pgType = column.type.replace('INTEGER', 'INT').replace('TEXT', 'VARCHAR');\r\n queries.push(`ALTER TABLE ${tableName} ALTER COLUMN ${columnName} TYPE ${pgType};`);\r\n }\r\n\r\n if (column.nullable !== oldColumn.nullable) {\r\n const constraint = column.nullable ? 'DROP NOT NULL' : 'SET NOT NULL';\r\n queries.push(`ALTER TABLE ${tableName} ALTER COLUMN ${columnName} ${constraint};`);\r\n }\r\n }\r\n }\r\n\r\n return queries;\r\n }\r\n\r\n function generateSQLiteQueries(\r\n nowSchema: TableSchema,\r\n oldSchema: TableSchema,\r\n tableName: string\r\n ): string[] {\r\n // SQLite no soporta DROP COLUMN directamente, necesitamos recrear la tabla\r\n const queries: string[] = [];\r\n\r\n // Verificar si hay diferencias\r\n if (schemasEqual(nowSchema, oldSchema)) {\r\n return queries; // No hay cambios\r\n }\r\n\r\n const tempTableName = `${tableName}_temp_${Date.now()}`;\r\n\r\n // 1. Crear tabla temporal con el nuevo esquema\r\n const createTempQuery = buildCreateTableQuery(nowSchema, 'sqlite', tempTableName);\r\n queries.push(createTempQuery);\r\n\r\n // 2. Copiar datos compatibles\r\n const commonColumns = nowSchema.columns\r\n .filter(col => oldSchema.columns.some(oldCol => oldCol.name.toLowerCase() === col.name.toLowerCase()))\r\n .map(col => col.name);\r\n\r\n if (commonColumns.length > 0) {\r\n const columnsList = commonColumns.join(', ');\r\n queries.push(`INSERT INTO ${tempTableName} (${columnsList}) SELECT ${columnsList} FROM ${tableName};`);\r\n }\r\n\r\n // 3. Eliminar tabla original\r\n queries.push(`DROP TABLE ${tableName};`);\r\n\r\n // 4. Renombrar tabla temporal\r\n queries.push(`ALTER TABLE ${tempTableName} RENAME TO ${tableName};`);\r\n\r\n return queries;\r\n }\r\n\r\n function generateMongoDBQueries(\r\n nowColumns: Map<string, Column>,\r\n oldColumns: Map<string, Column>,\r\n collectionName: string\r\n ): string[] {\r\n const queries: string[] = [];\r\n\r\n // Campos a eliminar\r\n const fieldsToRemove: string[] = [];\r\n for (const [fieldName] of oldColumns) {\r\n if (!nowColumns.has(fieldName)) {\r\n fieldsToRemove.push(fieldName);\r\n }\r\n }\r\n\r\n if (fieldsToRemove.length > 0) {\r\n const unsetFields = fieldsToRemove.reduce((acc, field) => {\r\n acc[field] = \"\";\r\n return acc;\r\n }, {} as Record<string, string>);\r\n\r\n queries.push(`db.${collectionName}.updateMany({}, { $unset: ${JSON.stringify(unsetFields)} });`);\r\n }\r\n\r\n // Campos a agregar (con valores por defecto)\r\n const fieldsToAdd: Record<string, any> = {};\r\n for (const [fieldName, column] of nowColumns) {\r\n if (!oldColumns.has(fieldName)) {\r\n // Valor por defecto según el tipo\r\n let defaultValue: any = null;\r\n if (!column.nullable) {\r\n switch (column.type.toUpperCase()) {\r\n case 'INTEGER':\r\n defaultValue = 0;\r\n break;\r\n case 'TEXT':\r\n case 'VARCHAR':\r\n defaultValue = '';\r\n break;\r\n default:\r\n defaultValue = null;\r\n }\r\n }\r\n fieldsToAdd[fieldName] = defaultValue;\r\n }\r\n }\r\n\r\n if (Object.keys(fieldsToAdd).length > 0) {\r\n queries.push(`db.${collectionName}.updateMany({}, { $set: ${JSON.stringify(fieldsToAdd)} });`);\r\n }\r\n\r\n return queries;\r\n }\r\n\r\n function buildColumnDefinition(column: Column, dbType: DatabaseType): string {\r\n let def = `${column.name} ${column.type}`;\r\n\r\n if (column.primaryKey) {\r\n def += ' PRIMARY KEY';\r\n }\r\n\r\n if (column.autoIncrement) {\r\n if (dbType === 'mysql') {\r\n def += ' AUTO_INCREMENT';\r\n } else if (dbType === 'sqlite') {\r\n def += ' AUTOINCREMENT';\r\n } else if (dbType === 'postgres') {\r\n def = def.replace(column.type, 'SERIAL');\r\n }\r\n }\r\n\r\n if (!column.nullable) {\r\n def += ' NOT NULL';\r\n }\r\n\r\n return def;\r\n }\r\n\r\n function buildCreateTableQuery(schema: TableSchema, dbType: DatabaseType, tableName?: string): string {\r\n const name = tableName || schema.tableName;\r\n const columnDefs = schema.columns.map(col => buildColumnDefinition(col, dbType));\r\n return `CREATE TABLE ${name} (${columnDefs.join(', ')});`;\r\n }\r\n\r\n function columnsEqual(col1: Column, col2: Column): boolean {\r\n return col1.name.toLowerCase() === col2.name.toLowerCase() &&\r\n col1.type === col2.type &&\r\n col1.nullable === col2.nullable &&\r\n col1.primaryKey === col2.primaryKey &&\r\n col1.autoIncrement === col2.autoIncrement;\r\n }\r\n\r\n function schemasEqual(schema1: TableSchema, schema2: TableSchema): boolean {\r\n if (schema1.columns.length !== schema2.columns.length) {\r\n return false;\r\n }\r\n\r\n const cols1 = new Map(schema1.columns.map(col => [col.name.toLowerCase(), col]));\r\n const cols2 = new Map(schema2.columns.map(col => [col.name.toLowerCase(), col]));\r\n\r\n for (const [name, col1] of cols1) {\r\n const col2 = cols2.get(name);\r\n if (!col2 || !columnsEqual(col1, col2)) {\r\n return false;\r\n }\r\n }\r\n\r\n return true;\r\n }\r\n\r\n if (await DbConfig.ifExist()) {\r\n await DbConfig.connect()\r\n try {\r\n // Verificar si la tabla de schemas existe antes de intentar acceder a ella\r\n const tableExistsQuery = `SELECT name FROM sqlite_master WHERE type='table' AND name='dbcube_schemas_config'`;\r\n const tableExistsResult = await DbConfig.query(tableExistsQuery);\r\n\r\n if (tableExistsResult.status === 'success' && tableExistsResult.data && tableExistsResult.data.length > 0) {\r\n const queryComputes = await DbConfig.queryWithParameters(`SELECT * FROM dbcube_schemas_config WHERE table_ref=? AND database_ref=?`, [tableName, database_ref]);\r\n const oldQuery = queryComputes.data[0];\r\n\r\n // Sin esquema previo registrado: tabla nueva → devolver el CREATE\r\n // (el engine lo ejecuta como CREATE TABLE IF NOT EXISTS en modo refresh)\r\n if (!oldQuery || !oldQuery.struct) {\r\n await DbConfig.disconnect()\r\n return [nowQuery];\r\n }\r\n\r\n const nowSchema = parseCreateTableQuery(nowQuery, dbType);\r\n const oldSchema = parseCreateTableQuery(oldQuery.struct, dbType);\r\n\r\n // Verificar que el nombre de tabla coincida\r\n if (nowSchema.tableName.toLowerCase() !== tableName.toLowerCase()) {\r\n throw new Error(`El nombre de tabla en la query (${nowSchema.tableName}) no coincide con el parámetro (${tableName})`);\r\n }\r\n\r\n // Crear mapas para facilitar la comparación\r\n const nowColumns = new Map(nowSchema.columns.map(col => [col.name.toLowerCase(), col]));\r\n const oldColumns = new Map(oldSchema.columns.map(col => [col.name.toLowerCase(), col]));\r\n\r\n switch (dbType) {\r\n case 'mysql':\r\n return generateMySQLQueries(nowColumns, oldColumns, tableName);\r\n\r\n case 'postgres':\r\n return generatePostgreSQLQueries(nowColumns, oldColumns, tableName);\r\n\r\n case 'sqlite':\r\n return generateSQLiteQueries(nowSchema, oldSchema, tableName);\r\n\r\n case 'mongodb':\r\n return generateMongoDBQueries(nowColumns, oldColumns, tableName);\r\n\r\n default:\r\n throw new Error(`Tipo de base de datos no soportado: ${dbType}`);\r\n }\r\n }\r\n } catch (error) {\r\n console.error('Error fetching computed fields:', error);\r\n }\r\n await DbConfig.disconnect()\r\n return [nowQuery];\r\n } else {\r\n return [nowQuery];\r\n }\r\n }\r\n\r\n static async saveQuery(table_ref: string, database_ref: string, struct: string): Promise<void> {\r\n\r\n if (await DbConfig.ifExist()) {\r\n await DbConfig.connect()\r\n try {\r\n await DbConfig.queryWithParameters(`DELETE FROM dbcube_schemas_config WHERE table_ref=? AND database_ref=?`, [table_ref, database_ref]);\r\n\r\n // Verificar si la tabla computes existe antes de intentar acceder a ella\r\n const tableExistsQuery = `INSERT INTO dbcube_schemas_config (table_ref, database_ref, struct) VALUES (?, ?, ?)`;\r\n await DbConfig.queryWithParameters(tableExistsQuery, [table_ref, database_ref, struct]);\r\n } catch (error) {\r\n console.error('Error fetching computed fields:', error);\r\n }\r\n await DbConfig.disconnect()\r\n }\r\n }\r\n}\r\n\r\nexport class TriggerProcessor {\r\n\r\n static async getTriggers(name: string): Promise<any[]> {\r\n let triggers = [];\r\n if (await DbConfig.ifExist()) {\r\n await DbConfig.connect()\r\n try {\r\n // Verificar si la tabla computes existe antes de intentar acceder a ella\r\n const tableExistsQuery = `SELECT name FROM sqlite_master WHERE type='table' AND name='dbcube_triggers_config'`;\r\n const tableExistsResult = await DbConfig.query(tableExistsQuery);\r\n\r\n if (tableExistsResult.status === 'success' && tableExistsResult.data && tableExistsResult.data.length > 0) {\r\n const queryComputes = await DbConfig.queryWithParameters(`SELECT * FROM dbcube_triggers_config WHERE database_ref=?`, [name]);\r\n triggers = queryComputes.data;\r\n } else {\r\n // La tabla no existe, inicializar como array vacío\r\n triggers = [];\r\n }\r\n } catch (error) {\r\n console.error('Error fetching computed fields:', error);\r\n triggers = [];\r\n }\r\n await DbConfig.disconnect()\r\n }\r\n\r\n return triggers;\r\n }\r\n}\r\n\r\n// Utils\r\nfunction convertToType(value: any, type: DataType): any {\r\n switch (type) {\r\n case 'string':\r\n return String(value);\r\n case 'number':\r\n const num = Number(value);\r\n return isNaN(num) ? 0 : num;\r\n case 'boolean':\r\n return Boolean(value);\r\n case 'date':\r\n return value instanceof Date ? value : new Date(value);\r\n case 'object':\r\n return value;\r\n default:\r\n return value;\r\n }\r\n}"],"mappings":"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","names":["import_path","platform","arch","os","followRedirects","resolve","arch","platform","ora","chalk","__filename","fs","path","os","import_url","import_path","import_meta","__filename","platform","arch","import_child_process","import_path","path","fs","resolve","net","path","require","resolve","import_path","import_module","net","import_child_process","resolve","path","require","import_child_process","path","fs","import_module","import_url","import_path","import_meta","platform","__filename","require","path","import_fs","fs","resolve","fs","path","type","dbType","tableName"]}
1
+ {"version":3,"sources":["../src/index.ts","../src/lib/Engine.ts","../src/lib/Arquitecture.ts","../src/lib/Donwloader.ts","../src/lib/Binary.ts","../src/lib/Config.ts","../src/lib/DaemonClient.ts","../src/lib/QueryEngine.ts","../src/lib/EmbeddedEngine.ts","../src/lib/DbConfig.ts","../src/lib/FileLogger.ts","../src/lib/Processors.ts"],"sourcesContent":["import { Engine } from './lib/Engine';\r\nimport { QueryEngine } from './lib/QueryEngine';\r\nimport { Arquitecture } from './lib/Arquitecture';\r\nimport { Binary } from './lib/Binary';\r\nimport { DbConfig } from './lib/DbConfig';\r\nimport { Config } from './lib/Config';\r\nimport { DaemonClient } from './lib/DaemonClient';\r\nimport { FileLogger, InterceptController } from './lib/FileLogger';\r\nimport { ComputedFieldProcessor, TableProcessor, TriggerProcessor } from './lib/Processors';\r\n\r\nexport { Config, Engine, QueryEngine, Arquitecture, Binary, DbConfig, DaemonClient, ComputedFieldProcessor, TableProcessor, TriggerProcessor, FileLogger, InterceptController };","import path from \"path\";\r\nimport { Binary } from \"./Binary\";\r\nimport { Config as ConfigClass } from './Config';\r\nimport { spawn } from \"child_process\";\r\nimport { ProcessResponse, ResponseEngine } from \"../@types/Engine\";\r\nimport { BinaryType } from \"../@types/Binary\";\r\nimport { createRequire } from 'module';\r\nimport { DaemonClient } from './DaemonClient';\r\n\r\nclass Engine {\r\n private name: string;\r\n private config: any;\r\n private arguments: any;\r\n private binary: BinaryType | null = null;\r\n private timeout: number;\r\n private daemonFailed = false;\r\n\r\n constructor(name: string, timeout = 30000) {\r\n this.name = name;\r\n this.config = this.setConfig(name);\r\n this.arguments = this.setArguments();\r\n this.timeout = timeout;\r\n }\r\n\r\n async initializeBinary(): Promise<void> {\r\n if (!this.binary) {\r\n this.binary = await Binary.get();\r\n }\r\n }\r\n\r\n /**\r\n * Returns a connected DaemonClient for this database, or null when\r\n * daemon mode is disabled/unavailable (then callers use spawn mode).\r\n */\r\n private async getDaemon(): Promise<DaemonClient | null> {\r\n if (this.daemonFailed || !DaemonClient.isEnabled()) return null;\r\n await this.initializeBinary();\r\n if (!this.binary) return null;\r\n\r\n const binaryPath = this.binary['query_engine' as keyof BinaryType];\r\n if (!binaryPath) return null;\r\n\r\n const client = DaemonClient.get(this.name, binaryPath, this.arguments);\r\n const ok = await client.ensure();\r\n if (!ok) {\r\n this.daemonFailed = true; // don't retry on every query\r\n return null;\r\n }\r\n return client;\r\n }\r\n\r\n /**\r\n * Executes a DML plan. Uses the persistent daemon (sub-millisecond\r\n * overhead) when available; falls back to one-shot spawn otherwise.\r\n */\r\n async executeDml(dml: object, txId?: string): Promise<ResponseEngine> {\r\n const daemon = await this.getDaemon();\r\n if (daemon) {\r\n try {\r\n return await daemon.execute(dml, txId);\r\n } catch (error: any) {\r\n if (txId) throw error; // a transaction can't change transport mid-flight\r\n // fall through to spawn mode\r\n }\r\n }\r\n if (txId) {\r\n throw new Error('Transactions require daemon mode. Make sure the query-engine binary is up to date (npx dbcube update).');\r\n }\r\n return this.run('query_engine', ['--action', 'execute', '--dml', JSON.stringify(dml)] as any);\r\n }\r\n\r\n /**\r\n * Executes raw SQL (or a MongoDB command document) with bound parameters.\r\n */\r\n async rawQuery(query: string, params: any[] = [], txId?: string): Promise<ResponseEngine> {\r\n const daemon = await this.getDaemon();\r\n if (daemon) {\r\n try {\r\n return await daemon.raw(query, params, txId);\r\n } catch (error: any) {\r\n if (txId) throw error;\r\n }\r\n }\r\n if (txId) {\r\n throw new Error('Transactions require daemon mode. Make sure the query-engine binary is up to date (npx dbcube update).');\r\n }\r\n return this.run('query_engine', ['--action', 'raw', '--query', query, '--params', JSON.stringify(params)] as any);\r\n }\r\n\r\n /** Starts a transaction (daemon mode only). Returns the transaction id. */\r\n async beginTransaction(): Promise<string> {\r\n const daemon = await this.getDaemon();\r\n if (!daemon) {\r\n throw new Error('Transactions require daemon mode. Make sure the query-engine binary is up to date (npx dbcube update).');\r\n }\r\n return daemon.begin();\r\n }\r\n\r\n async commitTransaction(txId: string): Promise<void> {\r\n const daemon = await this.getDaemon();\r\n if (!daemon) throw new Error('Daemon connection lost during transaction');\r\n return daemon.commit(txId);\r\n }\r\n\r\n async rollbackTransaction(txId: string): Promise<void> {\r\n const daemon = await this.getDaemon();\r\n if (!daemon) throw new Error('Daemon connection lost during transaction');\r\n return daemon.rollback(txId);\r\n }\r\n\r\n setArguments() {\r\n let args = [];\r\n if (this.config.type == 'sqlite') {\r\n args = [\r\n '--id', 'dbcube-' + this.name,\r\n '--database-ref', this.name,\r\n '--database', this.config.config.DATABASE + \".db\",\r\n '--motor', this.config.type\r\n ];\r\n } else {\r\n args = [\r\n '--id', 'dbcube-' + this.name,\r\n '--database-ref', this.name,\r\n '--database', this.config.config.DATABASE,\r\n '--host', this.config.config.HOST,\r\n '--port', String(this.config.config.PORT),\r\n '--motor', this.config.type\r\n ];\r\n // Credenciales opcionales (p. ej. MongoDB local sin auth)\r\n if (this.config.config.USER != null && this.config.config.USER !== '') {\r\n args.push('--user', this.config.config.USER);\r\n }\r\n if (this.config.config.PASSWORD != null && this.config.config.PASSWORD !== '') {\r\n args.push('--password', this.config.config.PASSWORD);\r\n }\r\n }\r\n return args;\r\n }\r\n\r\n setConfig(name: string) {\r\n const configInstance = new ConfigClass();\r\n\r\n try {\r\n const configFilePath = path.resolve(process.cwd(), 'dbcube.config.js');\r\n // Use __filename for CJS, process.cwd() for ESM\r\n const requireUrl = typeof __filename !== 'undefined' ? __filename : process.cwd();\r\n const require = createRequire(requireUrl);\r\n // Clear require cache to ensure fresh load (safe check for bundled environments)\r\n if (require.cache && require.resolve) {\r\n try {\r\n delete require.cache[require.resolve(configFilePath)];\r\n } catch (e) {\r\n // Ignore errors in bundled environments\r\n }\r\n }\r\n const configModule = require(configFilePath);\r\n const configFn = configModule.default || configModule;\r\n\r\n if (typeof configFn === 'function') {\r\n configFn(configInstance);\r\n } else {\r\n console.error('❌ El archivo dbcube.config.js no exporta una función.');\r\n }\r\n } catch (error: any) {\r\n console.error('❌ Error loading config file:', error.message);\r\n if (error.code === 'MODULE_NOT_FOUND') {\r\n console.error('❌ Config file not found, please create a dbcube.config.js file');\r\n }\r\n }\r\n\r\n return configInstance.getDatabase(name);\r\n\r\n }\r\n\r\n getConfig() {\r\n return this.config;\r\n }\r\n\r\n async run(binary: string, args: []) {\r\n await this.initializeBinary();\r\n\r\n if (!this.binary) {\r\n throw new Error('Binary not initialized');\r\n }\r\n\r\n return new Promise<ResponseEngine>((resolve, reject) => {\r\n const child = spawn(this.binary![binary as keyof BinaryType], [...this.arguments, ...args]);\r\n\r\n let stdoutBuffer = '';\r\n let stderrBuffer = '';\r\n let isResolved = false;\r\n\r\n const timeoutId = setTimeout(() => {\r\n if (!isResolved) {\r\n isResolved = true;\r\n child.kill();\r\n reject(new Error('Process timeout'));\r\n }\r\n }, this.timeout);\r\n\r\n const resolveOnce = (response: ResponseEngine) => {\r\n if (!isResolved) {\r\n isResolved = true;\r\n clearTimeout(timeoutId);\r\n resolve(response);\r\n }\r\n };\r\n\r\n // Framing por línea (la respuesta termina en '\\n'): un regex sobre\r\n // el buffer parcial fallaría con respuestas grandes fragmentadas\r\n const tryParseLines = (buffer: string): string => {\r\n let idx: number;\r\n while ((idx = buffer.indexOf('\\n')) !== -1) {\r\n const line = buffer.slice(0, idx);\r\n buffer = buffer.slice(idx + 1);\r\n const marker = line.indexOf('PROCESS_RESPONSE:');\r\n if (marker === -1) continue;\r\n try {\r\n const response: ProcessResponse = JSON.parse(line.slice(marker + 'PROCESS_RESPONSE:'.length));\r\n resolveOnce({\r\n status: response.status,\r\n message: response.message,\r\n data: response.data\r\n });\r\n } catch (error) {\r\n resolveOnce({\r\n status: 500,\r\n message: 'Failed to parse response JSON',\r\n data: null\r\n });\r\n }\r\n }\r\n return buffer;\r\n };\r\n\r\n child.stdout.on('data', (data) => {\r\n const text = data.toString();\r\n // Mostrar solo el chunk nuevo, sin la línea de protocolo\r\n const visible = text.split('\\n').filter((l: string) => l.trim() && !l.includes('PROCESS_RESPONSE:')).join('\\n');\r\n if (visible) console.log(visible);\r\n stdoutBuffer = tryParseLines(stdoutBuffer + text);\r\n });\r\n\r\n child.stderr.on('data', (data) => {\r\n const text = data.toString();\r\n // Logs de usuario del engine van por stderr\r\n const visible = text.split('\\n').filter((l: string) => l.trim() && !l.includes('PROCESS_RESPONSE:')).join('\\n');\r\n if (visible) console.log(visible);\r\n stderrBuffer = tryParseLines(stderrBuffer + text);\r\n });\r\n\r\n\r\n child.on('close', (code) => {\r\n clearTimeout(timeoutId);\r\n if (!isResolved) {\r\n resolveOnce({\r\n status: code === 0 ? 200 : 500,\r\n message: code === 0 ? 'Process completed' : `Process exited with code ${code}`,\r\n data: null\r\n });\r\n }\r\n });\r\n\r\n child.on('error', (error) => {\r\n clearTimeout(timeoutId);\r\n if (!isResolved) {\r\n resolveOnce({\r\n status: 500,\r\n message: `Process error: ${error.message}`,\r\n data: null\r\n });\r\n }\r\n });\r\n\r\n child.unref();\r\n });\r\n }\r\n}\r\n\r\nexport { Engine }","import * as os from 'os';\r\nimport * as path from 'path';\r\nimport * as fs from 'fs';\r\n\r\ninterface SystemInfo {\r\n platform: string;\r\n arch: string;\r\n release: string;\r\n type: string;\r\n endianness: string;\r\n cpus: number;\r\n}\r\n\r\ninterface BinaryInfo {\r\n name: string;\r\n path: string;\r\n exists: boolean;\r\n executable: boolean;\r\n}\r\n\r\nclass Arquitecture {\r\n private systemInfo: SystemInfo;\r\n\r\n constructor() {\r\n this.systemInfo = this.detectSystemInfo();\r\n }\r\n\r\n /**\r\n * Detecta información completa del sistema\r\n */\r\n private detectSystemInfo(): SystemInfo {\r\n return {\r\n platform: os.platform(),\r\n arch: os.arch(),\r\n release: os.release(),\r\n type: os.type(),\r\n endianness: os.endianness(),\r\n cpus: os.cpus().length\r\n };\r\n }\r\n\r\n /**\r\n * Obtiene la plataforma normalizada\r\n */\r\n getPlatform(): string {\r\n const platform = this.systemInfo.platform;\r\n \r\n switch (platform) {\r\n case 'win32':\r\n return 'windows';\r\n case 'darwin':\r\n return 'macos';\r\n case 'linux':\r\n return 'linux';\r\n case 'freebsd':\r\n return 'freebsd';\r\n case 'openbsd':\r\n return 'openbsd';\r\n case 'sunos':\r\n return 'solaris';\r\n default:\r\n return platform;\r\n }\r\n }\r\n\r\n /**\r\n * Obtiene la arquitectura normalizada\r\n */\r\n getArchitecture(): string {\r\n const arch = this.systemInfo.arch;\r\n \r\n switch (arch) {\r\n case 'x64':\r\n return 'x86_64';\r\n case 'x32':\r\n case 'ia32':\r\n return 'i686';\r\n case 'arm64':\r\n return 'aarch64';\r\n case 'arm':\r\n return 'armv7';\r\n case 'ppc64':\r\n return 'powerpc64';\r\n case 'ppc':\r\n return 'powerpc';\r\n case 's390x':\r\n return 's390x';\r\n case 'mips':\r\n return 'mips';\r\n case 'mipsel':\r\n return 'mipsel';\r\n default:\r\n return arch;\r\n }\r\n }\r\n\r\n /**\r\n * Genera el nombre del binario basado en la arquitectura\r\n */\r\n getBinaryName(baseName: string): string {\r\n const platform = this.getPlatform();\r\n const arch = this.getArchitecture();\r\n const extension = platform === 'windows' ? '.exe' : '';\r\n \r\n return `${baseName}-${platform}-${arch}${extension}`;\r\n }\r\n\r\n /**\r\n * Obtiene información completa del sistema\r\n */\r\n getSystemInfo(): SystemInfo {\r\n return { ...this.systemInfo };\r\n }\r\n\r\n /**\r\n * Obtiene el triple de destino (target triple) para Rust\r\n */\r\n getRustTargetTriple(): string {\r\n const platform = this.getPlatform();\r\n const arch = this.getArchitecture();\r\n \r\n // Mapeo de plataformas y arquitecturas a target triples de Rust\r\n const targetMap: { [key: string]: string } = {\r\n 'linux-x86_64': 'x86_64-unknown-linux-gnu',\r\n 'linux-i686': 'i686-unknown-linux-gnu',\r\n 'linux-aarch64': 'aarch64-unknown-linux-gnu',\r\n 'linux-armv7': 'armv7-unknown-linux-gnueabihf',\r\n 'macos-x86_64': 'x86_64-apple-darwin',\r\n 'macos-aarch64': 'aarch64-apple-darwin',\r\n 'windows-x86_64': 'x86_64-pc-windows-msvc',\r\n 'windows-i686': 'i686-pc-windows-msvc',\r\n 'windows-aarch64': 'aarch64-pc-windows-msvc',\r\n 'freebsd-x86_64': 'x86_64-unknown-freebsd',\r\n };\r\n \r\n const key = `${platform}-${arch}`;\r\n return targetMap[key] || `${arch}-unknown-${platform}`;\r\n }\r\n\r\n /**\r\n * Muestra información detallada del sistema\r\n */\r\n printSystemInfo(): void {\r\n console.log('🖥️ System Information:');\r\n console.log('├─ Platform:', this.getPlatform());\r\n console.log('├─ Arquitecture:', this.getArchitecture());\r\n console.log('├─ OS Type:', this.systemInfo.type);\r\n console.log('├─ OS Release:', this.systemInfo.release);\r\n console.log('├─ Endianness:', this.systemInfo.endianness);\r\n console.log('├─ CPUs:', this.systemInfo.cpus);\r\n console.log('└─ Rust Target:', this.getRustTargetTriple());\r\n }\r\n}\r\n\r\nexport { \r\n Arquitecture, \r\n SystemInfo,\r\n BinaryInfo\r\n};","import { BinaryType } from \"../@types/Binary\";\nimport { Arquitecture } from \"./Arquitecture\";\nimport * as fs from \"fs\";\nimport * as path from \"path\";\nimport * as os from \"os\";\nimport followRedirects from 'follow-redirects';\nconst { https } = followRedirects;\nimport * as unzipper from \"unzipper\";\nimport { IncomingMessage } from 'http';\nimport ora from \"ora\";\nimport chalk from \"chalk\";\nimport { fileURLToPath } from \"url\";\nimport { dirname } from \"path\";\n\ninterface DownloadProgress {\n downloaded: number;\n total: number;\n percentage: number;\n}\n\ninterface BinaryVersion {\n date_published: string;\n name: string;\n version: string;\n platforms: string[];\n download_url: string;\n}\n\nclass Downloader {\n private static mainSpinner: any = null;\n private static currentSpinner: any = null;\n private static readonly VERSION_URLS = {\n query: 'https://raw.githubusercontent.com/Dbcube/binaries/main/query-engines.json',\n schema: 'https://raw.githubusercontent.com/Dbcube/binaries/main/schema-engines.json'\n };\n\n /**\n * Fetch latest version from GitHub\n */\n private static async fetchLatestVersion(prefix: 'query' | 'schema'): Promise<string> {\n const url = this.VERSION_URLS[prefix];\n\n return new Promise((resolve, reject) => {\n https.get(url, (response: IncomingMessage) => {\n let data = '';\n\n response.on('data', (chunk) => {\n data += chunk;\n });\n\n response.on('end', () => {\n try {\n const versions: BinaryVersion[] = JSON.parse(data);\n if (versions && versions.length > 0) {\n // Get the latest version (first in array)\n resolve(versions[0].version);\n } else {\n reject(new Error('No versions found'));\n }\n } catch (error) {\n reject(error);\n }\n });\n\n response.on('error', reject);\n }).on('error', reject);\n });\n }\n\n /**\n * Extract version from binary filename\n * Example: schema-engine-v1.0.0-windows-x64.exe -> v1.0.0\n */\n private static extractVersionFromFilename(filename: string): string | null {\n const match = filename.match(/-(v\\d+\\.\\d+\\.\\d+)-/);\n return match ? match[1] : null;\n }\n\n /**\n * Get local version of installed binary\n */\n private static getLocalVersion(binDir: string, prefix: string): string | null {\n try {\n const files = fs.readdirSync(binDir);\n const binaryPattern = new RegExp(`^${prefix}-engine-v`);\n const binaryFile = files.find(f => binaryPattern.test(f));\n\n if (binaryFile) {\n return this.extractVersionFromFilename(binaryFile);\n }\n } catch (error) {\n // Directory doesn't exist or can't read\n }\n return null;\n }\n\n /**\n * Compare versions (returns true if remote is newer)\n */\n private static isNewerVersion(localVersion: string | null, remoteVersion: string): boolean {\n if (!localVersion) return true; // No local version, download\n\n // Remove 'v' prefix if exists\n const cleanLocal = localVersion.replace(/^v/, '');\n const cleanRemote = remoteVersion.replace(/^v/, '');\n\n const localParts = cleanLocal.split('.').map(Number);\n const remoteParts = cleanRemote.split('.').map(Number);\n\n for (let i = 0; i < 3; i++) {\n if (remoteParts[i] > localParts[i]) return true;\n if (remoteParts[i] < localParts[i]) return false;\n }\n\n return false; // Versions are equal\n }\n\n /**\n * Delete old binary files\n */\n private static deleteOldBinary(binDir: string, prefix: string): void {\n try {\n const files = fs.readdirSync(binDir);\n const binaryPattern = new RegExp(`^${prefix}-engine-`);\n\n files.forEach(file => {\n if (binaryPattern.test(file)) {\n const filePath = path.join(binDir, file);\n try {\n fs.unlinkSync(filePath);\n console.log(`🗑️ Deleted old binary: ${file}`);\n } catch (err) {\n console.warn(`⚠️ Could not delete: ${file}`);\n }\n }\n });\n } catch (error) {\n // Ignore errors\n }\n }\n\n static get(prefix: string): BinaryType & { name: string; url: string; version: string } {\n const arch = new Arquitecture();\n const platform = arch.getPlatform();\n const architecture = arch.getArchitecture();\n\n const platformMap: Record<string, string> = {\n windows: \"windows\",\n linux: \"linux\",\n darwin: \"macos\"\n };\n\n const archMap: Record<string, string> = {\n x86_64: \"x64\",\n aarch64: \"arm64\"\n };\n\n const plat = platformMap[platform];\n const archSuffix = archMap[architecture];\n\n if (plat && archSuffix) {\n // Note: This is a sync method, version will be \"latest\" placeholder\n // The actual version will be resolved during download\n const baseName = `${prefix}-engine-${plat}-${archSuffix}`;\n const binaryName = platform === \"windows\" ? `${baseName}.exe` : baseName;\n\n const url = `https://github.com/Dbcube/binaries/releases/download/${prefix}-engine/${prefix}-engine-latest-${plat}-${archSuffix}.zip`;\n return {\n name: binaryName,\n url,\n version: \"latest\",\n query_engine: binaryName,\n schema_engine: `${prefix}-engine-${plat}-${archSuffix}${platform === \"windows\" ? \".exe\" : \"\"}`\n };\n }\n\n return {\n name: \"\",\n url: \"\",\n version: \"\",\n query_engine: \"\",\n schema_engine: \"\"\n };\n }\n\n /**\n * Get binary info with actual version from GitHub\n */\n static async getWithVersion(prefix: 'query' | 'schema'): Promise<BinaryType & { name: string; url: string; version: string }> {\n const arch = new Arquitecture();\n const platform = arch.getPlatform();\n const architecture = arch.getArchitecture();\n\n const platformMap: Record<string, string> = {\n windows: \"windows\",\n linux: \"linux\",\n darwin: \"macos\"\n };\n\n const archMap: Record<string, string> = {\n x86_64: \"x64\",\n aarch64: \"arm64\"\n };\n\n const plat = platformMap[platform];\n const archSuffix = archMap[architecture];\n\n if (plat && archSuffix) {\n // Fetch latest version from GitHub\n const version = await this.fetchLatestVersion(prefix);\n\n const baseName = `${prefix}-engine-${version}-${plat}-${archSuffix}`;\n const binaryName = platform === \"windows\" ? `${baseName}.exe` : baseName;\n\n const url = `https://github.com/Dbcube/binaries/releases/download/${prefix}-engine/${prefix}-engine-${version}-${plat}-${archSuffix}.zip`;\n return {\n name: binaryName,\n url,\n version,\n query_engine: binaryName,\n schema_engine: binaryName\n };\n }\n\n return {\n name: \"\",\n url: \"\",\n version: \"\",\n query_engine: \"\",\n schema_engine: \"\"\n };\n }\n\n static async download(targetDir?: string): Promise<void> {\n const binDir = targetDir || this.getDefaultBinDir();\n fs.mkdirSync(binDir, { recursive: true });\n\n // Initialize main spinner\n this.mainSpinner = ora({\n text: chalk.blue('Verificando versiones de binarios...'),\n spinner: 'dots12'\n }).start();\n\n const binariesToProcess: Array<{ prefix: 'query' | 'schema'; needsUpdate: boolean; localVersion: string | null; remoteVersion: string }> = [];\n\n // Check versions for all engines (sqlite-engine retirado: el config.db\n // interno ahora lo lee el query-engine)\n for (const prefix of ['query', 'schema'] as const) {\n try {\n const localVersion = this.getLocalVersion(binDir, prefix);\n const remoteVersion = await this.fetchLatestVersion(prefix);\n const needsUpdate = this.isNewerVersion(localVersion, remoteVersion);\n\n binariesToProcess.push({\n prefix,\n needsUpdate,\n localVersion,\n remoteVersion\n });\n\n if (needsUpdate) {\n console.log(`\\n📦 ${prefix}-engine: ${localVersion || 'not installed'} → ${remoteVersion}`);\n } else if (localVersion) {\n console.log(`\\n✅ ${prefix}-engine: ${localVersion} (up to date)`);\n }\n } catch (error) {\n console.warn(`⚠️ Could not check version for ${prefix}-engine, will attempt download`);\n binariesToProcess.push({\n prefix,\n needsUpdate: true,\n localVersion: null,\n remoteVersion: 'latest'\n });\n }\n }\n\n const binariesToDownload = binariesToProcess.filter(b => b.needsUpdate);\n\n if (binariesToDownload.length === 0) {\n this.mainSpinner.succeed(chalk.green('All binaries are up to date'));\n return;\n }\n\n // Show update progress\n this.mainSpinner.text = chalk.blue(`Updating ${binariesToDownload.length} binary(ies)...`);\n\n try {\n // Download and update binaries in parallel. allSettled: si una\n // descarga falla las demás terminan igual y se reportan TODOS los\n // errores (Promise.all descartaba los resultados restantes).\n const results = await Promise.allSettled(binariesToDownload.map(async (binary) => {\n const maxRetries = 3;\n let attempt = 0;\n\n while (attempt <= maxRetries) {\n try {\n // Get binary info with version\n const binaryInfo = await this.getWithVersion(binary.prefix);\n\n if (!binaryInfo.name || !binaryInfo.url) {\n throw new Error(`Platform or architecture not supported for ${binary.prefix}`);\n }\n\n const tempZipPath = path.join(os.tmpdir(), `dbcube-${binary.prefix}-${Date.now()}.zip`);\n const finalBinaryPath = path.join(binDir, binaryInfo.name);\n\n // Delete old binary first\n this.deleteOldBinary(binDir, binary.prefix);\n\n // Download\n await this.downloadFileWithProgress(binaryInfo.url, tempZipPath, binary.prefix);\n\n // Extract\n await this.extractBinary(tempZipPath, finalBinaryPath, binary.prefix);\n\n console.log(`✅ ${binary.prefix}-engine updated to ${binary.remoteVersion}`);\n break;\n\n } catch (error: unknown) {\n const errorMessage = error instanceof Error ? error.message : 'Unknown error';\n\n if (attempt < maxRetries && (\n errorMessage.includes('ECONNRESET') ||\n errorMessage.includes('timeout') ||\n errorMessage.includes('ETIMEDOUT') ||\n errorMessage.includes('ENOTFOUND')\n )) {\n attempt++;\n console.log(`🔄 Retrying ${binary.prefix}-engine (${attempt}/${maxRetries})...`);\n await new Promise(resolve => setTimeout(resolve, 1000 + Math.random() * 1000));\n } else {\n throw new Error(`Error downloading ${binary.prefix}: ${errorMessage}`);\n }\n }\n }\n }));\n\n const failures = results.filter((r): r is PromiseRejectedResult => r.status === 'rejected');\n if (failures.length > 0) {\n const messages = failures.map(f => f.reason instanceof Error ? f.reason.message : String(f.reason));\n throw new Error(messages.join(' | '));\n }\n\n // Complete successfully\n this.mainSpinner.succeed(chalk.green('Binaries updated successfully'));\n } catch (error: unknown) {\n const errorMessage = error instanceof Error ? error.message : 'Unknown error';\n this.mainSpinner.fail(chalk.red(`Error updating binaries: ${errorMessage}`));\n throw error;\n }\n }\n\n private static updateMainProgress(binary: string, current: number, total: number, status: string, attempt?: number) {\n const progressBar = this.createProgressBar(current, total);\n const statusEmojis = {\n downloading: '📥',\n extracting: '📦',\n completed: '✅',\n exists: '✅',\n retrying: '🔄'\n };\n\n const statusMessages = {\n downloading: chalk.blue('descargando'),\n extracting: chalk.yellow('extrayendo'),\n completed: chalk.green('completado'),\n exists: chalk.gray('existe'),\n retrying: chalk.yellow(`reintentando (${attempt}/${3})`)\n };\n\n const emoji = statusEmojis[status as keyof typeof statusEmojis] || '📥';\n const message = statusMessages[status as keyof typeof statusMessages] || status;\n\n this.mainSpinner.text = `${progressBar} ${emoji} ${chalk.bold(binary)} - ${message}`;\n }\n\n private static createProgressBar(current: number, total: number, width: number = 20): string {\n const filled = Math.round((current / total) * width);\n const empty = width - filled;\n const filledBar = chalk.green('█'.repeat(filled));\n const emptyBar = chalk.gray('░'.repeat(empty));\n const percentage = chalk.bold(`${current}/${total}`);\n return `[${filledBar}${emptyBar}] ${percentage}`;\n }\n\n private static downloadFileWithProgress(url: string, outputPath: string, prefix: string): Promise<void> {\n return new Promise((resolve, reject) => {\n const request = https.get(url, { timeout: 0 }, (response: IncomingMessage) => {\n if (response.statusCode === 302 || response.statusCode === 301) {\n const redirectUrl = response.headers.location;\n if (redirectUrl) {\n return this.downloadFileWithProgress(redirectUrl, outputPath, prefix).then(resolve).catch(reject);\n }\n }\n\n if (response.statusCode !== 200) {\n reject(new Error(`HTTP ${response.statusCode} para ${prefix}`));\n return;\n }\n\n const file = fs.createWriteStream(outputPath);\n const totalBytes = parseInt(response.headers['content-length'] || '0', 10);\n let downloadedBytes = 0;\n\n response.on('data', (chunk) => {\n downloadedBytes += chunk.length;\n file.write(chunk);\n\n if (totalBytes > 0) {\n const progress: DownloadProgress = {\n downloaded: downloadedBytes,\n total: totalBytes,\n percentage: (downloadedBytes / totalBytes) * 100\n };\n this.updateDownloadProgress(prefix, progress);\n }\n });\n\n response.on('end', () => {\n // Resolver recién cuando el archivo está flushed a disco;\n // si no, extractBinary puede leer un ZIP incompleto\n file.end(() => resolve());\n });\n\n response.on('error', (err) => {\n file.close();\n this.cleanupFile(outputPath);\n reject(err);\n });\n\n file.on('error', (err) => {\n file.close();\n this.cleanupFile(outputPath);\n reject(err);\n });\n });\n\n request.on('error', reject);\n request.on('timeout', () => {\n request.destroy();\n reject(new Error(`Timeout descargando ${prefix}`));\n });\n });\n }\n\n private static updateDownloadProgress(binary: string, progress: DownloadProgress) {\n const percentage = progress.percentage.toFixed(1);\n const downloaded = (progress.downloaded / 1024 / 1024).toFixed(1);\n const total = (progress.total / 1024 / 1024).toFixed(1);\n\n // Create a mini progress bar for the binary\n const barWidth = 15;\n const filled = Math.round((progress.percentage / 100) * barWidth);\n const empty = barWidth - filled;\n const progressBar = chalk.green('█'.repeat(filled)) + chalk.gray('░'.repeat(empty));\n\n const progressText = `[${progressBar}] ${percentage}% (${downloaded}/${total}MB)`;\n this.mainSpinner.text = `📥 ${chalk.bold(binary)} - ${progressText}`;\n }\n\n private static extractBinary(zipPath: string, outputPath: string, prefix: string): Promise<void> {\n return new Promise((resolve, reject) => {\n // Los ZIPs traen el binario principal (primer archivo) y, desde\n // v1.1.0, también la cdylib embebida (query-engine-embedded-*.dll/\n // .so/.dylib). El binario va a outputPath; el resto conserva su\n // nombre junto a él.\n const outDir = path.dirname(outputPath);\n let extracted = 0;\n const pending: Promise<void>[] = [];\n\n fs.createReadStream(zipPath)\n .pipe(unzipper.Parse())\n .on('entry', (entry: unzipper.Entry) => {\n if (entry.type !== 'File') {\n entry.autodrain();\n return;\n }\n const isMain = extracted === 0;\n extracted++;\n const target = isMain ? outputPath : path.join(outDir, path.basename(entry.path));\n\n pending.push(new Promise<void>((res, rej) => {\n const writeStream = fs.createWriteStream(target);\n entry.pipe(writeStream);\n writeStream.on('finish', () => {\n if (process.platform !== 'win32') {\n try { fs.chmodSync(target, 0o755); } catch { /* fs sin permisos */ }\n }\n res();\n });\n writeStream.on('error', rej);\n }));\n })\n .on('error', (err: Error) => {\n this.cleanupFile(zipPath);\n reject(err);\n })\n .on('close', () => {\n Promise.all(pending)\n .then(() => {\n this.cleanupFile(zipPath);\n if (extracted === 0) {\n reject(new Error(`No se encontró archivo válido en el ZIP para ${prefix}`));\n } else {\n resolve();\n }\n })\n .catch((err) => {\n this.cleanupFile(zipPath);\n reject(err);\n });\n });\n });\n }\n\n private static cleanupFile(filePath: string): void {\n try {\n if (fs.existsSync(filePath)) {\n fs.unlinkSync(filePath);\n }\n } catch {\n // Ignore cleanup errors\n }\n }\n\n private static getDefaultBinDir(): string {\n // Get __dirname equivalent for ESM\n const __filename = typeof import.meta !== 'undefined' && import.meta.url\n ? fileURLToPath(import.meta.url)\n : '';\n const __dirname = __filename ? dirname(__filename) : process.cwd();\n\n // Try to find a suitable directory for binaries in order of preference\n const possibleDirs = [\n path.resolve(process.cwd(), '.dbcube', 'bin'),\n path.resolve(process.cwd(), 'node_modules', '.dbcube', 'bin'),\n path.resolve(__dirname, '..', 'bin'),\n ];\n\n // Use the first one that can be created or already exists\n for (const dir of possibleDirs) {\n try {\n if (!fs.existsSync(dir)) {\n fs.mkdirSync(dir, { recursive: true });\n }\n // Test write permissions\n const testFile = path.join(dir, '.test');\n fs.writeFileSync(testFile, 'test');\n fs.unlinkSync(testFile);\n return dir;\n } catch {\n // Try next directory\n continue;\n }\n }\n\n // Fallback to .dbcube directory in temp\n const tempDir = path.join(os.tmpdir(), '.dbcube', 'bin');\n fs.mkdirSync(tempDir, { recursive: true });\n return tempDir;\n }\n}\n\nexport { Downloader };","import { BinaryType } from \"../@types/Binary\";\r\nimport { Arquitecture } from \"./Arquitecture\"\r\nimport { Downloader } from \"./Donwloader\";\r\nimport * as fs from \"fs\";\r\nimport * as path from \"path\";\r\nimport * as os from \"os\";\r\nimport { fileURLToPath } from \"url\";\r\nimport { dirname } from \"path\";\r\n\r\nclass Binary{\r\n private static isDownloading = false;\r\n private static downloadPromise: Promise<void> | null = null;\r\n private static cachedBinaries: { [key: string]: string } = {};\r\n\r\n static async ensureBinariesExist(): Promise<void> {\r\n if (this.isDownloading && this.downloadPromise) {\r\n await this.downloadPromise;\r\n return;\r\n }\r\n\r\n const binDir = this.getBinDir();\r\n\r\n // Always check and download/update binaries\r\n if (!this.isDownloading) {\r\n this.isDownloading = true;\r\n this.downloadPromise = this.downloadBinaries();\r\n\r\n try {\r\n await this.downloadPromise;\r\n } finally {\r\n this.isDownloading = false;\r\n this.downloadPromise = null;\r\n }\r\n }\r\n }\r\n\r\n private static async downloadBinaries(): Promise<void> {\r\n try {\r\n const binDir = this.getBinDir();\r\n await Downloader.download(binDir);\r\n } catch (error) {\r\n console.warn('⚠️ Dbcube: Error descargando binarios:', (error as Error).message);\r\n console.log('🔧 Los binarios se intentarán descargar en la próxima ejecución');\r\n }\r\n }\r\n\r\n private static getBinDir(): string {\r\n // Get __dirname equivalent for ESM\r\n const __filename = typeof import.meta !== 'undefined' && import.meta.url\r\n ? fileURLToPath(import.meta.url)\r\n : '';\r\n const __dirname = __filename ? dirname(__filename) : process.cwd();\r\n\r\n // Try to find a suitable directory for binaries in order of preference\r\n const possibleDirs = [\r\n path.resolve(process.cwd(), '.dbcube', 'bin'),\r\n path.resolve(process.cwd(), 'node_modules', '.dbcube', 'bin'),\r\n path.resolve(__dirname, '..', 'bin'),\r\n ];\r\n\r\n // Use the first one that can be created or already exists\r\n for (const dir of possibleDirs) {\r\n try {\r\n if (!fs.existsSync(dir)) {\r\n fs.mkdirSync(dir, { recursive: true });\r\n }\r\n \r\n \r\n return dir;\r\n } catch {\r\n // Try next directory\r\n continue;\r\n }\r\n }\r\n\r\n // Fallback to .dbcube directory in temp\r\n const tempDir = path.join(os.tmpdir(), '.dbcube', 'bin');\r\n fs.mkdirSync(tempDir, { recursive: true });\r\n return tempDir;\r\n }\r\n\r\n\r\n private static findVersionedBinary(binDir: string, prefix: string, platform: string, arch: string): string {\r\n // Check cache first\r\n const cacheKey = `${prefix}-${platform}-${arch}`;\r\n if (this.cachedBinaries[cacheKey]) {\r\n const cachedPath = path.join(binDir, this.cachedBinaries[cacheKey]);\r\n if (fs.existsSync(cachedPath)) {\r\n return cachedPath;\r\n }\r\n }\r\n\r\n try {\r\n const files = fs.readdirSync(binDir);\r\n const extension = platform === 'windows' ? '.exe' : '';\r\n const pattern = new RegExp(`^${prefix}-engine-v\\\\d+\\\\.\\\\d+\\\\.\\\\d+-${platform}-${arch}${extension.replace('.', '\\\\.')}$`);\r\n\r\n const matchingFile = files.find(f => pattern.test(f));\r\n\r\n if (matchingFile) {\r\n this.cachedBinaries[cacheKey] = matchingFile;\r\n return path.join(binDir, matchingFile);\r\n }\r\n } catch (error) {\r\n // Directory doesn't exist or can't read\r\n }\r\n\r\n // Fallback to non-versioned name (for backwards compatibility)\r\n const fallbackName = `${prefix}-engine-${platform}-${arch}${platform === 'windows' ? '.exe' : ''}`;\r\n return path.join(binDir, fallbackName);\r\n }\r\n\r\n static async get(): Promise<BinaryType> {\r\n await this.ensureBinariesExist();\r\n\r\n const arch = new Arquitecture();\r\n const platform = arch.getPlatform();\r\n const architecture = arch.getArchitecture();\r\n const binDir = this.getBinDir();\r\n\r\n const platformMap: Record<string, string> = {\r\n windows: \"windows\",\r\n linux: \"linux\",\r\n darwin: \"macos\"\r\n };\r\n\r\n const archMap: Record<string, string> = {\r\n x86_64: \"x64\",\r\n aarch64: \"arm64\"\r\n };\r\n\r\n const plat = platformMap[platform];\r\n const archSuffix = archMap[architecture];\r\n\r\n if (plat && archSuffix) {\r\n return {\r\n query_engine: this.findVersionedBinary(binDir, 'query', plat, archSuffix),\r\n schema_engine: this.findVersionedBinary(binDir, 'schema', plat, archSuffix)\r\n };\r\n }\r\n\r\n return {\r\n query_engine: \"\",\r\n schema_engine: \"\"\r\n };\r\n }\r\n}\r\n\r\nexport { Binary }","/**\n * Connection parameters for one database.\n */\nexport interface DatabaseConnectionConfig {\n /** Host name or IP (not used by SQLite) */\n HOST?: string;\n /** Database user (not used by SQLite) */\n USER?: string;\n /** Database password (not used by SQLite) */\n PASSWORD?: string;\n /** Database name (SQLite: file name without extension) */\n DATABASE: string;\n /** Port (not used by SQLite) */\n PORT?: number | string;\n}\n\n/**\n * Connection-pool tuning. Every field is optional — engine defaults apply\n * when omitted (maxConnections 5 — 10 for SQLite —, minConnections 2,\n * acquireTimeoutMs 3000, idleTimeoutMs 3600000).\n */\nexport interface DatabasePoolConfig {\n /** Max simultaneous connections held by the engine pool */\n maxConnections?: number;\n /** Connections kept warm even when idle */\n minConnections?: number;\n /** How long to wait for a free connection before failing (ms) */\n acquireTimeoutMs?: number;\n /** Close connections idle longer than this (ms) */\n idleTimeoutMs?: number;\n}\n\n/**\n * Daemon-mode tuning.\n */\nexport interface DatabaseDaemonConfig {\n /** Set to false to disable the persistent TCP daemon (one-shot mode).\n * Transactions require the daemon. Equivalent to DBCUBE_DAEMON=0. */\n enabled?: boolean;\n /** Per-request timeout against the daemon (ms, default 30000) */\n requestTimeoutMs?: number;\n}\n\nexport type DatabaseType = 'mysql' | 'postgres' | 'postgresql' | 'sqlite' | 'mongodb';\n\n/**\n * One database entry in dbcube.config.js.\n */\nexport interface DatabaseDefinition {\n type: DatabaseType;\n config: DatabaseConnectionConfig;\n pool?: DatabasePoolConfig;\n daemon?: DatabaseDaemonConfig;\n}\n\n/**\n * Shape accepted by config.set().\n */\nexport interface ConfigData {\n databases?: Record<string, DatabaseDefinition>;\n [key: string]: unknown;\n}\n\n/**\n * Clase para manejar la configuración del ORM\n */\nexport class Config {\n private data: ConfigData = {};\n private databases: Record<string, DatabaseDefinition> = {};\n\n /**\n * Establece la configuración\n * @param configData - Datos de configuración\n */\n set(configData: ConfigData): void {\n this.data = configData;\n\n if (configData.databases) {\n this.databases = configData.databases;\n }\n }\n\n /**\n * Obtiene un valor de configuración\n * @param key - Clave de configuración\n */\n get<T = unknown>(key: string): T {\n return this.data[key] as T;\n }\n\n /**\n * Obtiene la configuración de una base de datos específica\n * @param dbName - Nombre de la base de datos\n */\n getDatabase(dbName: string): DatabaseDefinition | null {\n return this.databases[dbName] || null;\n }\n\n /**\n * Obtiene todas las bases de datos configuradas\n */\n getAllDatabases(): Record<string, DatabaseDefinition> {\n return this.databases;\n }\n}\n\nexport default Config;\n","import net from 'net';\nimport fs from 'fs';\nimport path from 'path';\nimport { spawn } from 'child_process';\n\ninterface DaemonResponse {\n status: number;\n message: string;\n data: any;\n}\n\ninterface PendingRequest {\n resolve: (r: DaemonResponse) => void;\n reject: (e: Error) => void;\n timer: NodeJS.Timeout;\n}\n\n/**\n * TCP client for the query-engine daemon (server mode).\n *\n * Instead of spawning a new engine process per query (30-80ms overhead),\n * the daemon keeps the engine alive with warm connection pools and serves\n * requests over a local TCP socket in <1ms. One daemon per database name.\n */\nexport class DaemonClient {\n private static registry: Map<string, DaemonClient> = new Map();\n\n private name: string;\n private binaryPath: string;\n private engineArgs: string[];\n private socket: net.Socket | null = null;\n private buffer = '';\n private pending: PendingRequest[] = [];\n private starting: Promise<boolean> | null = null;\n private requestTimeout: number;\n\n private constructor(name: string, binaryPath: string, engineArgs: string[], requestTimeout = 30000) {\n this.name = name;\n this.binaryPath = binaryPath;\n this.engineArgs = engineArgs;\n this.requestTimeout = requestTimeout;\n }\n\n static get(name: string, binaryPath: string, engineArgs: string[]): DaemonClient {\n let client = this.registry.get(name);\n if (!client) {\n client = new DaemonClient(name, binaryPath, engineArgs);\n this.registry.set(name, client);\n }\n return client;\n }\n\n static isEnabled(): boolean {\n const flag = process.env.DBCUBE_DAEMON;\n if (flag === '0' || flag === 'false') return false;\n return true; // ON by default — fastest path with automatic fallback\n }\n\n private portfilePath(): string {\n return path.join(process.cwd(), '.dbcube', 'daemon', `${this.name}.json`);\n }\n\n private lockfilePath(): string {\n return path.join(process.cwd(), '.dbcube', 'daemon', `${this.name}.lock`);\n }\n\n /**\n * Exclusive-create lock so two processes never spawn two daemons for the\n * same database at once. Stale locks (crashed starter) expire after 15s.\n */\n private acquireSpawnLock(): boolean {\n const lockPath = this.lockfilePath();\n try {\n fs.mkdirSync(path.dirname(lockPath), { recursive: true });\n const fd = fs.openSync(lockPath, 'wx');\n fs.writeSync(fd, String(process.pid));\n fs.closeSync(fd);\n return true;\n } catch {\n try {\n const age = Date.now() - fs.statSync(lockPath).mtimeMs;\n if (age > 15000) {\n fs.unlinkSync(lockPath);\n return this.acquireSpawnLock();\n }\n } catch { /* lock vanished between checks */ }\n return false;\n }\n }\n\n private releaseSpawnLock(): void {\n try { fs.unlinkSync(this.lockfilePath()); } catch { /* already gone */ }\n }\n\n /**\n * Ensures a usable daemon connection. Returns false when the daemon\n * can't be used (old binary, startup failure) so callers fall back\n * to one-shot spawn mode.\n */\n async ensure(): Promise<boolean> {\n if (this.socket && !this.socket.destroyed) return true;\n if (this.starting) return this.starting;\n\n this.starting = this.connectOrStart().catch(() => false);\n const result = await this.starting;\n this.starting = null;\n return result;\n }\n\n private async connectOrStart(): Promise<boolean> {\n // 1. Try an existing daemon via portfile\n const port = this.readPortfile();\n if (port && await this.tryConnect(port)) return true;\n\n // 2. Stale portfile — remove and start a fresh daemon. The spawn lock\n // ensures only one process boots the daemon; the rest just wait for\n // the new portfile to appear.\n const gotLock = this.acquireSpawnLock();\n try {\n if (gotLock) {\n try { fs.unlinkSync(this.portfilePath()); } catch { /* not there */ }\n this.spawnDaemon();\n }\n\n // 3. Poll the portfile while the daemon boots (up to 10s)\n const deadline = Date.now() + 10000;\n while (Date.now() < deadline) {\n await new Promise(r => setTimeout(r, 150));\n const newPort = this.readPortfile();\n if (newPort && await this.tryConnect(newPort)) return true;\n }\n return false;\n } finally {\n if (gotLock) this.releaseSpawnLock();\n }\n }\n\n private readPortfile(): number | null {\n try {\n const raw = fs.readFileSync(this.portfilePath(), 'utf8');\n const info = JSON.parse(raw);\n const port = info?.port;\n return Number.isInteger(port) && port > 0 && port <= 65535 ? port : null;\n } catch {\n return null;\n }\n }\n\n private spawnDaemon(): void {\n const child = spawn(this.binaryPath, [...this.engineArgs, '--action', 'server', '--tcp-port', '9944'], {\n detached: true,\n stdio: 'ignore',\n cwd: process.cwd(),\n });\n child.unref();\n }\n\n private tryConnect(port: number): Promise<boolean> {\n return new Promise((resolve) => {\n const socket = net.createConnection({ host: '127.0.0.1', port }, async () => {\n socket.setNoDelay(true);\n this.attach(socket);\n // Verify it's a current-generation daemon (supports ping).\n // Short timeout: if the port was reused by an unrelated\n // process, we must not hang the full request timeout.\n try {\n const pong = await this.send({ action: 'ping' }, 2000);\n resolve(pong.status === 200);\n } catch {\n this.detach();\n resolve(false);\n }\n });\n socket.once('error', () => resolve(false));\n socket.setTimeout(3000, () => { socket.destroy(); resolve(false); });\n });\n }\n\n private attach(socket: net.Socket): void {\n this.socket = socket;\n this.buffer = '';\n socket.setTimeout(0);\n socket.on('data', (chunk: Buffer | string) => this.onData(Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk)));\n socket.on('close', () => this.detach());\n socket.on('error', () => this.detach());\n }\n\n private detach(): void {\n if (this.socket) {\n this.socket.removeAllListeners();\n this.socket.destroy();\n this.socket = null;\n }\n // Fail anything still in flight\n for (const req of this.pending.splice(0)) {\n clearTimeout(req.timer);\n req.reject(new Error('Daemon connection lost'));\n }\n }\n\n private onData(chunk: Buffer): void {\n this.buffer += chunk.toString('utf8');\n let idx: number;\n while ((idx = this.buffer.indexOf('\\n')) !== -1) {\n const line = this.buffer.slice(0, idx).trim();\n this.buffer = this.buffer.slice(idx + 1);\n if (!line) continue;\n const marker = line.indexOf('PROCESS_RESPONSE:');\n if (marker === -1) continue; // engine log noise\n const jsonPart = line.slice(marker + 'PROCESS_RESPONSE:'.length);\n const req = this.pending.shift();\n if (!req) continue;\n clearTimeout(req.timer);\n try {\n req.resolve(JSON.parse(jsonPart));\n } catch (e: any) {\n req.reject(new Error(`Invalid daemon response: ${e.message}`));\n }\n }\n }\n\n /**\n * Sends a request to the daemon. Responses arrive in FIFO order on the\n * single socket, so pending requests resolve in send order.\n */\n send(payload: Record<string, any>, timeoutMs?: number): Promise<DaemonResponse> {\n return new Promise((resolve, reject) => {\n if (!this.socket || this.socket.destroyed) {\n reject(new Error('Daemon not connected'));\n return;\n }\n const timer = setTimeout(() => {\n const i = this.pending.findIndex(p => p.timer === timer);\n if (i !== -1) this.pending.splice(i, 1);\n reject(new Error('Daemon request timeout'));\n // La respuesta tardía de este request llegaría igual y se\n // emparejaría con el siguiente pending (FIFO desincronizado,\n // datos cruzados). La conexión ya no es confiable: descartarla.\n this.detach();\n }, timeoutMs ?? this.requestTimeout);\n\n this.pending.push({ resolve, reject, timer });\n this.socket.write(JSON.stringify(payload) + '\\n');\n });\n }\n\n async execute(dml: object, txId?: string): Promise<DaemonResponse> {\n const payload: Record<string, any> = { action: 'execute', dml };\n if (txId) payload.tx_id = txId;\n return this.send(payload);\n }\n\n async raw(query: string, params: any[] = [], txId?: string): Promise<DaemonResponse> {\n const payload: Record<string, any> = { action: 'raw', query, params };\n if (txId) payload.tx_id = txId;\n return this.send(payload);\n }\n\n async begin(): Promise<string> {\n const res = await this.send({ action: 'begin' });\n if (res.status !== 200 || !res.data?.tx_id) {\n throw new Error(res.message || 'Failed to begin transaction');\n }\n return res.data.tx_id;\n }\n\n async commit(txId: string): Promise<void> {\n const res = await this.send({ action: 'commit', tx_id: txId });\n if (res.status !== 200) throw new Error(res.message || 'Failed to commit transaction');\n }\n\n async rollback(txId: string): Promise<void> {\n const res = await this.send({ action: 'rollback', tx_id: txId });\n if (res.status !== 200) throw new Error(res.message || 'Failed to rollback transaction');\n }\n\n async shutdown(): Promise<void> {\n try { await this.send({ action: 'shutdown' }); } catch { /* daemon exits mid-response */ }\n this.detach();\n try { fs.unlinkSync(this.portfilePath()); } catch { /* already gone */ }\n }\n}\n\nexport default DaemonClient;\n","import path from \"path\";\r\nimport { Binary } from \"./Binary\";\r\nimport { Config as ConfigClass } from './Config';\r\nimport { EmbeddedEngine } from './EmbeddedEngine';\r\nimport { ProcessResponse, ResponseEngine } from \"../@types/Engine\";\r\nimport { BinaryType } from \"../@types/Binary\";\r\nimport { createRequire } from 'module';\r\nimport * as net from 'net';\r\nimport { spawn, ChildProcess } from \"child_process\";\r\n\r\n// Almacén global de servidores TCP y conexiones persistentes\r\nconst globalTcpServers = new Map<string, { port: number, process: ChildProcess | null }>();\r\n\r\n// Pool de sockets por base de datos: N conexiones al daemon con UNA petición\r\n// en vuelo por socket. Con un único socket + cola FIFO, 100 queries de un\r\n// Promise.all se ejecutaban en serie (~100 × RTT); con el pool corren en\r\n// paralelo real contra el pool sqlx del daemon.\r\ninterface SocketPool {\r\n free: net.Socket[];\r\n total: number;\r\n waiters: Array<(s: net.Socket) => void>;\r\n}\r\nconst socketPools = new Map<string, SocketPool>();\r\nconst CLIENT_POOL_SIZE = 10; // alineado con el pool sqlx del daemon\r\n\r\n// Query Cache para evitar JSON.parse repetido\r\nconst queryCache = new Map<string, any>();\r\nconst MAX_CACHE_SIZE = 500;\r\n\r\nclass QueryEngine {\r\n private name: string;\r\n private config: any;\r\n private arguments: any;\r\n private binary: BinaryType | null = null;\r\n private timeout: number;\r\n private connectionId: string;\r\n private tcpPort: number;\r\n\r\n constructor(name: string, timeout = 30000, explicitConfig?: any) {\r\n this.name = name;\r\n // `explicitConfig` permite conexiones internas que NO viven en\r\n // dbcube.config.js (p. ej. el config.db de DBCube). El resto resuelve\r\n // su config por nombre desde dbcube.config.js.\r\n this.config = explicitConfig ?? this.setConfig(name);\r\n this.arguments = this.setArguments();\r\n // daemon.requestTimeoutMs de dbcube.config.js manda sobre el default\r\n this.timeout = this.config?.daemon?.requestTimeoutMs ?? timeout;\r\n this.connectionId = `${name}_query_engine_${this.config.type}_${this.config.config.DATABASE}_${this.config.config.HOST || 'localhost'}`;\r\n this.tcpPort = this.generatePort();\r\n }\r\n\r\n private generatePort(): number {\r\n // Empezar desde el puerto 9944 y buscar hacia abajo\r\n return 9944;\r\n }\r\n\r\n private async findAvailablePort(startPort: number): Promise<number> {\r\n for (let port = startPort; port >= 9900; port--) {\r\n if (await this.isPortAvailable(port)) {\r\n return port;\r\n }\r\n }\r\n throw new Error('No available ports found in range 9900-9944');\r\n }\r\n\r\n private isPortAvailable(port: number): Promise<boolean> {\r\n return new Promise((resolve) => {\r\n const tester = net.createServer();\r\n\r\n tester.once('error', () => resolve(false));\r\n tester.once('listening', () => {\r\n tester.close();\r\n resolve(true);\r\n });\r\n\r\n tester.listen(port, '127.0.0.1');\r\n });\r\n }\r\n\r\n async initializeBinary(): Promise<void> {\r\n if (!this.binary) {\r\n this.binary = await Binary.get();\r\n }\r\n }\r\n\r\n setArguments() {\r\n let args = [];\r\n if (this.config.type == 'sqlite') {\r\n args = [\r\n '--id', 'dbcube-' + this.name,\r\n '--database-ref', this.name,\r\n '--database', this.config.config.DATABASE + \".db\",\r\n '--motor', this.config.type\r\n ];\r\n } else {\r\n args = [\r\n '--id', 'dbcube-' + this.name,\r\n '--database-ref', this.name,\r\n '--database', this.config.config.DATABASE,\r\n '--host', this.config.config.HOST,\r\n '--port', String(this.config.config.PORT),\r\n '--motor', this.config.type\r\n ];\r\n // Credenciales opcionales (p. ej. MongoDB local sin auth)\r\n if (this.config.config.USER != null && this.config.config.USER !== '') {\r\n args.push('--user', this.config.config.USER);\r\n }\r\n if (this.config.config.PASSWORD != null && this.config.config.PASSWORD !== '') {\r\n args.push('--password', this.config.config.PASSWORD);\r\n }\r\n }\r\n\r\n // Tuning de pool desde la sección `pool` de dbcube.config.js\r\n const pool = this.config.pool ?? {};\r\n if (pool.maxConnections != null) args.push('--max-connections', String(pool.maxConnections));\r\n if (pool.minConnections != null) args.push('--min-connections', String(pool.minConnections));\r\n if (pool.acquireTimeoutMs != null) args.push('--acquire-timeout-ms', String(pool.acquireTimeoutMs));\r\n if (pool.idleTimeoutMs != null) args.push('--idle-timeout-ms', String(pool.idleTimeoutMs));\r\n\r\n return args;\r\n }\r\n\r\n /** El daemon puede desactivarse por config (daemon.enabled=false) o por env (DBCUBE_DAEMON=0). */\r\n private daemonEnabled(): boolean {\r\n const flag = process.env.DBCUBE_DAEMON;\r\n if (flag === '0' || flag === 'false') return false;\r\n return this.config?.daemon?.enabled !== false;\r\n }\r\n\r\n setConfig(name: string) {\r\n const configInstance = new ConfigClass();\r\n\r\n try {\r\n const configFilePath = path.resolve(process.cwd(), 'dbcube.config.js');\r\n const requireUrl = typeof __filename !== 'undefined' ? __filename : process.cwd();\r\n const require = createRequire(requireUrl);\r\n // Clear require cache to ensure fresh load (safe check for bundled environments)\r\n if (require.cache && require.resolve) {\r\n try {\r\n delete require.cache[require.resolve(configFilePath)];\r\n } catch (e) {\r\n // Ignore errors in bundled environments\r\n }\r\n }\r\n const configModule = require(configFilePath);\r\n const configFn = configModule.default || configModule;\r\n\r\n if (typeof configFn === 'function') {\r\n configFn(configInstance);\r\n } else {\r\n console.error('❌ El archivo dbcube.config.js no exporta una función.');\r\n }\r\n } catch (error: any) {\r\n console.error('❌ Error loading config file:', error.message);\r\n if (error.code === 'MODULE_NOT_FOUND') {\r\n console.error('❌ Config file not found, please create a dbcube.config.js file');\r\n }\r\n }\r\n\r\n return configInstance.getDatabase(name);\r\n }\r\n\r\n getConfig() {\r\n return this.config;\r\n }\r\n\r\n async run(binary: string, args: string[]): Promise<ResponseEngine> {\r\n // Detectar si es una acción execute de query_engine\r\n const actionIndex = args.findIndex(arg => arg === '--action');\r\n const isExecuteAction = actionIndex !== -1 && args[actionIndex + 1] === 'execute';\r\n const isQueryEngine = binary === 'query_engine';\r\n\r\n if (isQueryEngine && isExecuteAction) {\r\n // Solo query_engine con execute usa servidor TCP con cola\r\n return this.executeWithTcpServer(this.argsToCommand(args));\r\n } else {\r\n // Para otras acciones, usar método normal\r\n return this.createProcess(binary, args);\r\n }\r\n }\r\n\r\n private argsToCommand(args: string[]): Record<string, any> {\r\n const command: Record<string, any> = {};\r\n for (let i = 0; i < args.length; i += 2) {\r\n if (args[i].startsWith('--')) {\r\n command[args[i].substring(2)] = args[i + 1];\r\n }\r\n }\r\n return command;\r\n }\r\n\r\n /** El motor embebido (FFI) es el camino por defecto cuando la librería\r\n * nativa está disponible; el daemon TCP queda como fallback y como modo\r\n * multi-proceso explícito. */\r\n private useEmbedded(): boolean {\r\n return EmbeddedEngine.available();\r\n }\r\n\r\n /**\r\n * Executes a DML plan. Embedded engine when available (in-process FFI,\r\n * no network hop); persistent TCP daemon otherwise.\r\n * Pass txId to run it inside an active transaction.\r\n */\r\n async executeDml(dml: object, txId?: string): Promise<ResponseEngine> {\r\n if (this.useEmbedded()) {\r\n return EmbeddedEngine.executeDml(this.connectionId, this.config, dml, txId);\r\n }\r\n // El DML viaja como objeto dentro del comando: una sola serialización\r\n // (el server acepta objeto; el string anidado queda para clientes legacy)\r\n const command: Record<string, any> = { action: 'execute', dml };\r\n if (txId) command.tx_id = txId;\r\n return this.executeWithTcpServer(command);\r\n }\r\n\r\n /**\r\n * Atomic batch: N write plans inside one transaction with a single\r\n * engine round-trip. Falls back to begin/ops/commit over the daemon\r\n * when the embedded engine is not available.\r\n */\r\n async executeBatch(ops: object[]): Promise<ResponseEngine> {\r\n if (this.useEmbedded()) {\r\n return EmbeddedEngine.executeBatch(this.connectionId, this.config, ops);\r\n }\r\n // Fallback daemon: misma atomicidad, N+2 cruces\r\n const txId = await this.beginTransaction();\r\n try {\r\n const results: any[] = [];\r\n for (const op of ops) {\r\n const res = await this.executeDml(op, txId);\r\n if (res.status !== 200) {\r\n throw new Error(String(res.message));\r\n }\r\n results.push(res.data);\r\n }\r\n await this.commitTransaction(txId);\r\n return { status: 200, message: 'Batch committed', data: results };\r\n } catch (error: any) {\r\n try { await this.rollbackTransaction(txId); } catch { /* secundario */ }\r\n return { status: 500, message: error?.message ?? String(error), data: null };\r\n }\r\n }\r\n\r\n /**\r\n * Executes raw SQL (or a MongoDB command document) with bound parameters.\r\n */\r\n async rawQuery(query: string, params: any[] = [], txId?: string): Promise<ResponseEngine> {\r\n if (this.useEmbedded()) {\r\n return EmbeddedEngine.rawQuery(this.connectionId, this.config, query, params, txId);\r\n }\r\n const command: Record<string, any> = { action: 'raw', query, params };\r\n if (txId) command.tx_id = txId;\r\n return this.executeWithTcpServer(command);\r\n }\r\n\r\n /** Starts a transaction and returns its id. */\r\n async beginTransaction(): Promise<string> {\r\n const res = this.useEmbedded()\r\n ? await EmbeddedEngine.begin(this.connectionId, this.config)\r\n : await this.executeWithTcpServer({ action: 'begin' });\r\n if (res.status !== 200 || !res.data?.tx_id) {\r\n throw new Error(String(res.message || 'Failed to begin transaction (update the query-engine binary: npx dbcube update)'));\r\n }\r\n return res.data.tx_id;\r\n }\r\n\r\n async commitTransaction(txId: string): Promise<void> {\r\n const res = this.useEmbedded()\r\n ? await EmbeddedEngine.commit(this.connectionId, this.config, txId)\r\n : await this.executeWithTcpServer({ action: 'commit', tx_id: txId });\r\n if (res.status !== 200) throw new Error(String(res.message || 'Failed to commit transaction'));\r\n }\r\n\r\n async rollbackTransaction(txId: string): Promise<void> {\r\n const res = this.useEmbedded()\r\n ? await EmbeddedEngine.rollback(this.connectionId, this.config, txId)\r\n : await this.executeWithTcpServer({ action: 'rollback', tx_id: txId });\r\n if (res.status !== 200) throw new Error(String(res.message || 'Failed to rollback transaction'));\r\n }\r\n\r\n private async executeWithTcpServer(command: Record<string, any>): Promise<ResponseEngine> {\r\n // Daemon desactivado: ejecutar one-shot por spawn. Las transacciones\r\n // requieren el daemon (la TX vive en su memoria entre requests).\r\n if (!this.daemonEnabled()) {\r\n if (command.tx_id || ['begin', 'commit', 'rollback'].includes(command.action)) {\r\n throw new Error('Transactions require daemon mode. Remove daemon.enabled=false from dbcube.config.js (or unset DBCUBE_DAEMON=0).');\r\n }\r\n const args: string[] = [];\r\n for (const [key, value] of Object.entries(command)) {\r\n args.push(`--${key.replace(/_/g, '-')}`, typeof value === 'string' ? value : JSON.stringify(value));\r\n }\r\n return this.createProcess('query_engine', args);\r\n }\r\n\r\n const serverInfo = globalTcpServers.get(this.connectionId);\r\n\r\n // Si no hay servidor TCP, iniciarlo\r\n if (!serverInfo || !serverInfo.process || serverInfo.process.killed) {\r\n await this.startTcpServer();\r\n // Solo verificar la primera vez\r\n await this.waitForServerReady();\r\n }\r\n\r\n const port = globalTcpServers.get(this.connectionId)!.port;\r\n const socket = await this.acquireSocket(port);\r\n try {\r\n const result = await this.executeOnConnection(socket, command);\r\n this.releaseSocket(socket, false);\r\n return result;\r\n } catch (error) {\r\n // Un socket que falló o quedó con respuesta pendiente no es\r\n // reutilizable: descartarlo y dejar que el pool crezca de nuevo\r\n this.releaseSocket(socket, true);\r\n throw error;\r\n }\r\n }\r\n\r\n private poolFor(): SocketPool {\r\n let pool = socketPools.get(this.connectionId);\r\n if (!pool) {\r\n pool = { free: [], total: 0, waiters: [] };\r\n socketPools.set(this.connectionId, pool);\r\n }\r\n return pool;\r\n }\r\n\r\n private async acquireSocket(port: number): Promise<net.Socket> {\r\n const pool = this.poolFor();\r\n\r\n // Reusar un socket libre vivo\r\n while (pool.free.length > 0) {\r\n const s = pool.free.pop()!;\r\n if (!s.destroyed) return s;\r\n pool.total--;\r\n }\r\n\r\n if (pool.total < CLIENT_POOL_SIZE) {\r\n pool.total++;\r\n try {\r\n return await this.createNewConnection(port);\r\n } catch (e) {\r\n pool.total--;\r\n throw e;\r\n }\r\n }\r\n\r\n // Pool lleno: esperar a que se libere uno\r\n return new Promise<net.Socket>(resolve => pool.waiters.push(resolve));\r\n }\r\n\r\n private releaseSocket(socket: net.Socket, broken: boolean): void {\r\n const pool = socketPools.get(this.connectionId);\r\n if (!pool) { socket.destroy(); return; }\r\n\r\n if (broken || socket.destroyed) {\r\n pool.total--;\r\n try { socket.destroy(); } catch { /* ya cerrado */ }\r\n return;\r\n }\r\n\r\n const waiter = pool.waiters.shift();\r\n if (waiter) {\r\n waiter(socket);\r\n } else {\r\n pool.free.push(socket);\r\n }\r\n }\r\n\r\n private async waitForServerReady(): Promise<void> {\r\n const maxRetries = 10;\r\n const retryDelay = 500; // 500ms entre intentos\r\n\r\n const serverInfo = globalTcpServers.get(this.connectionId);\r\n if (!serverInfo) {\r\n throw new Error('Server not found');\r\n }\r\n\r\n for (let i = 0; i < maxRetries; i++) {\r\n if (await this.isServerResponding(serverInfo.port)) {\r\n return;\r\n }\r\n await this.sleep(retryDelay);\r\n }\r\n throw new Error('TCP server failed to become ready within timeout');\r\n }\r\n\r\n private async isServerResponding(port: number): Promise<boolean> {\r\n return new Promise((resolve) => {\r\n const client = new net.Socket();\r\n const timeout = setTimeout(() => {\r\n client.destroy();\r\n resolve(false);\r\n }, 1000);\r\n\r\n client.connect(port, '127.0.0.1', () => {\r\n clearTimeout(timeout);\r\n client.destroy();\r\n resolve(true);\r\n });\r\n\r\n client.on('error', () => {\r\n clearTimeout(timeout);\r\n resolve(false);\r\n });\r\n });\r\n }\r\n\r\n private sleep(ms: number): Promise<void> {\r\n return new Promise(resolve => setTimeout(resolve, ms));\r\n }\r\n\r\n private getCachedDML(dmlJson: string): any {\r\n // Buscar en cache primero\r\n if (queryCache.has(dmlJson)) {\r\n return queryCache.get(dmlJson);\r\n }\r\n\r\n // Parse y guardar en cache, desalojando la entrada más vieja si está\r\n // lleno (Map conserva orden de inserción)\r\n const parsed = JSON.parse(dmlJson);\r\n\r\n if (queryCache.size >= MAX_CACHE_SIZE) {\r\n const oldest = queryCache.keys().next().value;\r\n if (oldest !== undefined) queryCache.delete(oldest);\r\n }\r\n queryCache.set(dmlJson, parsed);\r\n\r\n return parsed;\r\n }\r\n\r\n private async startTcpServer(): Promise<void> {\r\n await this.initializeBinary();\r\n\r\n if (!this.binary) {\r\n throw new Error('Binary not initialized');\r\n }\r\n\r\n // Buscar puerto disponible\r\n this.tcpPort = await this.findAvailablePort(this.tcpPort);\r\n\r\n return new Promise((resolve, reject) => {\r\n // Iniciar el query_engine como servidor TCP\r\n const serverArgs = [...this.arguments, '--action', 'server', '--tcp-port', this.tcpPort.toString()];\r\n const serverProcess = spawn(this.binary!['query_engine' as keyof BinaryType], serverArgs);\r\n\r\n let started = false;\r\n\r\n const timeout = setTimeout(() => {\r\n if (!started) {\r\n serverProcess.kill();\r\n reject(new Error('TCP server startup timeout'));\r\n }\r\n }, 15000); // Aumentar timeout a 15 segundos\r\n\r\n serverProcess.stdout.on('data', (data) => {\r\n const output = data.toString();\r\n\r\n if (output.includes('TCP Server listening on')) {\r\n if (!started) {\r\n started = true;\r\n clearTimeout(timeout);\r\n globalTcpServers.set(this.connectionId, {\r\n port: this.tcpPort,\r\n process: serverProcess\r\n });\r\n resolve();\r\n }\r\n }\r\n });\r\n\r\n serverProcess.stderr.on('data', (data) => {\r\n console.error(`[query_engine TCP Server Error] ${data.toString().trim()}`);\r\n });\r\n\r\n serverProcess.on('close', (code) => {\r\n globalTcpServers.delete(this.connectionId);\r\n });\r\n\r\n serverProcess.on('error', (error) => {\r\n if (!started) {\r\n clearTimeout(timeout);\r\n reject(error);\r\n }\r\n });\r\n });\r\n }\r\n\r\n private async createNewConnection(port: number): Promise<net.Socket> {\r\n return new Promise((resolve, reject) => {\r\n const client = new net.Socket();\r\n client.setNoDelay(true);\r\n client.setKeepAlive(true, 60000);\r\n\r\n const timeout = setTimeout(() => {\r\n client.destroy();\r\n reject(new Error('Connection timeout'));\r\n }, 5000);\r\n\r\n client.connect(port, '127.0.0.1', () => {\r\n clearTimeout(timeout);\r\n resolve(client);\r\n });\r\n\r\n client.on('error', (error) => {\r\n clearTimeout(timeout);\r\n reject(error);\r\n });\r\n });\r\n }\r\n\r\n private async executeOnConnection(connection: net.Socket, command: Record<string, any>): Promise<ResponseEngine> {\r\n return new Promise((resolve, reject) => {\r\n let responseBuffer = '';\r\n let isResolved = false;\r\n\r\n const timeout = setTimeout(() => {\r\n if (!isResolved) {\r\n isResolved = true;\r\n connection.removeListener('data', onData);\r\n connection.removeListener('error', onError);\r\n reject(new Error('Request timeout'));\r\n }\r\n }, this.timeout);\r\n\r\n const onData = (data: Buffer) => {\r\n responseBuffer += data.toString();\r\n // Framing por línea: el server termina cada respuesta con '\\n'.\r\n // Un regex sobre el buffer parcial dispararía antes de tiempo\r\n // con respuestas grandes fragmentadas en varios chunks TCP\r\n // (matchearía hasta un '}' interno y el JSON.parse fallaría).\r\n let idx: number;\r\n while ((idx = responseBuffer.indexOf('\\n')) !== -1 && !isResolved) {\r\n const line = responseBuffer.slice(0, idx);\r\n responseBuffer = responseBuffer.slice(idx + 1);\r\n const marker = line.indexOf('PROCESS_RESPONSE:');\r\n if (marker === -1) continue; // ruido de logs del engine\r\n isResolved = true;\r\n clearTimeout(timeout);\r\n connection.removeListener('data', onData);\r\n connection.removeListener('error', onError);\r\n\r\n try {\r\n const response: ProcessResponse = JSON.parse(line.slice(marker + 'PROCESS_RESPONSE:'.length));\r\n resolve({\r\n status: response.status,\r\n message: response.message,\r\n data: response.data\r\n });\r\n } catch (error) {\r\n reject(new Error('Failed to parse response'));\r\n }\r\n }\r\n };\r\n\r\n const onError = (error: Error) => {\r\n if (!isResolved) {\r\n isResolved = true;\r\n clearTimeout(timeout);\r\n connection.removeListener('data', onData);\r\n connection.removeListener('error', onError);\r\n reject(error);\r\n }\r\n };\r\n\r\n connection.on('data', onData);\r\n connection.on('error', onError);\r\n\r\n // Enviar comando como JSON delimitado por '\\n' (framing del servidor)\r\n connection.write(JSON.stringify(command) + '\\n');\r\n });\r\n }\r\n\r\n private async createProcess(binary: string, args: string[]): Promise<ResponseEngine> {\r\n await this.initializeBinary();\r\n\r\n if (!this.binary) {\r\n throw new Error('Binary not initialized');\r\n }\r\n\r\n return new Promise<ResponseEngine>((resolve, reject) => {\r\n const child = spawn(this.binary![binary as keyof BinaryType], [...this.arguments, ...args]);\r\n\r\n let stdoutBuffer = '';\r\n let stderrBuffer = '';\r\n let isResolved = false;\r\n\r\n const timeoutId = setTimeout(() => {\r\n if (!isResolved) {\r\n isResolved = true;\r\n child.kill();\r\n reject(new Error('Process timeout'));\r\n }\r\n }, this.timeout);\r\n\r\n const resolveOnce = (response: ResponseEngine) => {\r\n if (!isResolved) {\r\n isResolved = true;\r\n clearTimeout(timeoutId);\r\n resolve(response);\r\n }\r\n };\r\n\r\n // Framing por línea (la respuesta termina en '\\n'): un regex sobre\r\n // el buffer parcial fallaría con respuestas grandes fragmentadas\r\n const tryParseLines = (buffer: string): string => {\r\n let idx: number;\r\n while ((idx = buffer.indexOf('\\n')) !== -1) {\r\n const line = buffer.slice(0, idx);\r\n buffer = buffer.slice(idx + 1);\r\n const marker = line.indexOf('PROCESS_RESPONSE:');\r\n if (marker === -1) continue;\r\n try {\r\n const response: ProcessResponse = JSON.parse(line.slice(marker + 'PROCESS_RESPONSE:'.length));\r\n resolveOnce({\r\n status: response.status,\r\n message: response.message,\r\n data: response.data\r\n });\r\n } catch (error) {\r\n resolveOnce({\r\n status: 500,\r\n message: 'Failed to parse response JSON',\r\n data: null\r\n });\r\n }\r\n }\r\n return buffer;\r\n };\r\n\r\n child.stdout.on('data', (data) => {\r\n stdoutBuffer = tryParseLines(stdoutBuffer + data.toString());\r\n });\r\n\r\n child.stderr.on('data', (data) => {\r\n stderrBuffer = tryParseLines(stderrBuffer + data.toString());\r\n });\r\n\r\n child.on('close', (code) => {\r\n clearTimeout(timeoutId);\r\n if (!isResolved) {\r\n resolveOnce({\r\n status: code === 0 ? 200 : 500,\r\n message: code === 0 ? 'Process completed' : `Process exited with code ${code}`,\r\n data: null\r\n });\r\n }\r\n });\r\n\r\n child.on('error', (error) => {\r\n clearTimeout(timeoutId);\r\n if (!isResolved) {\r\n resolveOnce({\r\n status: 500,\r\n message: `Process error: ${error.message}`,\r\n data: null\r\n });\r\n }\r\n });\r\n\r\n child.unref();\r\n });\r\n }\r\n\r\n async disconnect(): Promise<ResponseEngine> {\r\n // Liberar la conexión del motor embebido si existe\r\n await EmbeddedEngine.disconnect(this.connectionId);\r\n\r\n // Cerrar todos los sockets del pool\r\n const pool = socketPools.get(this.connectionId);\r\n if (pool) {\r\n for (const s of pool.free) {\r\n try { s.destroy(); } catch { /* ya cerrado */ }\r\n }\r\n socketPools.delete(this.connectionId);\r\n }\r\n\r\n const serverInfo = globalTcpServers.get(this.connectionId);\r\n\r\n if (serverInfo && serverInfo.process && !serverInfo.process.killed) {\r\n serverInfo.process.kill();\r\n globalTcpServers.delete(this.connectionId);\r\n\r\n return {\r\n status: 200,\r\n message: 'TCP server and connections stopped',\r\n data: null\r\n };\r\n }\r\n\r\n return {\r\n status: 200,\r\n message: 'No TCP server to stop',\r\n data: null\r\n };\r\n }\r\n}\r\n\r\nexport { QueryEngine }","import * as fs from 'fs';\nimport * as path from 'path';\nimport { ResponseEngine } from '../@types/Engine';\n\n/**\n * Motor embebido: el query-engine de Rust cargado DENTRO del proceso, en\n * lugar de hablarle por TCP a un daemon. Elimina el round-trip de red por\n * query (~1-1.5ms → ~µs).\n *\n * Dos backends, en orden de preferencia:\n * 1. **Addon napi** (`query-engine-node-<plat>-<arch>.node`): async real —\n * cada llamada corre en el runtime tokio del addon y resuelve la Promise\n * vía threadsafe-function, sin ocupar el threadpool de libuv ni\n * serializar marshaling en el hilo principal (concurrencia plena).\n * 2. **koffi/FFI** (`query-engine-embedded-<plat>-<arch>.dll/.so/.dylib`):\n * interfaz C pura — el mismo contrato que usarán Python/PHP/Go.\n *\n * - Desactivable con DBCUBE_EMBEDDED=0 (vuelve al daemon TCP).\n * - El daemon sigue siendo el modo correcto cuando varios PROCESOS quieren\n * compartir pools; embebido es el camino rápido por-proceso.\n */\n\n// Solo afecta al backend koffi (sus llamadas async usan el threadpool de\n// libuv). El addon napi no pasa por ahí.\nif (!process.env.UV_THREADPOOL_SIZE) {\n process.env.UV_THREADPOOL_SIZE = '16';\n}\n\n/** Contrato interno: cada backend resuelve a ResponseEngine.\n * dml/params viajan como valores JS: el backend napi los pasa nativos\n * (cero JSON); el backend koffi los serializa una vez. */\ninterface EngineBackend {\n /** Devuelve el handle de conexión; lanza si falla. */\n connect(cfgJson: string): Promise<number>;\n execute(handle: number, dml: object, txId: string | null): Promise<ResponseEngine>;\n /** Transacción atómica de N escrituras en UNA llamada (begin/commit internos). */\n executeBatch(handle: number, ops: object[]): Promise<ResponseEngine>;\n raw(handle: number, query: string, params: unknown[], txId: string | null): Promise<ResponseEngine>;\n begin(handle: number): Promise<ResponseEngine>;\n commit(handle: number, txId: string): Promise<ResponseEngine>;\n rollback(handle: number, txId: string): Promise<ResponseEngine>;\n disconnect(handle: number): Promise<void>;\n}\n\nlet backend: EngineBackend | null = null;\nlet loadFailed = false;\n\nconst handles = new Map<string, number>();\nconst connecting = new Map<string, Promise<number>>();\n\nfunction platTag(): { plat: string; ext: string; arch: string } {\n const arch = process.arch === 'arm64' ? 'arm64' : 'x64';\n if (process.platform === 'win32') return { plat: 'windows', ext: 'dll', arch };\n if (process.platform === 'darwin') return { plat: 'macos', ext: 'dylib', arch };\n return { plat: 'linux', ext: 'so', arch };\n}\n\nfunction findFile(name: string): string | null {\n const candidates = [\n path.resolve(process.cwd(), '.dbcube', 'bin', name),\n path.resolve(process.cwd(), 'node_modules', '.dbcube', 'bin', name),\n ];\n for (const c of candidates) {\n if (fs.existsSync(c)) return c;\n }\n return null;\n}\n\nfunction ok(data: unknown): ResponseEngine {\n return { status: 200, message: 'OK', data: data as any };\n}\n\nfunction errResp(e: unknown): ResponseEngine {\n const msg = e instanceof Error ? e.message : String(e);\n return { status: 500, message: msg, data: null };\n}\n\n// ── Backend 1: addon napi ────────────────────────────────────────────────\n\nfunction loadNapiBackend(): EngineBackend | null {\n const { plat, arch } = platTag();\n const addonPath = findFile(`query-engine-node-${plat}-${arch}.node`);\n if (!addonPath) return null;\n\n try {\n // eslint-disable-next-line @typescript-eslint/no-var-requires\n const addon = require(addonPath);\n if (typeof addon.connect !== 'function') return null;\n\n return {\n async connect(cfgJson) {\n return Number(await addon.connect(cfgJson));\n },\n async execute(handle, dml, txId) {\n try {\n // dml y filas cruzan como objetos nativos: cero JSON\n const rows = await addon.execute(handle, dml, txId ?? undefined);\n return ok(rows);\n } catch (e) { return errResp(e); }\n },\n async executeBatch(handle, ops) {\n try {\n const results = await addon.executeBatch(handle, ops);\n return ok(results);\n } catch (e) { return errResp(e); }\n },\n async raw(handle, query, params, txId) {\n try {\n const rows = await addon.raw(handle, query, params, txId ?? undefined);\n return ok(rows);\n } catch (e) { return errResp(e); }\n },\n async begin(handle) {\n try {\n const txId = await addon.begin(handle);\n return ok({ tx_id: txId });\n } catch (e) { return errResp(e); }\n },\n async commit(_handle, txId) {\n try {\n await addon.commit(txId);\n return ok(null);\n } catch (e) { return errResp(e); }\n },\n async rollback(_handle, txId) {\n try {\n await addon.rollback(txId);\n return ok(null);\n } catch (e) { return errResp(e); }\n },\n async disconnect(handle) {\n try { addon.disconnect(handle); } catch { /* proceso terminando */ }\n },\n };\n } catch {\n return null;\n }\n}\n\n// ── Backend 2: koffi sobre la interfaz C ─────────────────────────────────\n\nfunction loadKoffiBackend(): EngineBackend | null {\n const { plat, ext, arch } = platTag();\n const libPath = findFile(`query-engine-embedded-${plat}-${arch}.${ext}`);\n if (!libPath) return null;\n\n try {\n // eslint-disable-next-line @typescript-eslint/no-var-requires\n const koffi = require('koffi');\n const lib = koffi.load(libPath);\n\n const cConnect = lib.func('dbc_connect', 'void *', ['str']);\n const cExecute = lib.func('dbc_execute', 'void *', ['uint64', 'str', 'str']);\n const cExecuteBatch = lib.func('dbc_execute_batch', 'void *', ['uint64', 'str']);\n const cRaw = lib.func('dbc_raw', 'void *', ['uint64', 'str', 'str', 'str']);\n const cBegin = lib.func('dbc_begin', 'void *', ['uint64']);\n const cCommit = lib.func('dbc_commit', 'void *', ['uint64', 'str']);\n const cRollback = lib.func('dbc_rollback', 'void *', ['uint64', 'str']);\n const cDisconnect = lib.func('dbc_disconnect', 'void *', ['uint64']);\n const cFree = lib.func('dbc_free', 'void', ['void *']);\n\n const take = (ptr: unknown): ResponseEngine => {\n if (!ptr) return { status: 500, message: 'embedded engine returned null', data: null };\n const s: string = koffi.decode(ptr, 'char', -1);\n cFree(ptr);\n try {\n const r = JSON.parse(s);\n return { status: r.status ?? 500, message: r.message ?? '', data: r.data ?? null };\n } catch (e: any) {\n return { status: 500, message: `Invalid embedded response: ${e.message}`, data: null };\n }\n };\n\n const call = (fn: any, ...args: unknown[]): Promise<ResponseEngine> =>\n new Promise((resolve, reject) => {\n fn.async(...args, (err: Error | null, ptr: unknown) => {\n if (err) return reject(err);\n resolve(take(ptr));\n });\n });\n\n return {\n async connect(cfgJson) {\n const res = await call(cConnect, cfgJson);\n if (res.status !== 200 || !res.data?.handle) {\n throw new Error(String(res.message || 'embedded connect failed'));\n }\n return Number(res.data.handle);\n },\n execute: (handle, dml, txId) => call(cExecute, handle, JSON.stringify(dml), txId),\n executeBatch: (handle, ops) => call(cExecuteBatch, handle, JSON.stringify(ops)),\n raw: (handle, query, params, txId) => call(cRaw, handle, query, JSON.stringify(params ?? []), txId),\n begin: (handle) => call(cBegin, handle),\n commit: (handle, txId) => call(cCommit, handle, txId),\n rollback: (handle, txId) => call(cRollback, handle, txId),\n async disconnect(handle) {\n try { await call(cDisconnect, handle); } catch { /* proceso terminando */ }\n },\n };\n } catch {\n return null;\n }\n}\n\nfunction loadBackend(): EngineBackend | null {\n if (backend) return backend;\n if (loadFailed) return null;\n if (process.env.DBCUBE_EMBEDDED === '0' || process.env.DBCUBE_EMBEDDED === 'false') {\n loadFailed = true;\n return null;\n }\n backend = loadNapiBackend() ?? loadKoffiBackend();\n if (!backend) loadFailed = true;\n return backend;\n}\n\n// ── API pública (igual que antes) ────────────────────────────────────────\n\nexport class EmbeddedEngine {\n /** true si algún backend nativo está disponible en esta instalación. */\n static available(): boolean {\n return loadBackend() !== null;\n }\n\n private static async handleFor(connectionId: string, config: any): Promise<number> {\n const existing = handles.get(connectionId);\n if (existing) return existing;\n\n const inFlight = connecting.get(connectionId);\n if (inFlight) return inFlight;\n\n const promise = (async () => {\n const be = loadBackend();\n if (!be) throw new Error('embedded engine not available');\n\n const motor = config.type === 'postgres' ? 'postgresql' : config.type;\n const cfg: Record<string, unknown> = {\n databaseRef: connectionId,\n motor,\n database: config.type === 'sqlite' ? `${config.config.DATABASE}.db` : config.config.DATABASE,\n host: config.config.HOST,\n port: config.config.PORT != null ? Number(config.config.PORT) : undefined,\n user: config.config.USER,\n password: config.config.PASSWORD,\n maxConnections: config.pool?.maxConnections,\n minConnections: config.pool?.minConnections,\n acquireTimeoutMs: config.pool?.acquireTimeoutMs,\n idleTimeoutMs: config.pool?.idleTimeoutMs,\n };\n const handle = await be.connect(JSON.stringify(cfg));\n handles.set(connectionId, handle);\n return handle;\n })();\n\n connecting.set(connectionId, promise);\n try {\n return await promise;\n } finally {\n connecting.delete(connectionId);\n }\n }\n\n static async executeDml(connectionId: string, config: any, dml: object, txId?: string): Promise<ResponseEngine> {\n const be = loadBackend()!;\n const handle = await this.handleFor(connectionId, config);\n return be.execute(handle, dml, txId ?? null);\n }\n\n static async executeBatch(connectionId: string, config: any, ops: object[]): Promise<ResponseEngine> {\n const be = loadBackend()!;\n const handle = await this.handleFor(connectionId, config);\n return be.executeBatch(handle, ops);\n }\n\n static async rawQuery(connectionId: string, config: any, query: string, params: any[], txId?: string): Promise<ResponseEngine> {\n const be = loadBackend()!;\n const handle = await this.handleFor(connectionId, config);\n return be.raw(handle, query, params ?? [], txId ?? null);\n }\n\n static async begin(connectionId: string, config: any): Promise<ResponseEngine> {\n const be = loadBackend()!;\n const handle = await this.handleFor(connectionId, config);\n return be.begin(handle);\n }\n\n static async commit(connectionId: string, config: any, txId: string): Promise<ResponseEngine> {\n const be = loadBackend()!;\n const handle = await this.handleFor(connectionId, config);\n return be.commit(handle, txId);\n }\n\n static async rollback(connectionId: string, config: any, txId: string): Promise<ResponseEngine> {\n const be = loadBackend()!;\n const handle = await this.handleFor(connectionId, config);\n return be.rollback(handle, txId);\n }\n\n static async disconnect(connectionId: string): Promise<void> {\n const be = loadBackend();\n const handle = handles.get(connectionId);\n if (be && handle) {\n handles.delete(connectionId);\n await be.disconnect(handle);\n }\n }\n}\n\nexport default EmbeddedEngine;\n","import { QueryEngine } from './QueryEngine';\r\nimport * as path from 'path';\r\nimport fs from 'fs';\r\n\r\nconst rootPath = path.resolve(process.cwd(), '.dbcube');\r\n\r\ninterface DatabaseConfig {\r\n name?: string;\r\n HOST?: string;\r\n USER?: string;\r\n PASSWORD?: string;\r\n DATABASE?: string;\r\n PORT?: number;\r\n}\r\n\r\ninterface QueryResult {\r\n status: 'success' | 'error';\r\n message: string;\r\n data: any | null;\r\n}\r\n\r\ninterface ParametrizedQueryResult {\r\n query: string;\r\n parameters: any[];\r\n}\r\n\r\n// La base interna de DBCube (computed fields, triggers y schemas registrados)\r\n// es un SQLite en `.dbcube/<database>.db`. Antes la leía un binario aparte\r\n// (sqlite-engine, un proceso por query); ahora va por el MISMO query-engine que\r\n// el resto de consultas SQLite — in-process vía el addon embebido (o el daemon\r\n// como fallback). Un binario menos que compilar/versionar/descargar.\r\nclass SQLite {\r\n private database: string;\r\n private engine: QueryEngine | null = null;\r\n\r\n constructor(config: DatabaseConfig) {\r\n this.database = config.DATABASE || 'config';\r\n }\r\n\r\n /** Ruta del archivo SQLite interno (.dbcube/<database>.db). */\r\n private dbFilePath(): string {\r\n return path.join(rootPath, this.database + '.db');\r\n }\r\n\r\n /** QueryEngine sqlite apuntando al archivo interno, con config explícito\r\n * (no vive en dbcube.config.js). La ruta relativa `.dbcube/<db>` deja que\r\n * QueryEngine le añada `.db` → `.dbcube/<db>.db`, relativo al CWD. */\r\n private getEngine(): QueryEngine {\r\n if (!this.engine) {\r\n const relativeDb = path.join('.dbcube', this.database).replace(/\\\\/g, '/');\r\n this.engine = new QueryEngine(`dbcube-internal-${this.database}`, 30000, {\r\n type: 'sqlite',\r\n config: { DATABASE: relativeDb },\r\n });\r\n }\r\n return this.engine;\r\n }\r\n\r\n async ifExist(): Promise<Boolean> {\r\n // Crear .dbcube si no existe (no crea el .db: eso lo hace schema-engine)\r\n if (!fs.existsSync(rootPath)) {\r\n fs.mkdirSync(rootPath, { recursive: true });\r\n }\r\n return fs.existsSync(this.dbFilePath());\r\n }\r\n\r\n async connect(): Promise<QueryEngine> {\r\n if (!fs.existsSync(rootPath)) {\r\n fs.mkdirSync(rootPath, { recursive: true });\r\n }\r\n return this.getEngine();\r\n }\r\n\r\n async disconnect(): Promise<void> {\r\n // Mantenemos el handle caliente entre llamadas (no hay proceso que matar).\r\n // El engine embebido reutiliza la conexión por connectionId.\r\n }\r\n\r\n async query(sqlQuery: string): Promise<QueryResult> {\r\n return this.queryWithParameters(sqlQuery, []);\r\n }\r\n\r\n async queryWithParameters(sqlQuery: string, params: any[] = []): Promise<QueryResult> {\r\n try {\r\n if (typeof sqlQuery !== 'string') {\r\n throw new Error('The SQL query must be a string.');\r\n }\r\n if (!Array.isArray(params)) {\r\n throw new Error('Parameters must be an array.');\r\n }\r\n\r\n const response = await this.getEngine().rawQuery(sqlQuery, params);\r\n\r\n if (response.status !== 200) {\r\n return { status: 'error', message: response.message || 'Query failed', data: null };\r\n }\r\n return { status: 'success', message: 'Query executed successfully', data: response.data };\r\n } catch (error) {\r\n return {\r\n status: 'error',\r\n message: (error as Error).message || 'An error occurred while executing the query.',\r\n data: null,\r\n };\r\n }\r\n }\r\n\r\n convertToParameterizedQuery(sql: string): ParametrizedQueryResult {\r\n const normalizedSql = sql.replace(/\\s+/g, ' ').trim();\r\n \r\n const baseQueryMatch = normalizedSql.match(/^(.+?)\\s+VALUES\\s*\\(/i);\r\n if (!baseQueryMatch) {\r\n throw new Error('No se pudo encontrar la estructura VALUES en la consulta');\r\n }\r\n \r\n const baseQuery = baseQueryMatch[1];\r\n \r\n const valuesStartIndex = normalizedSql.toUpperCase().indexOf('VALUES');\r\n const valuesSection = normalizedSql.substring(valuesStartIndex);\r\n const valuesMatch = valuesSection.match(/VALUES\\s*\\((.+)\\)\\s*;?\\s*$/i);\r\n if (!valuesMatch) {\r\n throw new Error('No se pudieron extraer los valores de la consulta');\r\n }\r\n \r\n const valuesString = valuesMatch[1];\r\n \r\n function parseValues(str: string): any[] {\r\n const values: any[] = [];\r\n let currentValue = '';\r\n let inQuotes = false;\r\n let quoteChar = '';\r\n let inCompute = false;\r\n let computeDepth = 0;\r\n \r\n for (let i = 0; i < str.length; i++) {\r\n const char = str[i];\r\n const prevChar = str[i - 1];\r\n \r\n if (!inQuotes && str.substring(i, i + 8) === '@compute') {\r\n inCompute = true;\r\n }\r\n \r\n if (inCompute && char === '(') {\r\n computeDepth++;\r\n } else if (inCompute && char === ')') {\r\n computeDepth--;\r\n if (computeDepth === 0) {\r\n inCompute = false;\r\n }\r\n }\r\n \r\n if (!inCompute && (char === '\"' || char === \"'\") && prevChar !== '\\\\') {\r\n if (!inQuotes) {\r\n inQuotes = true;\r\n quoteChar = char;\r\n } else if (char === quoteChar) {\r\n if (str[i + 1] === quoteChar) {\r\n currentValue += char + char;\r\n i++;\r\n continue;\r\n } else {\r\n inQuotes = false;\r\n quoteChar = '';\r\n }\r\n }\r\n }\r\n \r\n if (!inQuotes && !inCompute && char === ',') {\r\n values.push(cleanValue(currentValue.trim()));\r\n currentValue = '';\r\n continue;\r\n }\r\n \r\n currentValue += char;\r\n }\r\n \r\n if (currentValue.trim()) {\r\n values.push(cleanValue(currentValue.trim()));\r\n }\r\n \r\n return values;\r\n }\r\n \r\n function cleanValue(value: string): any {\r\n value = value.trim();\r\n \r\n if (value.startsWith('@compute')) {\r\n return value;\r\n }\r\n \r\n if ((value.startsWith('\"') && value.endsWith('\"')) || \r\n (value.startsWith(\"'\") && value.endsWith(\"'\"))) {\r\n value = value.slice(1, -1);\r\n value = value.replace(/''/g, \"'\").replace(/\"\"/g, '\"');\r\n }\r\n \r\n return value;\r\n }\r\n \r\n const parameters = parseValues(valuesString);\r\n const placeholders = parameters.map(() => '?').join(', ');\r\n const parametrizedQuery = `${baseQuery} VALUES (${placeholders});`;\r\n \r\n return {\r\n query: parametrizedQuery,\r\n parameters: parameters\r\n };\r\n }\r\n}\r\n\r\nexport const DbConfig = new SQLite({DATABASE: \"config\"});\r\nexport default DbConfig;","import * as fs from 'fs';\r\nimport * as path from 'path';\r\nimport { EventEmitter } from 'events';\r\n\r\ninterface InterceptOptions {\r\n interceptLog?: boolean;\r\n interceptError?: boolean;\r\n interceptWarn?: boolean;\r\n keepOriginal?: boolean;\r\n useBuffer?: boolean;\r\n}\r\n\r\ninterface ReadOptions {\r\n lines?: number | null;\r\n fromEnd?: boolean;\r\n asArray?: boolean;\r\n}\r\n\r\ninterface WatchOptions {\r\n persistent?: boolean;\r\n interval?: number;\r\n fromEnd?: boolean;\r\n}\r\n\r\ninterface WatchController {\r\n id: string;\r\n stop: () => void;\r\n isWatching: () => boolean;\r\n}\r\n\r\nexport interface InterceptController {\r\n restore: () => void;\r\n commit: () => Promise<boolean>;\r\n discard: () => number;\r\n hasBuffer: () => boolean;\r\n getBufferSize: () => number;\r\n}\r\n\r\ninterface DeleteResult {\r\n filePath: string;\r\n deleted: boolean;\r\n error: string | null;\r\n}\r\n\r\ntype LogLevel = 'INFO' | 'ERROR' | 'WARN' | 'DEBUG';\r\n\r\nexport class FileLogger extends EventEmitter {\r\n private static watchers = new Map<string, (curr: fs.Stats, prev: fs.Stats) => void>(); // Store listener functions\r\n private static buffers = new Map<string, string[]>();\r\n \r\n /**\r\n * Escribe un log en el archivo especificado\r\n * @param filePath - Ruta del archivo de log\r\n * @param message - Mensaje a escribir\r\n * @param level - Nivel del log (INFO, ERROR, WARN, DEBUG)\r\n * @param append - Si debe agregar al final del archivo (default: true)\r\n */\r\n static async write(filePath: string, message: string, level: LogLevel = 'INFO', append: boolean = true): Promise<boolean> {\r\n try {\r\n // Asegurar que el directorio existe\r\n const dir = path.dirname(filePath);\r\n if (!fs.existsSync(dir)) {\r\n fs.mkdirSync(dir, { recursive: true });\r\n }\r\n \r\n // Formatear el mensaje con timestamp\r\n const timestamp = new Date().toISOString();\r\n const formattedMessage = `[${timestamp}] [${level}] ${message}\\n`;\r\n \r\n // Si existe un buffer para este archivo, agregarlo al buffer en lugar de escribir directamente\r\n if (FileLogger.buffers.has(filePath)) {\r\n FileLogger.buffers.get(filePath)!.push(formattedMessage);\r\n return true;\r\n }\r\n \r\n // Escribir al archivo normalmente\r\n if (append) {\r\n await fs.promises.appendFile(filePath, formattedMessage, 'utf8');\r\n } else {\r\n await fs.promises.writeFile(filePath, formattedMessage, 'utf8');\r\n }\r\n \r\n return true;\r\n } catch (error) {\r\n console.error('Error escribiendo log:', error);\r\n throw error;\r\n }\r\n }\r\n \r\n /**\r\n * Inicia un buffer temporal para un archivo de log\r\n * @param filePath - Ruta del archivo de log\r\n */\r\n static startBuffer(filePath: string): void {\r\n if (!FileLogger.buffers.has(filePath)) {\r\n FileLogger.buffers.set(filePath, []);\r\n }\r\n }\r\n \r\n /**\r\n * Confirma y escribe todos los logs del buffer al archivo\r\n * @param filePath - Ruta del archivo de log\r\n */\r\n static async commitBuffer(filePath: string): Promise<boolean> {\r\n const buffer = FileLogger.buffers.get(filePath);\r\n if (buffer && buffer.length > 0) {\r\n try {\r\n // Asegurar que el directorio existe\r\n const dir = path.dirname(filePath);\r\n if (!fs.existsSync(dir)) {\r\n fs.mkdirSync(dir, { recursive: true });\r\n }\r\n \r\n // Escribir todos los logs del buffer\r\n const content = buffer.join('');\r\n await fs.promises.appendFile(filePath, content, 'utf8');\r\n \r\n // Limpiar el buffer\r\n FileLogger.buffers.delete(filePath);\r\n return true;\r\n } catch (error) {\r\n console.error('Error confirmando buffer:', error);\r\n throw error;\r\n }\r\n }\r\n \r\n // Limpiar el buffer aunque esté vacío\r\n FileLogger.buffers.delete(filePath);\r\n return false;\r\n }\r\n \r\n /**\r\n * Descarta todos los logs del buffer sin escribirlos\r\n * @param filePath - Ruta del archivo de log\r\n */\r\n static discardBuffer(filePath: string): number {\r\n if (FileLogger.buffers.has(filePath)) {\r\n const discardedCount = FileLogger.buffers.get(filePath)!.length;\r\n FileLogger.buffers.delete(filePath);\r\n return discardedCount;\r\n }\r\n return 0;\r\n }\r\n \r\n /**\r\n * Verifica si existe un buffer activo para un archivo\r\n * @param filePath - Ruta del archivo de log\r\n */\r\n static hasBuffer(filePath: string): boolean {\r\n return FileLogger.buffers.has(filePath);\r\n }\r\n \r\n /**\r\n * Obtiene el número de logs en el buffer\r\n * @param filePath - Ruta del archivo de log\r\n */\r\n static getBufferSize(filePath: string): number {\r\n const buffer = FileLogger.buffers.get(filePath);\r\n return buffer ? buffer.length : 0;\r\n }\r\n \r\n /**\r\n * Intercepta console.log y console.error para escribir a archivo\r\n * @param filePath - Ruta del archivo de log\r\n * @param options - Opciones de interceptación\r\n */\r\n static interceptConsole(filePath: string, options: InterceptOptions = {}): InterceptController {\r\n const {\r\n interceptLog = true,\r\n interceptError = true,\r\n interceptWarn = true,\r\n keepOriginal = true, // Mantener el comportamiento original de console\r\n useBuffer = false // Usar buffer temporal\r\n } = options;\r\n \r\n // Iniciar buffer si se solicita\r\n if (useBuffer) {\r\n FileLogger.startBuffer(filePath);\r\n }\r\n \r\n // Guardar referencias originales\r\n const originalLog = console.log;\r\n const originalError = console.error;\r\n const originalWarn = console.warn;\r\n \r\n if (interceptLog) {\r\n console.log = function(...args: any[]) {\r\n const message = args.map(arg => \r\n typeof arg === 'object' ? JSON.stringify(arg) : String(arg)\r\n ).join(' ');\r\n \r\n FileLogger.write(filePath, message, 'INFO').catch(err => {\r\n originalError('Error escribiendo log:', err);\r\n });\r\n \r\n if (keepOriginal) {\r\n originalLog.apply(console, args);\r\n }\r\n };\r\n }\r\n \r\n if (interceptError) {\r\n console.error = function(...args: any[]) {\r\n const message = args.map(arg => \r\n typeof arg === 'object' ? JSON.stringify(arg) : String(arg)\r\n ).join(' ');\r\n \r\n FileLogger.write(filePath, message, 'ERROR').catch(err => {\r\n originalError('Error escribiendo error log:', err);\r\n });\r\n \r\n if (keepOriginal) {\r\n originalError.apply(console, args);\r\n }\r\n };\r\n }\r\n \r\n if (interceptWarn) {\r\n console.warn = function(...args: any[]) {\r\n const message = args.map(arg => \r\n typeof arg === 'object' ? JSON.stringify(arg) : String(arg)\r\n ).join(' ');\r\n \r\n FileLogger.write(filePath, message, 'WARN').catch(err => {\r\n originalError('Error escribiendo warn log:', err);\r\n });\r\n \r\n if (keepOriginal) {\r\n originalWarn.apply(console, args);\r\n }\r\n };\r\n }\r\n \r\n // Retornar función para restaurar console original\r\n return {\r\n restore: () => {\r\n if (interceptLog) console.log = originalLog;\r\n if (interceptError) console.error = originalError;\r\n if (interceptWarn) console.warn = originalWarn;\r\n },\r\n commit: async () => {\r\n if (useBuffer) {\r\n return await FileLogger.commitBuffer(filePath);\r\n }\r\n return false;\r\n },\r\n discard: () => {\r\n if (useBuffer) {\r\n return FileLogger.discardBuffer(filePath);\r\n }\r\n return 0;\r\n },\r\n hasBuffer: () => FileLogger.hasBuffer(filePath),\r\n getBufferSize: () => FileLogger.getBufferSize(filePath)\r\n };\r\n }\r\n \r\n /**\r\n * Lee el contenido completo del archivo de log\r\n * @param filePath - Ruta del archivo de log\r\n * @param options - Opciones de lectura\r\n * @returns Contenido del archivo\r\n */\r\n static async read(filePath: string, options: ReadOptions = {}): Promise<string | string[]> {\r\n const { \r\n lines = null, // Número de líneas a leer (null = todas)\r\n fromEnd = false, // Si debe leer desde el final\r\n asArray = false // Si debe retornar como array de líneas\r\n } = options;\r\n \r\n try {\r\n if (!fs.existsSync(filePath)) {\r\n return asArray ? [] : '';\r\n }\r\n \r\n let content = await fs.promises.readFile(filePath, 'utf8');\r\n \r\n if (asArray) {\r\n let linesArray = content.split('\\n').filter(line => line.trim() !== '');\r\n \r\n if (lines !== null) {\r\n if (fromEnd) {\r\n linesArray = linesArray.slice(-lines);\r\n } else {\r\n linesArray = linesArray.slice(0, lines);\r\n }\r\n }\r\n \r\n return linesArray;\r\n }\r\n \r\n // Si se especifica número de líneas y no es array\r\n if (lines !== null) {\r\n let linesArray = content.split('\\n').filter(line => line.trim() !== '');\r\n if (fromEnd) {\r\n linesArray = linesArray.slice(-lines);\r\n } else {\r\n linesArray = linesArray.slice(0, lines);\r\n }\r\n content = linesArray.join('\\n');\r\n }\r\n \r\n return content;\r\n } catch (error) {\r\n console.error('Error leyendo log:', error);\r\n throw error;\r\n }\r\n }\r\n \r\n /**\r\n * Observa un archivo de log en tiempo real\r\n * @param filePath - Ruta del archivo de log\r\n * @param callback - Función callback para nuevas líneas\r\n * @param options - Opciones del watcher\r\n * @returns Objeto con métodos para controlar el watcher\r\n */\r\n static watch(filePath: string, callback: (line: string, filePath: string) => void, options: WatchOptions = {}): WatchController {\r\n const {\r\n persistent = true,\r\n interval = 100,\r\n fromEnd = true // Empezar desde el final del archivo\r\n } = options;\r\n \r\n let lastSize = 0;\r\n let lastPosition = 0;\r\n \r\n // Inicializar posición si el archivo ya existe\r\n if (fs.existsSync(filePath)) {\r\n const stats = fs.statSync(filePath);\r\n lastSize = stats.size;\r\n lastPosition = fromEnd ? stats.size : 0;\r\n }\r\n \r\n // Fixed: Correct listener function signature for fs.watchFile\r\n const listener = async (curr: fs.Stats, prev: fs.Stats) => {\r\n try {\r\n if (curr.size > lastSize) {\r\n // El archivo ha crecido\r\n const stream = fs.createReadStream(filePath, {\r\n start: lastPosition,\r\n end: curr.size - 1,\r\n encoding: 'utf8'\r\n });\r\n \r\n let buffer = '';\r\n \r\n stream.on('data', (chunk) => {\r\n buffer += chunk;\r\n const lines = buffer.split('\\n');\r\n \r\n // Procesar líneas completas\r\n for (let i = 0; i < lines.length - 1; i++) {\r\n if (lines[i].trim()) {\r\n callback(lines[i].trim(), filePath);\r\n }\r\n }\r\n \r\n // Guardar la línea incompleta\r\n buffer = lines[lines.length - 1];\r\n });\r\n \r\n stream.on('end', () => {\r\n // Procesar la última línea si existe\r\n if (buffer.trim()) {\r\n callback(buffer.trim(), filePath);\r\n }\r\n });\r\n \r\n lastSize = curr.size;\r\n lastPosition = curr.size;\r\n }\r\n } catch (error) {\r\n console.error('Error en watcher:', error);\r\n }\r\n };\r\n \r\n // Watcher para cambios en el archivo\r\n fs.watchFile(filePath, { persistent, interval }, listener);\r\n \r\n // Guardar referencia del watcher\r\n const watcherId = `${filePath}_${Date.now()}`;\r\n // Store listener reference for cleanup\r\n FileLogger.watchers.set(watcherId, listener as any);\r\n \r\n // Retornar objeto de control\r\n return {\r\n id: watcherId,\r\n stop: () => {\r\n const storedListener = FileLogger.watchers.get(watcherId);\r\n if (storedListener) {\r\n fs.unwatchFile(filePath, storedListener);\r\n FileLogger.watchers.delete(watcherId);\r\n }\r\n },\r\n isWatching: () => FileLogger.watchers.has(watcherId)\r\n };\r\n }\r\n \r\n /**\r\n * Detiene todos los watchers activos\r\n */\r\n static stopAllWatchers(): void {\r\n for (const [watcherId] of FileLogger.watchers) {\r\n const filePath = watcherId.split('_')[0];\r\n fs.unwatchFile(filePath);\r\n }\r\n FileLogger.watchers.clear();\r\n }\r\n \r\n /**\r\n * Métodos de conveniencia para diferentes niveles de log\r\n */\r\n static async info(filePath: string, message: string): Promise<boolean> {\r\n return this.write(filePath, message, 'INFO');\r\n }\r\n \r\n static async error(filePath: string, message: string): Promise<boolean> {\r\n return this.write(filePath, message, 'ERROR');\r\n }\r\n \r\n static async warn(filePath: string, message: string): Promise<boolean> {\r\n return this.write(filePath, message, 'WARN');\r\n }\r\n \r\n static async debug(filePath: string, message: string): Promise<boolean> {\r\n return this.write(filePath, message, 'DEBUG');\r\n }\r\n \r\n /**\r\n * Limpia logs antiguos\r\n * @param filePath - Ruta del archivo de log\r\n * @param maxLines - Máximo número de líneas a mantener\r\n */\r\n static async cleanup(filePath: string, maxLines: number = 1000): Promise<number> {\r\n try {\r\n const lines = await this.read(filePath, { asArray: true }) as string[];\r\n \r\n if (lines.length > maxLines) {\r\n const keepLines = lines.slice(-maxLines);\r\n const content = keepLines.join('\\n') + '\\n';\r\n await fs.promises.writeFile(filePath, content, 'utf8');\r\n return lines.length - maxLines; // Líneas eliminadas\r\n }\r\n \r\n return 0;\r\n } catch (error) {\r\n console.error('Error limpiando logs:', error);\r\n throw error;\r\n }\r\n }\r\n \r\n /**\r\n * Elimina un archivo de log\r\n * @param filePath - Ruta del archivo de log a eliminar\r\n */\r\n static async deleteLogFile(filePath: string): Promise<boolean> {\r\n try {\r\n if (fs.existsSync(filePath)) {\r\n await fs.promises.unlink(filePath);\r\n return true;\r\n }\r\n return false;\r\n } catch (error) {\r\n console.error('Error eliminando archivo de log:', error);\r\n throw error;\r\n }\r\n }\r\n \r\n /**\r\n * Elimina múltiples archivos de log\r\n * @param filePaths - Array de rutas de archivos de log a eliminar\r\n */\r\n static async deleteLogFiles(filePaths: string[]): Promise<DeleteResult[]> {\r\n const results: DeleteResult[] = [];\r\n \r\n for (const filePath of filePaths) {\r\n try {\r\n const deleted = await this.deleteLogFile(filePath);\r\n results.push({ filePath, deleted, error: null });\r\n } catch (error) {\r\n results.push({ filePath, deleted: false, error: (error as Error).message });\r\n }\r\n }\r\n \r\n return results;\r\n }\r\n}\r\n\r\nexport default FileLogger;","import { ComputedFieldConfig, DataObject, DataType } from \"../@types/DataObject\";\r\nimport { Column, DatabaseType, TableSchema } from \"../@types/Processor\";\r\nimport DbConfig from \"./DbConfig\";\r\n\r\nexport class ComputedFieldProcessor {\r\n\r\n static async getComputedFields(name: string): Promise<any[]> {\r\n let computedFields = [];\r\n if (await DbConfig.ifExist()) {\r\n await DbConfig.connect()\r\n try {\r\n // Verificar si la tabla computes existe antes de intentar acceder a ella\r\n const tableExistsQuery = `SELECT name FROM sqlite_master WHERE type='table' AND name='dbcube_computes_config'`;\r\n const tableExistsResult = await DbConfig.query(tableExistsQuery);\r\n\r\n if (tableExistsResult.status === 'success' && tableExistsResult.data && tableExistsResult.data.length > 0) {\r\n const queryComputes = await DbConfig.queryWithParameters(`SELECT * FROM dbcube_computes_config WHERE database_ref=?`, [name]);\r\n computedFields = queryComputes.data;\r\n } else {\r\n // La tabla no existe, inicializar como array vacío\r\n computedFields = [];\r\n }\r\n } catch (error) {\r\n console.error('Error fetching computed fields:', error);\r\n computedFields = [];\r\n }\r\n await DbConfig.disconnect()\r\n }\r\n\r\n return computedFields;\r\n }\r\n\r\n /**\r\n * Processes computed field instruction and returns the computed value\r\n * @param instruction - The @compute instruction\r\n * @param rowData - The row data containing column values\r\n * @returns The computed value or null if there's an error\r\n */\r\n static processInstruction(instruction: string, rowData: Record<string, any>): any {\r\n try {\r\n // Remove @compute wrapper and extract the function content\r\n const functionMatch = instruction.match(/@compute\\s*\\(\\s*\\(\\s*\\)\\s*=>\\s*{([\\s\\S]*?)}\\s*\\)/);\r\n\r\n if (!functionMatch) {\r\n throw new Error('Invalid @compute instruction format');\r\n }\r\n\r\n let functionBody: string = functionMatch[1].trim();\r\n\r\n // Clean up the function body - remove trailing semicolon if present\r\n if (functionBody.endsWith(';')) {\r\n functionBody = functionBody.slice(0, -1).trim();\r\n }\r\n\r\n // Replace @column(columnName) with references into the row parameter.\r\n // Values are passed as data (never interpolated as code) so row content\r\n // cannot inject JavaScript into the compute function.\r\n functionBody = functionBody.replace(/@column\\(([^)]+)\\)/g, (_match, columnName: string) => {\r\n const cleanColumnName = columnName.trim().replace(/['\"]/g, '');\r\n return `__row[${JSON.stringify(cleanColumnName)}]`;\r\n });\r\n\r\n // Create and execute the function\r\n const computeFunction = new Function('__row', functionBody);\r\n return computeFunction(rowData);\r\n } catch (error) {\r\n console.error('Error processing computed field:', error);\r\n return null;\r\n }\r\n }\r\n\r\n /**\r\n * Extracts column dependencies from a computed field instruction\r\n * @param instruction - The @compute instruction\r\n * @returns Array of column names that this computed field depends on\r\n */\r\n static extractDependencies(instruction: string): string[] {\r\n const dependencies: string[] = [];\r\n const columnMatches = instruction.match(/@column\\(([^)]+)\\)/g);\r\n\r\n if (columnMatches) {\r\n for (const match of columnMatches) {\r\n const innerMatch = match.match(/@column\\(([^)]+)\\)/);\r\n if (innerMatch) {\r\n const columnName = innerMatch[1].trim().replace(/['\"]/g, '');\r\n if (!dependencies.includes(columnName)) {\r\n dependencies.push(columnName);\r\n }\r\n }\r\n }\r\n }\r\n\r\n return dependencies;\r\n }\r\n\r\n /**\r\n * Adds computed fields to an array of data objects based on configuration array\r\n * @param data - Array of data objects\r\n * @param computedConfigs - Array of computed field configurations\r\n * @returns Array with the new computed fields added\r\n */\r\n static computedFields<T extends DataObject>(\r\n data: T[],\r\n computedConfigs: ComputedFieldConfig[]\r\n ): T[] {\r\n\r\n return data.map((item, index) => {\r\n let processedItem: any = { ...item };\r\n\r\n // Procesar cada configuración de campo computado\r\n computedConfigs.forEach((config) => {\r\n try {\r\n const { column: fieldName, type, instruction } = config;\r\n\r\n // Reemplazar @column(fieldName) por referencias al parámetro de fila.\r\n // Los valores viajan como datos (nunca como código): el contenido de la\r\n // fila no puede inyectar JavaScript en la función de cómputo.\r\n let processedExpression = instruction.replace(\r\n /@column\\(([^)]+)\\)/g,\r\n (match, columnName) => {\r\n const cleanColumnName = columnName.replace(/['\"]/g, '');\r\n return `__row[${JSON.stringify(cleanColumnName)}]`;\r\n }\r\n );\r\n\r\n // Extraer la función dentro de @compute\r\n const computeMatch = processedExpression.match(/@compute\\s*\\(\\s*\\(\\s*\\)\\s*=>\\s*\\{(.*)\\}\\s*\\)/s);\r\n if (!computeMatch) {\r\n throw new Error(`Formato de @compute inválido para campo ${fieldName}`);\r\n }\r\n\r\n const functionBody = computeMatch[1];\r\n\r\n // Crear y ejecutar la función\r\n const computeFunction = new Function('__row', functionBody);\r\n let result = computeFunction(processedItem);\r\n\r\n // Aplicar conversión de tipo\r\n result = convertToType(result, type as DataType);\r\n\r\n // Agregar el nuevo campo al objeto procesado\r\n processedItem[fieldName] = result;\r\n\r\n } catch (error) {\r\n console.error(`Error procesando campo ${config.column} en item ${index}:`, error);\r\n // En caso de error, asignar null al campo\r\n processedItem[config.column] = null;\r\n }\r\n });\r\n\r\n return processedItem;\r\n });\r\n }\r\n}\r\n\r\nexport class TableProcessor {\r\n static async generateAlterQueries(\r\n nowQuery: string,\r\n dbType: DatabaseType,\r\n tableName: string,\r\n database_ref: string,\r\n ): Promise<string[]> {\r\n function parseCreateTableQuery(query: string, dbType: DatabaseType): TableSchema {\r\n // Limpiar y normalizar la query\r\n const cleanQuery = query.trim().replace(/\\s+/g, ' ');\r\n\r\n // Extraer el nombre de la tabla\r\n const tableNameMatch = cleanQuery.match(/CREATE TABLE (?:IF NOT EXISTS )?(\\w+)/i);\r\n if (!tableNameMatch) {\r\n throw new Error('No se pudo extraer el nombre de la tabla');\r\n }\r\n\r\n const tableName = tableNameMatch[1];\r\n\r\n // Extraer las definiciones de columnas\r\n const columnsMatch = cleanQuery.match(/\\((.+)\\)/);\r\n if (!columnsMatch) {\r\n throw new Error('No se pudieron extraer las definiciones de columnas');\r\n }\r\n\r\n const columnsString = columnsMatch[1];\r\n const columnDefinitions = columnsString.split(',').map(def => def.trim());\r\n\r\n const columns: Column[] = [];\r\n\r\n for (const def of columnDefinitions) {\r\n // Skip constraints that aren't column definitions\r\n if (def.toUpperCase().startsWith('PRIMARY KEY') ||\r\n def.toUpperCase().startsWith('FOREIGN KEY') ||\r\n def.toUpperCase().startsWith('CONSTRAINT')) {\r\n continue;\r\n }\r\n\r\n const parts = def.split(/\\s+/);\r\n if (parts.length < 2) continue;\r\n\r\n const columnName = parts[0];\r\n const columnType = parts[1];\r\n\r\n const column: Column = {\r\n name: columnName,\r\n type: columnType,\r\n nullable: !def.toUpperCase().includes('NOT NULL'),\r\n primaryKey: def.toUpperCase().includes('PRIMARY KEY'),\r\n autoIncrement: def.toUpperCase().includes('AUTOINCREMENT') || def.toUpperCase().includes('AUTO_INCREMENT')\r\n };\r\n\r\n columns.push(column);\r\n }\r\n\r\n return { tableName, columns };\r\n }\r\n\r\n function generateMySQLQueries(\r\n nowColumns: Map<string, Column>,\r\n oldColumns: Map<string, Column>,\r\n tableName: string\r\n ): string[] {\r\n const queries: string[] = [];\r\n\r\n // Columnas a eliminar\r\n for (const [columnName] of oldColumns) {\r\n if (!nowColumns.has(columnName)) {\r\n queries.push(`ALTER TABLE ${tableName} DROP COLUMN ${columnName};`);\r\n }\r\n }\r\n\r\n // Columnas a agregar o modificar\r\n for (const [columnName, column] of nowColumns) {\r\n const oldColumn = oldColumns.get(columnName);\r\n\r\n if (!oldColumn) {\r\n // Agregar nueva columna\r\n const columnDef = buildColumnDefinition(column, 'mysql');\r\n queries.push(`ALTER TABLE ${tableName} ADD COLUMN ${columnDef};`);\r\n } else if (!columnsEqual(column, oldColumn)) {\r\n // Modificar columna existente\r\n const columnDef = buildColumnDefinition(column, 'mysql');\r\n queries.push(`ALTER TABLE ${tableName} MODIFY COLUMN ${columnDef};`);\r\n }\r\n }\r\n\r\n return queries;\r\n }\r\n\r\n function generatePostgreSQLQueries(\r\n nowColumns: Map<string, Column>,\r\n oldColumns: Map<string, Column>,\r\n tableName: string\r\n ): string[] {\r\n const queries: string[] = [];\r\n\r\n // Columnas a eliminar\r\n for (const [columnName] of oldColumns) {\r\n if (!nowColumns.has(columnName)) {\r\n queries.push(`ALTER TABLE ${tableName} DROP COLUMN ${columnName};`);\r\n }\r\n }\r\n\r\n // Columnas a agregar o modificar\r\n for (const [columnName, column] of nowColumns) {\r\n const oldColumn = oldColumns.get(columnName);\r\n\r\n if (!oldColumn) {\r\n // Agregar nueva columna\r\n const columnDef = buildColumnDefinition(column, 'postgres');\r\n queries.push(`ALTER TABLE ${tableName} ADD COLUMN ${columnDef};`);\r\n } else if (!columnsEqual(column, oldColumn)) {\r\n // PostgreSQL requiere comandos separados para diferentes modificaciones\r\n if (column.type !== oldColumn.type) {\r\n const pgType = column.type.replace('INTEGER', 'INT').replace('TEXT', 'VARCHAR');\r\n queries.push(`ALTER TABLE ${tableName} ALTER COLUMN ${columnName} TYPE ${pgType};`);\r\n }\r\n\r\n if (column.nullable !== oldColumn.nullable) {\r\n const constraint = column.nullable ? 'DROP NOT NULL' : 'SET NOT NULL';\r\n queries.push(`ALTER TABLE ${tableName} ALTER COLUMN ${columnName} ${constraint};`);\r\n }\r\n }\r\n }\r\n\r\n return queries;\r\n }\r\n\r\n function generateSQLiteQueries(\r\n nowSchema: TableSchema,\r\n oldSchema: TableSchema,\r\n tableName: string\r\n ): string[] {\r\n // SQLite no soporta DROP COLUMN directamente, necesitamos recrear la tabla\r\n const queries: string[] = [];\r\n\r\n // Verificar si hay diferencias\r\n if (schemasEqual(nowSchema, oldSchema)) {\r\n return queries; // No hay cambios\r\n }\r\n\r\n const tempTableName = `${tableName}_temp_${Date.now()}`;\r\n\r\n // 1. Crear tabla temporal con el nuevo esquema\r\n const createTempQuery = buildCreateTableQuery(nowSchema, 'sqlite', tempTableName);\r\n queries.push(createTempQuery);\r\n\r\n // 2. Copiar datos compatibles\r\n const commonColumns = nowSchema.columns\r\n .filter(col => oldSchema.columns.some(oldCol => oldCol.name.toLowerCase() === col.name.toLowerCase()))\r\n .map(col => col.name);\r\n\r\n if (commonColumns.length > 0) {\r\n const columnsList = commonColumns.join(', ');\r\n queries.push(`INSERT INTO ${tempTableName} (${columnsList}) SELECT ${columnsList} FROM ${tableName};`);\r\n }\r\n\r\n // 3. Eliminar tabla original\r\n queries.push(`DROP TABLE ${tableName};`);\r\n\r\n // 4. Renombrar tabla temporal\r\n queries.push(`ALTER TABLE ${tempTableName} RENAME TO ${tableName};`);\r\n\r\n return queries;\r\n }\r\n\r\n function generateMongoDBQueries(\r\n nowColumns: Map<string, Column>,\r\n oldColumns: Map<string, Column>,\r\n collectionName: string\r\n ): string[] {\r\n const queries: string[] = [];\r\n\r\n // Campos a eliminar\r\n const fieldsToRemove: string[] = [];\r\n for (const [fieldName] of oldColumns) {\r\n if (!nowColumns.has(fieldName)) {\r\n fieldsToRemove.push(fieldName);\r\n }\r\n }\r\n\r\n if (fieldsToRemove.length > 0) {\r\n const unsetFields = fieldsToRemove.reduce((acc, field) => {\r\n acc[field] = \"\";\r\n return acc;\r\n }, {} as Record<string, string>);\r\n\r\n queries.push(`db.${collectionName}.updateMany({}, { $unset: ${JSON.stringify(unsetFields)} });`);\r\n }\r\n\r\n // Campos a agregar (con valores por defecto)\r\n const fieldsToAdd: Record<string, any> = {};\r\n for (const [fieldName, column] of nowColumns) {\r\n if (!oldColumns.has(fieldName)) {\r\n // Valor por defecto según el tipo\r\n let defaultValue: any = null;\r\n if (!column.nullable) {\r\n switch (column.type.toUpperCase()) {\r\n case 'INTEGER':\r\n defaultValue = 0;\r\n break;\r\n case 'TEXT':\r\n case 'VARCHAR':\r\n defaultValue = '';\r\n break;\r\n default:\r\n defaultValue = null;\r\n }\r\n }\r\n fieldsToAdd[fieldName] = defaultValue;\r\n }\r\n }\r\n\r\n if (Object.keys(fieldsToAdd).length > 0) {\r\n queries.push(`db.${collectionName}.updateMany({}, { $set: ${JSON.stringify(fieldsToAdd)} });`);\r\n }\r\n\r\n return queries;\r\n }\r\n\r\n function buildColumnDefinition(column: Column, dbType: DatabaseType): string {\r\n let def = `${column.name} ${column.type}`;\r\n\r\n if (column.primaryKey) {\r\n def += ' PRIMARY KEY';\r\n }\r\n\r\n if (column.autoIncrement) {\r\n if (dbType === 'mysql') {\r\n def += ' AUTO_INCREMENT';\r\n } else if (dbType === 'sqlite') {\r\n def += ' AUTOINCREMENT';\r\n } else if (dbType === 'postgres') {\r\n def = def.replace(column.type, 'SERIAL');\r\n }\r\n }\r\n\r\n if (!column.nullable) {\r\n def += ' NOT NULL';\r\n }\r\n\r\n return def;\r\n }\r\n\r\n function buildCreateTableQuery(schema: TableSchema, dbType: DatabaseType, tableName?: string): string {\r\n const name = tableName || schema.tableName;\r\n const columnDefs = schema.columns.map(col => buildColumnDefinition(col, dbType));\r\n return `CREATE TABLE ${name} (${columnDefs.join(', ')});`;\r\n }\r\n\r\n function columnsEqual(col1: Column, col2: Column): boolean {\r\n return col1.name.toLowerCase() === col2.name.toLowerCase() &&\r\n col1.type === col2.type &&\r\n col1.nullable === col2.nullable &&\r\n col1.primaryKey === col2.primaryKey &&\r\n col1.autoIncrement === col2.autoIncrement;\r\n }\r\n\r\n function schemasEqual(schema1: TableSchema, schema2: TableSchema): boolean {\r\n if (schema1.columns.length !== schema2.columns.length) {\r\n return false;\r\n }\r\n\r\n const cols1 = new Map(schema1.columns.map(col => [col.name.toLowerCase(), col]));\r\n const cols2 = new Map(schema2.columns.map(col => [col.name.toLowerCase(), col]));\r\n\r\n for (const [name, col1] of cols1) {\r\n const col2 = cols2.get(name);\r\n if (!col2 || !columnsEqual(col1, col2)) {\r\n return false;\r\n }\r\n }\r\n\r\n return true;\r\n }\r\n\r\n if (await DbConfig.ifExist()) {\r\n await DbConfig.connect()\r\n try {\r\n // Verificar si la tabla de schemas existe antes de intentar acceder a ella\r\n const tableExistsQuery = `SELECT name FROM sqlite_master WHERE type='table' AND name='dbcube_schemas_config'`;\r\n const tableExistsResult = await DbConfig.query(tableExistsQuery);\r\n\r\n if (tableExistsResult.status === 'success' && tableExistsResult.data && tableExistsResult.data.length > 0) {\r\n const queryComputes = await DbConfig.queryWithParameters(`SELECT * FROM dbcube_schemas_config WHERE table_ref=? AND database_ref=?`, [tableName, database_ref]);\r\n const oldQuery = queryComputes.data[0];\r\n\r\n // Sin esquema previo registrado: tabla nueva → devolver el CREATE\r\n // (el engine lo ejecuta como CREATE TABLE IF NOT EXISTS en modo refresh)\r\n if (!oldQuery || !oldQuery.struct) {\r\n await DbConfig.disconnect()\r\n return [nowQuery];\r\n }\r\n\r\n const nowSchema = parseCreateTableQuery(nowQuery, dbType);\r\n const oldSchema = parseCreateTableQuery(oldQuery.struct, dbType);\r\n\r\n // Verificar que el nombre de tabla coincida\r\n if (nowSchema.tableName.toLowerCase() !== tableName.toLowerCase()) {\r\n throw new Error(`El nombre de tabla en la query (${nowSchema.tableName}) no coincide con el parámetro (${tableName})`);\r\n }\r\n\r\n // Crear mapas para facilitar la comparación\r\n const nowColumns = new Map(nowSchema.columns.map(col => [col.name.toLowerCase(), col]));\r\n const oldColumns = new Map(oldSchema.columns.map(col => [col.name.toLowerCase(), col]));\r\n\r\n switch (dbType) {\r\n case 'mysql':\r\n return generateMySQLQueries(nowColumns, oldColumns, tableName);\r\n\r\n case 'postgres':\r\n return generatePostgreSQLQueries(nowColumns, oldColumns, tableName);\r\n\r\n case 'sqlite':\r\n return generateSQLiteQueries(nowSchema, oldSchema, tableName);\r\n\r\n case 'mongodb':\r\n return generateMongoDBQueries(nowColumns, oldColumns, tableName);\r\n\r\n default:\r\n throw new Error(`Tipo de base de datos no soportado: ${dbType}`);\r\n }\r\n }\r\n } catch (error) {\r\n console.error('Error fetching computed fields:', error);\r\n }\r\n await DbConfig.disconnect()\r\n return [nowQuery];\r\n } else {\r\n return [nowQuery];\r\n }\r\n }\r\n\r\n static async saveQuery(table_ref: string, database_ref: string, struct: string): Promise<void> {\r\n\r\n if (await DbConfig.ifExist()) {\r\n await DbConfig.connect()\r\n try {\r\n await DbConfig.queryWithParameters(`DELETE FROM dbcube_schemas_config WHERE table_ref=? AND database_ref=?`, [table_ref, database_ref]);\r\n\r\n // Verificar si la tabla computes existe antes de intentar acceder a ella\r\n const tableExistsQuery = `INSERT INTO dbcube_schemas_config (table_ref, database_ref, struct) VALUES (?, ?, ?)`;\r\n await DbConfig.queryWithParameters(tableExistsQuery, [table_ref, database_ref, struct]);\r\n } catch (error) {\r\n console.error('Error fetching computed fields:', error);\r\n }\r\n await DbConfig.disconnect()\r\n }\r\n }\r\n}\r\n\r\nexport class TriggerProcessor {\r\n\r\n static async getTriggers(name: string): Promise<any[]> {\r\n let triggers = [];\r\n if (await DbConfig.ifExist()) {\r\n await DbConfig.connect()\r\n try {\r\n // Verificar si la tabla computes existe antes de intentar acceder a ella\r\n const tableExistsQuery = `SELECT name FROM sqlite_master WHERE type='table' AND name='dbcube_triggers_config'`;\r\n const tableExistsResult = await DbConfig.query(tableExistsQuery);\r\n\r\n if (tableExistsResult.status === 'success' && tableExistsResult.data && tableExistsResult.data.length > 0) {\r\n const queryComputes = await DbConfig.queryWithParameters(`SELECT * FROM dbcube_triggers_config WHERE database_ref=?`, [name]);\r\n triggers = queryComputes.data;\r\n } else {\r\n // La tabla no existe, inicializar como array vacío\r\n triggers = [];\r\n }\r\n } catch (error) {\r\n console.error('Error fetching computed fields:', error);\r\n triggers = [];\r\n }\r\n await DbConfig.disconnect()\r\n }\r\n\r\n return triggers;\r\n }\r\n}\r\n\r\n// Utils\r\nfunction convertToType(value: any, type: DataType): any {\r\n switch (type) {\r\n case 'string':\r\n return String(value);\r\n case 'number':\r\n const num = Number(value);\r\n return isNaN(num) ? 0 : num;\r\n case 'boolean':\r\n return Boolean(value);\r\n case 'date':\r\n return value instanceof Date ? value : new Date(value);\r\n case 'object':\r\n return value;\r\n default:\r\n return value;\r\n }\r\n}"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACAA,IAAAA,eAAiB;;;ACAjB,SAAoB;AAoBpB,IAAM,eAAN,MAAmB;AAAA,EACP;AAAA,EAER,cAAc;AACV,SAAK,aAAa,KAAK,iBAAiB;AAAA,EAC5C;AAAA;AAAA;AAAA;AAAA,EAKQ,mBAA+B;AACnC,WAAO;AAAA,MACH,UAAa,YAAS;AAAA,MACtB,MAAS,QAAK;AAAA,MACd,SAAY,WAAQ;AAAA,MACpB,MAAS,QAAK;AAAA,MACd,YAAe,cAAW;AAAA,MAC1B,MAAS,QAAK,EAAE;AAAA,IACpB;AAAA,EACJ;AAAA;AAAA;AAAA;AAAA,EAKA,cAAsB;AAClB,UAAMC,YAAW,KAAK,WAAW;AAEjC,YAAQA,WAAU;AAAA,MACd,KAAK;AACD,eAAO;AAAA,MACX,KAAK;AACD,eAAO;AAAA,MACX,KAAK;AACD,eAAO;AAAA,MACX,KAAK;AACD,eAAO;AAAA,MACX,KAAK;AACD,eAAO;AAAA,MACX,KAAK;AACD,eAAO;AAAA,MACX;AACI,eAAOA;AAAA,IACf;AAAA,EACJ;AAAA;AAAA;AAAA;AAAA,EAKA,kBAA0B;AACtB,UAAMC,QAAO,KAAK,WAAW;AAE7B,YAAQA,OAAM;AAAA,MACV,KAAK;AACD,eAAO;AAAA,MACX,KAAK;AAAA,MACL,KAAK;AACD,eAAO;AAAA,MACX,KAAK;AACD,eAAO;AAAA,MACX,KAAK;AACD,eAAO;AAAA,MACX,KAAK;AACD,eAAO;AAAA,MACX,KAAK;AACD,eAAO;AAAA,MACX,KAAK;AACD,eAAO;AAAA,MACX,KAAK;AACD,eAAO;AAAA,MACX,KAAK;AACD,eAAO;AAAA,MACX;AACI,eAAOA;AAAA,IACf;AAAA,EACJ;AAAA;AAAA;AAAA;AAAA,EAKA,cAAc,UAA0B;AACpC,UAAMD,YAAW,KAAK,YAAY;AAClC,UAAMC,QAAO,KAAK,gBAAgB;AAClC,UAAM,YAAYD,cAAa,YAAY,SAAS;AAEpD,WAAO,GAAG,QAAQ,IAAIA,SAAQ,IAAIC,KAAI,GAAG,SAAS;AAAA,EACtD;AAAA;AAAA;AAAA;AAAA,EAKA,gBAA4B;AACxB,WAAO,EAAE,GAAG,KAAK,WAAW;AAAA,EAChC;AAAA;AAAA;AAAA;AAAA,EAKA,sBAA8B;AAC1B,UAAMD,YAAW,KAAK,YAAY;AAClC,UAAMC,QAAO,KAAK,gBAAgB;AAGlC,UAAM,YAAuC;AAAA,MACzC,gBAAgB;AAAA,MAChB,cAAc;AAAA,MACd,iBAAiB;AAAA,MACjB,eAAe;AAAA,MACf,gBAAgB;AAAA,MAChB,iBAAiB;AAAA,MACjB,kBAAkB;AAAA,MAClB,gBAAgB;AAAA,MAChB,mBAAmB;AAAA,MACnB,kBAAkB;AAAA,IACtB;AAEA,UAAM,MAAM,GAAGD,SAAQ,IAAIC,KAAI;AAC/B,WAAO,UAAU,GAAG,KAAK,GAAGA,KAAI,YAAYD,SAAQ;AAAA,EACxD;AAAA;AAAA;AAAA;AAAA,EAKA,kBAAwB;AACpB,YAAQ,IAAI,sCAA0B;AACtC,YAAQ,IAAI,0BAAgB,KAAK,YAAY,CAAC;AAC9C,YAAQ,IAAI,8BAAoB,KAAK,gBAAgB,CAAC;AACtD,YAAQ,IAAI,yBAAe,KAAK,WAAW,IAAI;AAC/C,YAAQ,IAAI,4BAAkB,KAAK,WAAW,OAAO;AACrD,YAAQ,IAAI,4BAAkB,KAAK,WAAW,UAAU;AACxD,YAAQ,IAAI,sBAAY,KAAK,WAAW,IAAI;AAC5C,YAAQ,IAAI,6BAAmB,KAAK,oBAAoB,CAAC;AAAA,EAC7D;AACJ;;;ACtJA,SAAoB;AACpB,WAAsB;AACtB,IAAAE,MAAoB;AACpB,8BAA4B;AAE5B,eAA0B;AAE1B,iBAAgB;AAChB,mBAAkB;AAClB,iBAA8B;AAC9B,kBAAwB;AAZxB;AAMA,IAAM,EAAE,MAAM,IAAI,wBAAAC;AAsBlB,IAAM,aAAN,MAAiB;AAAA,EACb,OAAe,cAAmB;AAAA,EAClC,OAAe,iBAAsB;AAAA,EACrC,OAAwB,eAAe;AAAA,IACnC,OAAO;AAAA,IACP,QAAQ;AAAA,EACZ;AAAA;AAAA;AAAA;AAAA,EAKA,aAAqB,mBAAmB,QAA6C;AACjF,UAAM,MAAM,KAAK,aAAa,MAAM;AAEpC,WAAO,IAAI,QAAQ,CAACC,UAAS,WAAW;AACpC,YAAM,IAAI,KAAK,CAAC,aAA8B;AAC1C,YAAI,OAAO;AAEX,iBAAS,GAAG,QAAQ,CAAC,UAAU;AAC3B,kBAAQ;AAAA,QACZ,CAAC;AAED,iBAAS,GAAG,OAAO,MAAM;AACrB,cAAI;AACA,kBAAM,WAA4B,KAAK,MAAM,IAAI;AACjD,gBAAI,YAAY,SAAS,SAAS,GAAG;AAEjC,cAAAA,SAAQ,SAAS,CAAC,EAAE,OAAO;AAAA,YAC/B,OAAO;AACH,qBAAO,IAAI,MAAM,mBAAmB,CAAC;AAAA,YACzC;AAAA,UACJ,SAAS,OAAO;AACZ,mBAAO,KAAK;AAAA,UAChB;AAAA,QACJ,CAAC;AAED,iBAAS,GAAG,SAAS,MAAM;AAAA,MAC/B,CAAC,EAAE,GAAG,SAAS,MAAM;AAAA,IACzB,CAAC;AAAA,EACL;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,OAAe,2BAA2B,UAAiC;AACvE,UAAM,QAAQ,SAAS,MAAM,oBAAoB;AACjD,WAAO,QAAQ,MAAM,CAAC,IAAI;AAAA,EAC9B;AAAA;AAAA;AAAA;AAAA,EAKA,OAAe,gBAAgB,QAAgB,QAA+B;AAC1E,QAAI;AACA,YAAM,QAAW,eAAY,MAAM;AACnC,YAAM,gBAAgB,IAAI,OAAO,IAAI,MAAM,WAAW;AACtD,YAAM,aAAa,MAAM,KAAK,OAAK,cAAc,KAAK,CAAC,CAAC;AAExD,UAAI,YAAY;AACZ,eAAO,KAAK,2BAA2B,UAAU;AAAA,MACrD;AAAA,IACJ,SAAS,OAAO;AAAA,IAEhB;AACA,WAAO;AAAA,EACX;AAAA;AAAA;AAAA;AAAA,EAKA,OAAe,eAAe,cAA6B,eAAgC;AACvF,QAAI,CAAC,aAAc,QAAO;AAG1B,UAAM,aAAa,aAAa,QAAQ,MAAM,EAAE;AAChD,UAAM,cAAc,cAAc,QAAQ,MAAM,EAAE;AAElD,UAAM,aAAa,WAAW,MAAM,GAAG,EAAE,IAAI,MAAM;AACnD,UAAM,cAAc,YAAY,MAAM,GAAG,EAAE,IAAI,MAAM;AAErD,aAAS,IAAI,GAAG,IAAI,GAAG,KAAK;AACxB,UAAI,YAAY,CAAC,IAAI,WAAW,CAAC,EAAG,QAAO;AAC3C,UAAI,YAAY,CAAC,IAAI,WAAW,CAAC,EAAG,QAAO;AAAA,IAC/C;AAEA,WAAO;AAAA,EACX;AAAA;AAAA;AAAA;AAAA,EAKA,OAAe,gBAAgB,QAAgB,QAAsB;AACjE,QAAI;AACA,YAAM,QAAW,eAAY,MAAM;AACnC,YAAM,gBAAgB,IAAI,OAAO,IAAI,MAAM,UAAU;AAErD,YAAM,QAAQ,UAAQ;AAClB,YAAI,cAAc,KAAK,IAAI,GAAG;AAC1B,gBAAM,WAAgB,UAAK,QAAQ,IAAI;AACvC,cAAI;AACA,YAAG,cAAW,QAAQ;AACtB,oBAAQ,IAAI,wCAA4B,IAAI,EAAE;AAAA,UAClD,SAAS,KAAK;AACV,oBAAQ,KAAK,mCAAyB,IAAI,EAAE;AAAA,UAChD;AAAA,QACJ;AAAA,MACJ,CAAC;AAAA,IACL,SAAS,OAAO;AAAA,IAEhB;AAAA,EACJ;AAAA,EAEA,OAAO,IAAI,QAA6E;AACpF,UAAMC,QAAO,IAAI,aAAa;AAC9B,UAAMC,YAAWD,MAAK,YAAY;AAClC,UAAM,eAAeA,MAAK,gBAAgB;AAE1C,UAAM,cAAsC;AAAA,MACxC,SAAS;AAAA,MACT,OAAO;AAAA,MACP,QAAQ;AAAA,IACZ;AAEA,UAAM,UAAkC;AAAA,MACpC,QAAQ;AAAA,MACR,SAAS;AAAA,IACb;AAEA,UAAM,OAAO,YAAYC,SAAQ;AACjC,UAAM,aAAa,QAAQ,YAAY;AAEvC,QAAI,QAAQ,YAAY;AAGpB,YAAM,WAAW,GAAG,MAAM,WAAW,IAAI,IAAI,UAAU;AACvD,YAAM,aAAaA,cAAa,YAAY,GAAG,QAAQ,SAAS;AAEhE,YAAM,MAAM,wDAAwD,MAAM,WAAW,MAAM,kBAAkB,IAAI,IAAI,UAAU;AAC/H,aAAO;AAAA,QACH,MAAM;AAAA,QACN;AAAA,QACA,SAAS;AAAA,QACT,cAAc;AAAA,QACd,eAAe,GAAG,MAAM,WAAW,IAAI,IAAI,UAAU,GAAGA,cAAa,YAAY,SAAS,EAAE;AAAA,MAChG;AAAA,IACJ;AAEA,WAAO;AAAA,MACH,MAAM;AAAA,MACN,KAAK;AAAA,MACL,SAAS;AAAA,MACT,cAAc;AAAA,MACd,eAAe;AAAA,IACnB;AAAA,EACJ;AAAA;AAAA;AAAA;AAAA,EAKA,aAAa,eAAe,QAAkG;AAC1H,UAAMD,QAAO,IAAI,aAAa;AAC9B,UAAMC,YAAWD,MAAK,YAAY;AAClC,UAAM,eAAeA,MAAK,gBAAgB;AAE1C,UAAM,cAAsC;AAAA,MACxC,SAAS;AAAA,MACT,OAAO;AAAA,MACP,QAAQ;AAAA,IACZ;AAEA,UAAM,UAAkC;AAAA,MACpC,QAAQ;AAAA,MACR,SAAS;AAAA,IACb;AAEA,UAAM,OAAO,YAAYC,SAAQ;AACjC,UAAM,aAAa,QAAQ,YAAY;AAEvC,QAAI,QAAQ,YAAY;AAEpB,YAAM,UAAU,MAAM,KAAK,mBAAmB,MAAM;AAEpD,YAAM,WAAW,GAAG,MAAM,WAAW,OAAO,IAAI,IAAI,IAAI,UAAU;AAClE,YAAM,aAAaA,cAAa,YAAY,GAAG,QAAQ,SAAS;AAEhE,YAAM,MAAM,wDAAwD,MAAM,WAAW,MAAM,WAAW,OAAO,IAAI,IAAI,IAAI,UAAU;AACnI,aAAO;AAAA,QACH,MAAM;AAAA,QACN;AAAA,QACA;AAAA,QACA,cAAc;AAAA,QACd,eAAe;AAAA,MACnB;AAAA,IACJ;AAEA,WAAO;AAAA,MACH,MAAM;AAAA,MACN,KAAK;AAAA,MACL,SAAS;AAAA,MACT,cAAc;AAAA,MACd,eAAe;AAAA,IACnB;AAAA,EACJ;AAAA,EAEA,aAAa,SAAS,WAAmC;AACrD,UAAM,SAAS,aAAa,KAAK,iBAAiB;AAClD,IAAG,aAAU,QAAQ,EAAE,WAAW,KAAK,CAAC;AAGxC,SAAK,kBAAc,WAAAC,SAAI;AAAA,MACnB,MAAM,aAAAC,QAAM,KAAK,sCAAsC;AAAA,MACvD,SAAS;AAAA,IACb,CAAC,EAAE,MAAM;AAET,UAAM,oBAAqI,CAAC;AAI5I,eAAW,UAAU,CAAC,SAAS,QAAQ,GAAY;AAC/C,UAAI;AACA,cAAM,eAAe,KAAK,gBAAgB,QAAQ,MAAM;AACxD,cAAM,gBAAgB,MAAM,KAAK,mBAAmB,MAAM;AAC1D,cAAM,cAAc,KAAK,eAAe,cAAc,aAAa;AAEnE,0BAAkB,KAAK;AAAA,UACnB;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,QACJ,CAAC;AAED,YAAI,aAAa;AACb,kBAAQ,IAAI;AAAA,YAAQ,MAAM,YAAY,gBAAgB,eAAe,WAAM,aAAa,EAAE;AAAA,QAC9F,WAAW,cAAc;AACrB,kBAAQ,IAAI;AAAA,SAAO,MAAM,YAAY,YAAY,eAAe;AAAA,QACpE;AAAA,MACJ,SAAS,OAAO;AACZ,gBAAQ,KAAK,6CAAmC,MAAM,gCAAgC;AACtF,0BAAkB,KAAK;AAAA,UACnB;AAAA,UACA,aAAa;AAAA,UACb,cAAc;AAAA,UACd,eAAe;AAAA,QACnB,CAAC;AAAA,MACL;AAAA,IACJ;AAEA,UAAM,qBAAqB,kBAAkB,OAAO,OAAK,EAAE,WAAW;AAEtE,QAAI,mBAAmB,WAAW,GAAG;AACjC,WAAK,YAAY,QAAQ,aAAAA,QAAM,MAAM,6BAA6B,CAAC;AACnE;AAAA,IACJ;AAGA,SAAK,YAAY,OAAO,aAAAA,QAAM,KAAK,YAAY,mBAAmB,MAAM,iBAAiB;AAEzF,QAAI;AAIA,YAAM,UAAU,MAAM,QAAQ,WAAW,mBAAmB,IAAI,OAAO,WAAW;AAC9E,cAAM,aAAa;AACnB,YAAI,UAAU;AAEd,eAAO,WAAW,YAAY;AAC1B,cAAI;AAEA,kBAAM,aAAa,MAAM,KAAK,eAAe,OAAO,MAAM;AAE1D,gBAAI,CAAC,WAAW,QAAQ,CAAC,WAAW,KAAK;AACrC,oBAAM,IAAI,MAAM,8CAA8C,OAAO,MAAM,EAAE;AAAA,YACjF;AAEA,kBAAM,cAAmB,UAAQ,WAAO,GAAG,UAAU,OAAO,MAAM,IAAI,KAAK,IAAI,CAAC,MAAM;AACtF,kBAAM,kBAAuB,UAAK,QAAQ,WAAW,IAAI;AAGzD,iBAAK,gBAAgB,QAAQ,OAAO,MAAM;AAG1C,kBAAM,KAAK,yBAAyB,WAAW,KAAK,aAAa,OAAO,MAAM;AAG9E,kBAAM,KAAK,cAAc,aAAa,iBAAiB,OAAO,MAAM;AAEpE,oBAAQ,IAAI,UAAK,OAAO,MAAM,sBAAsB,OAAO,aAAa,EAAE;AAC1E;AAAA,UAEJ,SAAS,OAAgB;AACrB,kBAAM,eAAe,iBAAiB,QAAQ,MAAM,UAAU;AAE9D,gBAAI,UAAU,eACV,aAAa,SAAS,YAAY,KAClC,aAAa,SAAS,SAAS,KAC/B,aAAa,SAAS,WAAW,KACjC,aAAa,SAAS,WAAW,IAClC;AACC;AACA,sBAAQ,IAAI,sBAAe,OAAO,MAAM,YAAY,OAAO,IAAI,UAAU,MAAM;AAC/E,oBAAM,IAAI,QAAQ,CAAAJ,aAAW,WAAWA,UAAS,MAAO,KAAK,OAAO,IAAI,GAAI,CAAC;AAAA,YACjF,OAAO;AACH,oBAAM,IAAI,MAAM,qBAAqB,OAAO,MAAM,KAAK,YAAY,EAAE;AAAA,YACzE;AAAA,UACJ;AAAA,QACJ;AAAA,MACJ,CAAC,CAAC;AAEF,YAAM,WAAW,QAAQ,OAAO,CAAC,MAAkC,EAAE,WAAW,UAAU;AAC1F,UAAI,SAAS,SAAS,GAAG;AACrB,cAAM,WAAW,SAAS,IAAI,OAAK,EAAE,kBAAkB,QAAQ,EAAE,OAAO,UAAU,OAAO,EAAE,MAAM,CAAC;AAClG,cAAM,IAAI,MAAM,SAAS,KAAK,KAAK,CAAC;AAAA,MACxC;AAGA,WAAK,YAAY,QAAQ,aAAAI,QAAM,MAAM,+BAA+B,CAAC;AAAA,IACzE,SAAS,OAAgB;AACrB,YAAM,eAAe,iBAAiB,QAAQ,MAAM,UAAU;AAC9D,WAAK,YAAY,KAAK,aAAAA,QAAM,IAAI,4BAA4B,YAAY,EAAE,CAAC;AAC3E,YAAM;AAAA,IACV;AAAA,EACJ;AAAA,EAEA,OAAe,mBAAmB,QAAgB,SAAiB,OAAe,QAAgB,SAAkB;AAChH,UAAM,cAAc,KAAK,kBAAkB,SAAS,KAAK;AACzD,UAAM,eAAe;AAAA,MACjB,aAAa;AAAA,MACb,YAAY;AAAA,MACZ,WAAW;AAAA,MACX,QAAQ;AAAA,MACR,UAAU;AAAA,IACd;AAEA,UAAM,iBAAiB;AAAA,MACnB,aAAa,aAAAA,QAAM,KAAK,aAAa;AAAA,MACrC,YAAY,aAAAA,QAAM,OAAO,YAAY;AAAA,MACrC,WAAW,aAAAA,QAAM,MAAM,YAAY;AAAA,MACnC,QAAQ,aAAAA,QAAM,KAAK,QAAQ;AAAA,MAC3B,UAAU,aAAAA,QAAM,OAAO,iBAAiB,OAAO,IAAI,CAAC,GAAG;AAAA,IAC3D;AAEA,UAAM,QAAQ,aAAa,MAAmC,KAAK;AACnE,UAAM,UAAU,eAAe,MAAqC,KAAK;AAEzE,SAAK,YAAY,OAAO,GAAG,WAAW,IAAI,KAAK,IAAI,aAAAA,QAAM,KAAK,MAAM,CAAC,MAAM,OAAO;AAAA,EACtF;AAAA,EAEA,OAAe,kBAAkB,SAAiB,OAAe,QAAgB,IAAY;AACzF,UAAM,SAAS,KAAK,MAAO,UAAU,QAAS,KAAK;AACnD,UAAM,QAAQ,QAAQ;AACtB,UAAM,YAAY,aAAAA,QAAM,MAAM,SAAI,OAAO,MAAM,CAAC;AAChD,UAAM,WAAW,aAAAA,QAAM,KAAK,SAAI,OAAO,KAAK,CAAC;AAC7C,UAAM,aAAa,aAAAA,QAAM,KAAK,GAAG,OAAO,IAAI,KAAK,EAAE;AACnD,WAAO,IAAI,SAAS,GAAG,QAAQ,KAAK,UAAU;AAAA,EAClD;AAAA,EAEA,OAAe,yBAAyB,KAAa,YAAoB,QAA+B;AACpG,WAAO,IAAI,QAAQ,CAACJ,UAAS,WAAW;AACpC,YAAM,UAAU,MAAM,IAAI,KAAK,EAAE,SAAS,EAAE,GAAG,CAAC,aAA8B;AAC1E,YAAI,SAAS,eAAe,OAAO,SAAS,eAAe,KAAK;AAC5D,gBAAM,cAAc,SAAS,QAAQ;AACrC,cAAI,aAAa;AACb,mBAAO,KAAK,yBAAyB,aAAa,YAAY,MAAM,EAAE,KAAKA,QAAO,EAAE,MAAM,MAAM;AAAA,UACpG;AAAA,QACJ;AAEA,YAAI,SAAS,eAAe,KAAK;AAC7B,iBAAO,IAAI,MAAM,QAAQ,SAAS,UAAU,SAAS,MAAM,EAAE,CAAC;AAC9D;AAAA,QACJ;AAEA,cAAM,OAAU,qBAAkB,UAAU;AAC5C,cAAM,aAAa,SAAS,SAAS,QAAQ,gBAAgB,KAAK,KAAK,EAAE;AACzE,YAAI,kBAAkB;AAEtB,iBAAS,GAAG,QAAQ,CAAC,UAAU;AAC3B,6BAAmB,MAAM;AACzB,eAAK,MAAM,KAAK;AAEhB,cAAI,aAAa,GAAG;AAChB,kBAAM,WAA6B;AAAA,cAC/B,YAAY;AAAA,cACZ,OAAO;AAAA,cACP,YAAa,kBAAkB,aAAc;AAAA,YACjD;AACA,iBAAK,uBAAuB,QAAQ,QAAQ;AAAA,UAChD;AAAA,QACJ,CAAC;AAED,iBAAS,GAAG,OAAO,MAAM;AAGrB,eAAK,IAAI,MAAMA,SAAQ,CAAC;AAAA,QAC5B,CAAC;AAED,iBAAS,GAAG,SAAS,CAAC,QAAQ;AAC1B,eAAK,MAAM;AACX,eAAK,YAAY,UAAU;AAC3B,iBAAO,GAAG;AAAA,QACd,CAAC;AAED,aAAK,GAAG,SAAS,CAAC,QAAQ;AACtB,eAAK,MAAM;AACX,eAAK,YAAY,UAAU;AAC3B,iBAAO,GAAG;AAAA,QACd,CAAC;AAAA,MACL,CAAC;AAED,cAAQ,GAAG,SAAS,MAAM;AAC1B,cAAQ,GAAG,WAAW,MAAM;AACxB,gBAAQ,QAAQ;AAChB,eAAO,IAAI,MAAM,uBAAuB,MAAM,EAAE,CAAC;AAAA,MACrD,CAAC;AAAA,IACL,CAAC;AAAA,EACL;AAAA,EAEA,OAAe,uBAAuB,QAAgB,UAA4B;AAC9E,UAAM,aAAa,SAAS,WAAW,QAAQ,CAAC;AAChD,UAAM,cAAc,SAAS,aAAa,OAAO,MAAM,QAAQ,CAAC;AAChE,UAAM,SAAS,SAAS,QAAQ,OAAO,MAAM,QAAQ,CAAC;AAGtD,UAAM,WAAW;AACjB,UAAM,SAAS,KAAK,MAAO,SAAS,aAAa,MAAO,QAAQ;AAChE,UAAM,QAAQ,WAAW;AACzB,UAAM,cAAc,aAAAI,QAAM,MAAM,SAAI,OAAO,MAAM,CAAC,IAAI,aAAAA,QAAM,KAAK,SAAI,OAAO,KAAK,CAAC;AAElF,UAAM,eAAe,IAAI,WAAW,KAAK,UAAU,MAAM,UAAU,IAAI,KAAK;AAC5E,SAAK,YAAY,OAAO,aAAM,aAAAA,QAAM,KAAK,MAAM,CAAC,MAAM,YAAY;AAAA,EACtE;AAAA,EAEA,OAAe,cAAc,SAAiB,YAAoB,QAA+B;AAC7F,WAAO,IAAI,QAAQ,CAACJ,UAAS,WAAW;AAKpC,YAAM,SAAc,aAAQ,UAAU;AACtC,UAAI,YAAY;AAChB,YAAM,UAA2B,CAAC;AAElC,MAAG,oBAAiB,OAAO,EACtB,KAAc,eAAM,CAAC,EACrB,GAAG,SAAS,CAAC,UAA0B;AACpC,YAAI,MAAM,SAAS,QAAQ;AACvB,gBAAM,UAAU;AAChB;AAAA,QACJ;AACA,cAAM,SAAS,cAAc;AAC7B;AACA,cAAM,SAAS,SAAS,aAAkB,UAAK,QAAa,cAAS,MAAM,IAAI,CAAC;AAEhF,gBAAQ,KAAK,IAAI,QAAc,CAAC,KAAK,QAAQ;AACzC,gBAAM,cAAiB,qBAAkB,MAAM;AAC/C,gBAAM,KAAK,WAAW;AACtB,sBAAY,GAAG,UAAU,MAAM;AAC3B,gBAAI,QAAQ,aAAa,SAAS;AAC9B,kBAAI;AAAE,gBAAG,aAAU,QAAQ,GAAK;AAAA,cAAG,QAAQ;AAAA,cAAwB;AAAA,YACvE;AACA,gBAAI;AAAA,UACR,CAAC;AACD,sBAAY,GAAG,SAAS,GAAG;AAAA,QAC/B,CAAC,CAAC;AAAA,MACN,CAAC,EACA,GAAG,SAAS,CAAC,QAAe;AACzB,aAAK,YAAY,OAAO;AACxB,eAAO,GAAG;AAAA,MACd,CAAC,EACA,GAAG,SAAS,MAAM;AACf,gBAAQ,IAAI,OAAO,EACd,KAAK,MAAM;AACR,eAAK,YAAY,OAAO;AACxB,cAAI,cAAc,GAAG;AACjB,mBAAO,IAAI,MAAM,sDAAgD,MAAM,EAAE,CAAC;AAAA,UAC9E,OAAO;AACH,YAAAA,SAAQ;AAAA,UACZ;AAAA,QACJ,CAAC,EACA,MAAM,CAAC,QAAQ;AACZ,eAAK,YAAY,OAAO;AACxB,iBAAO,GAAG;AAAA,QACd,CAAC;AAAA,MACT,CAAC;AAAA,IACT,CAAC;AAAA,EACL;AAAA,EAEA,OAAe,YAAY,UAAwB;AAC/C,QAAI;AACA,UAAO,cAAW,QAAQ,GAAG;AACzB,QAAG,cAAW,QAAQ;AAAA,MAC1B;AAAA,IACJ,QAAQ;AAAA,IAER;AAAA,EACJ;AAAA,EAEA,OAAe,mBAA2B;AAEtC,UAAMK,cAAa,OAAO,gBAAgB,eAAe,YAAY,UAC/D,0BAAc,YAAY,GAAG,IAC7B;AACN,UAAM,YAAYA,kBAAa,qBAAQA,WAAU,IAAI,QAAQ,IAAI;AAGjE,UAAM,eAAe;AAAA,MACZ,aAAQ,QAAQ,IAAI,GAAG,WAAW,KAAK;AAAA,MACvC,aAAQ,QAAQ,IAAI,GAAG,gBAAgB,WAAW,KAAK;AAAA,MACvD,aAAQ,WAAW,MAAM,KAAK;AAAA,IACvC;AAGA,eAAW,OAAO,cAAc;AAC5B,UAAI;AACA,YAAI,CAAI,cAAW,GAAG,GAAG;AACrB,UAAG,aAAU,KAAK,EAAE,WAAW,KAAK,CAAC;AAAA,QACzC;AAEA,cAAM,WAAgB,UAAK,KAAK,OAAO;AACvC,QAAG,iBAAc,UAAU,MAAM;AACjC,QAAG,cAAW,QAAQ;AACtB,eAAO;AAAA,MACX,QAAQ;AAEJ;AAAA,MACJ;AAAA,IACJ;AAGA,UAAM,UAAe,UAAQ,WAAO,GAAG,WAAW,KAAK;AACvD,IAAG,aAAU,SAAS,EAAE,WAAW,KAAK,CAAC;AACzC,WAAO;AAAA,EACX;AACJ;;;AC9iBA,IAAAC,MAAoB;AACpB,IAAAC,QAAsB;AACtB,IAAAC,MAAoB;AACpB,IAAAC,cAA8B;AAC9B,IAAAC,eAAwB;AAPxB,IAAAC,eAAA;AASA,IAAM,SAAN,MAAY;AAAA,EACR,OAAe,gBAAgB;AAAA,EAC/B,OAAe,kBAAwC;AAAA,EACvD,OAAe,iBAA4C,CAAC;AAAA,EAE5D,aAAa,sBAAqC;AAC9C,QAAI,KAAK,iBAAiB,KAAK,iBAAiB;AAC5C,YAAM,KAAK;AACX;AAAA,IACJ;AAEA,UAAM,SAAS,KAAK,UAAU;AAG9B,QAAI,CAAC,KAAK,eAAe;AACrB,WAAK,gBAAgB;AACrB,WAAK,kBAAkB,KAAK,iBAAiB;AAE7C,UAAI;AACA,cAAM,KAAK;AAAA,MACf,UAAE;AACE,aAAK,gBAAgB;AACrB,aAAK,kBAAkB;AAAA,MAC3B;AAAA,IACJ;AAAA,EACJ;AAAA,EAEA,aAAqB,mBAAkC;AACnD,QAAI;AACA,YAAM,SAAS,KAAK,UAAU;AAC9B,YAAM,WAAW,SAAS,MAAM;AAAA,IACpC,SAAS,OAAO;AACZ,cAAQ,KAAK,oDAA2C,MAAgB,OAAO;AAC/E,cAAQ,IAAI,iFAAiE;AAAA,IACjF;AAAA,EACJ;AAAA,EAEA,OAAe,YAAoB;AAE/B,UAAMC,cAAa,OAAOD,iBAAgB,eAAeA,aAAY,UAC/D,2BAAcA,aAAY,GAAG,IAC7B;AACN,UAAM,YAAYC,kBAAa,sBAAQA,WAAU,IAAI,QAAQ,IAAI;AAGjE,UAAM,eAAe;AAAA,MACZ,cAAQ,QAAQ,IAAI,GAAG,WAAW,KAAK;AAAA,MACvC,cAAQ,QAAQ,IAAI,GAAG,gBAAgB,WAAW,KAAK;AAAA,MACvD,cAAQ,WAAW,MAAM,KAAK;AAAA,IACvC;AAGA,eAAW,OAAO,cAAc;AAC5B,UAAI;AACA,YAAI,CAAI,eAAW,GAAG,GAAG;AACrB,UAAG,cAAU,KAAK,EAAE,WAAW,KAAK,CAAC;AAAA,QACzC;AAGA,eAAO;AAAA,MACX,QAAQ;AAEJ;AAAA,MACJ;AAAA,IACJ;AAGA,UAAM,UAAe,WAAQ,WAAO,GAAG,WAAW,KAAK;AACvD,IAAG,cAAU,SAAS,EAAE,WAAW,KAAK,CAAC;AACzC,WAAO;AAAA,EACX;AAAA,EAGA,OAAe,oBAAoB,QAAgB,QAAgBC,WAAkBC,OAAsB;AAEvG,UAAM,WAAW,GAAG,MAAM,IAAID,SAAQ,IAAIC,KAAI;AAC9C,QAAI,KAAK,eAAe,QAAQ,GAAG;AAC/B,YAAM,aAAkB,WAAK,QAAQ,KAAK,eAAe,QAAQ,CAAC;AAClE,UAAO,eAAW,UAAU,GAAG;AAC3B,eAAO;AAAA,MACX;AAAA,IACJ;AAEA,QAAI;AACA,YAAM,QAAW,gBAAY,MAAM;AACnC,YAAM,YAAYD,cAAa,YAAY,SAAS;AACpD,YAAM,UAAU,IAAI,OAAO,IAAI,MAAM,+BAA+BA,SAAQ,IAAIC,KAAI,GAAG,UAAU,QAAQ,KAAK,KAAK,CAAC,GAAG;AAEvH,YAAM,eAAe,MAAM,KAAK,OAAK,QAAQ,KAAK,CAAC,CAAC;AAEpD,UAAI,cAAc;AACd,aAAK,eAAe,QAAQ,IAAI;AAChC,eAAY,WAAK,QAAQ,YAAY;AAAA,MACzC;AAAA,IACJ,SAAS,OAAO;AAAA,IAEhB;AAGA,UAAM,eAAe,GAAG,MAAM,WAAWD,SAAQ,IAAIC,KAAI,GAAGD,cAAa,YAAY,SAAS,EAAE;AAChG,WAAY,WAAK,QAAQ,YAAY;AAAA,EACzC;AAAA,EAEA,aAAa,MAA2B;AACpC,UAAM,KAAK,oBAAoB;AAE/B,UAAMC,QAAO,IAAI,aAAa;AAC9B,UAAMD,YAAWC,MAAK,YAAY;AAClC,UAAM,eAAeA,MAAK,gBAAgB;AAC1C,UAAM,SAAS,KAAK,UAAU;AAE9B,UAAM,cAAsC;AAAA,MACxC,SAAS;AAAA,MACT,OAAO;AAAA,MACP,QAAQ;AAAA,IACZ;AAEA,UAAM,UAAkC;AAAA,MACpC,QAAQ;AAAA,MACR,SAAS;AAAA,IACb;AAEA,UAAM,OAAO,YAAYD,SAAQ;AACjC,UAAM,aAAa,QAAQ,YAAY;AAEvC,QAAI,QAAQ,YAAY;AACpB,aAAO;AAAA,QACH,cAAc,KAAK,oBAAoB,QAAQ,SAAS,MAAM,UAAU;AAAA,QACxE,eAAe,KAAK,oBAAoB,QAAQ,UAAU,MAAM,UAAU;AAAA,MAC9E;AAAA,IACJ;AAEA,WAAO;AAAA,MACH,cAAc;AAAA,MACd,eAAe;AAAA,IACnB;AAAA,EACJ;AACJ;;;AChFO,IAAM,SAAN,MAAa;AAAA,EACV,OAAmB,CAAC;AAAA,EACpB,YAAgD,CAAC;AAAA;AAAA;AAAA;AAAA;AAAA,EAMzD,IAAI,YAA8B;AAChC,SAAK,OAAO;AAEZ,QAAI,WAAW,WAAW;AACxB,WAAK,YAAY,WAAW;AAAA,IAC9B;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,IAAiB,KAAgB;AAC/B,WAAO,KAAK,KAAK,GAAG;AAAA,EACtB;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,YAAY,QAA2C;AACrD,WAAO,KAAK,UAAU,MAAM,KAAK;AAAA,EACnC;AAAA;AAAA;AAAA;AAAA,EAKA,kBAAsD;AACpD,WAAO,KAAK;AAAA,EACd;AACF;;;AJrGA,IAAAE,wBAAsB;AAGtB,oBAA8B;;;AKN9B,iBAAgB;AAChB,gBAAe;AACf,IAAAC,eAAiB;AACjB,2BAAsB;AAqBf,IAAM,eAAN,MAAM,cAAa;AAAA,EACtB,OAAe,WAAsC,oBAAI,IAAI;AAAA,EAErD;AAAA,EACA;AAAA,EACA;AAAA,EACA,SAA4B;AAAA,EAC5B,SAAS;AAAA,EACT,UAA4B,CAAC;AAAA,EAC7B,WAAoC;AAAA,EACpC;AAAA,EAEA,YAAY,MAAc,YAAoB,YAAsB,iBAAiB,KAAO;AAChG,SAAK,OAAO;AACZ,SAAK,aAAa;AAClB,SAAK,aAAa;AAClB,SAAK,iBAAiB;AAAA,EAC1B;AAAA,EAEA,OAAO,IAAI,MAAc,YAAoB,YAAoC;AAC7E,QAAI,SAAS,KAAK,SAAS,IAAI,IAAI;AACnC,QAAI,CAAC,QAAQ;AACT,eAAS,IAAI,cAAa,MAAM,YAAY,UAAU;AACtD,WAAK,SAAS,IAAI,MAAM,MAAM;AAAA,IAClC;AACA,WAAO;AAAA,EACX;AAAA,EAEA,OAAO,YAAqB;AACxB,UAAM,OAAO,QAAQ,IAAI;AACzB,QAAI,SAAS,OAAO,SAAS,QAAS,QAAO;AAC7C,WAAO;AAAA,EACX;AAAA,EAEQ,eAAuB;AAC3B,WAAO,aAAAC,QAAK,KAAK,QAAQ,IAAI,GAAG,WAAW,UAAU,GAAG,KAAK,IAAI,OAAO;AAAA,EAC5E;AAAA,EAEQ,eAAuB;AAC3B,WAAO,aAAAA,QAAK,KAAK,QAAQ,IAAI,GAAG,WAAW,UAAU,GAAG,KAAK,IAAI,OAAO;AAAA,EAC5E;AAAA;AAAA;AAAA;AAAA;AAAA,EAMQ,mBAA4B;AAChC,UAAM,WAAW,KAAK,aAAa;AACnC,QAAI;AACA,gBAAAC,QAAG,UAAU,aAAAD,QAAK,QAAQ,QAAQ,GAAG,EAAE,WAAW,KAAK,CAAC;AACxD,YAAM,KAAK,UAAAC,QAAG,SAAS,UAAU,IAAI;AACrC,gBAAAA,QAAG,UAAU,IAAI,OAAO,QAAQ,GAAG,CAAC;AACpC,gBAAAA,QAAG,UAAU,EAAE;AACf,aAAO;AAAA,IACX,QAAQ;AACJ,UAAI;AACA,cAAM,MAAM,KAAK,IAAI,IAAI,UAAAA,QAAG,SAAS,QAAQ,EAAE;AAC/C,YAAI,MAAM,MAAO;AACb,oBAAAA,QAAG,WAAW,QAAQ;AACtB,iBAAO,KAAK,iBAAiB;AAAA,QACjC;AAAA,MACJ,QAAQ;AAAA,MAAqC;AAC7C,aAAO;AAAA,IACX;AAAA,EACJ;AAAA,EAEQ,mBAAyB;AAC7B,QAAI;AAAE,gBAAAA,QAAG,WAAW,KAAK,aAAa,CAAC;AAAA,IAAG,QAAQ;AAAA,IAAqB;AAAA,EAC3E;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,MAAM,SAA2B;AAC7B,QAAI,KAAK,UAAU,CAAC,KAAK,OAAO,UAAW,QAAO;AAClD,QAAI,KAAK,SAAU,QAAO,KAAK;AAE/B,SAAK,WAAW,KAAK,eAAe,EAAE,MAAM,MAAM,KAAK;AACvD,UAAM,SAAS,MAAM,KAAK;AAC1B,SAAK,WAAW;AAChB,WAAO;AAAA,EACX;AAAA,EAEA,MAAc,iBAAmC;AAE7C,UAAM,OAAO,KAAK,aAAa;AAC/B,QAAI,QAAQ,MAAM,KAAK,WAAW,IAAI,EAAG,QAAO;AAKhD,UAAM,UAAU,KAAK,iBAAiB;AACtC,QAAI;AACA,UAAI,SAAS;AACT,YAAI;AAAE,oBAAAA,QAAG,WAAW,KAAK,aAAa,CAAC;AAAA,QAAG,QAAQ;AAAA,QAAkB;AACpE,aAAK,YAAY;AAAA,MACrB;AAGA,YAAM,WAAW,KAAK,IAAI,IAAI;AAC9B,aAAO,KAAK,IAAI,IAAI,UAAU;AAC1B,cAAM,IAAI,QAAQ,OAAK,WAAW,GAAG,GAAG,CAAC;AACzC,cAAM,UAAU,KAAK,aAAa;AAClC,YAAI,WAAW,MAAM,KAAK,WAAW,OAAO,EAAG,QAAO;AAAA,MAC1D;AACA,aAAO;AAAA,IACX,UAAE;AACE,UAAI,QAAS,MAAK,iBAAiB;AAAA,IACvC;AAAA,EACJ;AAAA,EAEQ,eAA8B;AAClC,QAAI;AACA,YAAM,MAAM,UAAAA,QAAG,aAAa,KAAK,aAAa,GAAG,MAAM;AACvD,YAAM,OAAO,KAAK,MAAM,GAAG;AAC3B,YAAM,OAAO,MAAM;AACnB,aAAO,OAAO,UAAU,IAAI,KAAK,OAAO,KAAK,QAAQ,QAAQ,OAAO;AAAA,IACxE,QAAQ;AACJ,aAAO;AAAA,IACX;AAAA,EACJ;AAAA,EAEQ,cAAoB;AACxB,UAAM,YAAQ,4BAAM,KAAK,YAAY,CAAC,GAAG,KAAK,YAAY,YAAY,UAAU,cAAc,MAAM,GAAG;AAAA,MACnG,UAAU;AAAA,MACV,OAAO;AAAA,MACP,KAAK,QAAQ,IAAI;AAAA,IACrB,CAAC;AACD,UAAM,MAAM;AAAA,EAChB;AAAA,EAEQ,WAAW,MAAgC;AAC/C,WAAO,IAAI,QAAQ,CAACC,aAAY;AAC5B,YAAM,SAAS,WAAAC,QAAI,iBAAiB,EAAE,MAAM,aAAa,KAAK,GAAG,YAAY;AACzE,eAAO,WAAW,IAAI;AACtB,aAAK,OAAO,MAAM;AAIlB,YAAI;AACA,gBAAM,OAAO,MAAM,KAAK,KAAK,EAAE,QAAQ,OAAO,GAAG,GAAI;AACrD,UAAAD,SAAQ,KAAK,WAAW,GAAG;AAAA,QAC/B,QAAQ;AACJ,eAAK,OAAO;AACZ,UAAAA,SAAQ,KAAK;AAAA,QACjB;AAAA,MACJ,CAAC;AACD,aAAO,KAAK,SAAS,MAAMA,SAAQ,KAAK,CAAC;AACzC,aAAO,WAAW,KAAM,MAAM;AAAE,eAAO,QAAQ;AAAG,QAAAA,SAAQ,KAAK;AAAA,MAAG,CAAC;AAAA,IACvE,CAAC;AAAA,EACL;AAAA,EAEQ,OAAO,QAA0B;AACrC,SAAK,SAAS;AACd,SAAK,SAAS;AACd,WAAO,WAAW,CAAC;AACnB,WAAO,GAAG,QAAQ,CAAC,UAA2B,KAAK,OAAO,OAAO,SAAS,KAAK,IAAI,QAAQ,OAAO,KAAK,KAAK,CAAC,CAAC;AAC9G,WAAO,GAAG,SAAS,MAAM,KAAK,OAAO,CAAC;AACtC,WAAO,GAAG,SAAS,MAAM,KAAK,OAAO,CAAC;AAAA,EAC1C;AAAA,EAEQ,SAAe;AACnB,QAAI,KAAK,QAAQ;AACb,WAAK,OAAO,mBAAmB;AAC/B,WAAK,OAAO,QAAQ;AACpB,WAAK,SAAS;AAAA,IAClB;AAEA,eAAW,OAAO,KAAK,QAAQ,OAAO,CAAC,GAAG;AACtC,mBAAa,IAAI,KAAK;AACtB,UAAI,OAAO,IAAI,MAAM,wBAAwB,CAAC;AAAA,IAClD;AAAA,EACJ;AAAA,EAEQ,OAAO,OAAqB;AAChC,SAAK,UAAU,MAAM,SAAS,MAAM;AACpC,QAAI;AACJ,YAAQ,MAAM,KAAK,OAAO,QAAQ,IAAI,OAAO,IAAI;AAC7C,YAAM,OAAO,KAAK,OAAO,MAAM,GAAG,GAAG,EAAE,KAAK;AAC5C,WAAK,SAAS,KAAK,OAAO,MAAM,MAAM,CAAC;AACvC,UAAI,CAAC,KAAM;AACX,YAAM,SAAS,KAAK,QAAQ,mBAAmB;AAC/C,UAAI,WAAW,GAAI;AACnB,YAAM,WAAW,KAAK,MAAM,SAAS,oBAAoB,MAAM;AAC/D,YAAM,MAAM,KAAK,QAAQ,MAAM;AAC/B,UAAI,CAAC,IAAK;AACV,mBAAa,IAAI,KAAK;AACtB,UAAI;AACA,YAAI,QAAQ,KAAK,MAAM,QAAQ,CAAC;AAAA,MACpC,SAAS,GAAQ;AACb,YAAI,OAAO,IAAI,MAAM,4BAA4B,EAAE,OAAO,EAAE,CAAC;AAAA,MACjE;AAAA,IACJ;AAAA,EACJ;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,KAAK,SAA8B,WAA6C;AAC5E,WAAO,IAAI,QAAQ,CAACA,UAAS,WAAW;AACpC,UAAI,CAAC,KAAK,UAAU,KAAK,OAAO,WAAW;AACvC,eAAO,IAAI,MAAM,sBAAsB,CAAC;AACxC;AAAA,MACJ;AACA,YAAM,QAAQ,WAAW,MAAM;AAC3B,cAAM,IAAI,KAAK,QAAQ,UAAU,OAAK,EAAE,UAAU,KAAK;AACvD,YAAI,MAAM,GAAI,MAAK,QAAQ,OAAO,GAAG,CAAC;AACtC,eAAO,IAAI,MAAM,wBAAwB,CAAC;AAI1C,aAAK,OAAO;AAAA,MAChB,GAAG,aAAa,KAAK,cAAc;AAEnC,WAAK,QAAQ,KAAK,EAAE,SAAAA,UAAS,QAAQ,MAAM,CAAC;AAC5C,WAAK,OAAO,MAAM,KAAK,UAAU,OAAO,IAAI,IAAI;AAAA,IACpD,CAAC;AAAA,EACL;AAAA,EAEA,MAAM,QAAQ,KAAa,MAAwC;AAC/D,UAAM,UAA+B,EAAE,QAAQ,WAAW,IAAI;AAC9D,QAAI,KAAM,SAAQ,QAAQ;AAC1B,WAAO,KAAK,KAAK,OAAO;AAAA,EAC5B;AAAA,EAEA,MAAM,IAAI,OAAe,SAAgB,CAAC,GAAG,MAAwC;AACjF,UAAM,UAA+B,EAAE,QAAQ,OAAO,OAAO,OAAO;AACpE,QAAI,KAAM,SAAQ,QAAQ;AAC1B,WAAO,KAAK,KAAK,OAAO;AAAA,EAC5B;AAAA,EAEA,MAAM,QAAyB;AAC3B,UAAM,MAAM,MAAM,KAAK,KAAK,EAAE,QAAQ,QAAQ,CAAC;AAC/C,QAAI,IAAI,WAAW,OAAO,CAAC,IAAI,MAAM,OAAO;AACxC,YAAM,IAAI,MAAM,IAAI,WAAW,6BAA6B;AAAA,IAChE;AACA,WAAO,IAAI,KAAK;AAAA,EACpB;AAAA,EAEA,MAAM,OAAO,MAA6B;AACtC,UAAM,MAAM,MAAM,KAAK,KAAK,EAAE,QAAQ,UAAU,OAAO,KAAK,CAAC;AAC7D,QAAI,IAAI,WAAW,IAAK,OAAM,IAAI,MAAM,IAAI,WAAW,8BAA8B;AAAA,EACzF;AAAA,EAEA,MAAM,SAAS,MAA6B;AACxC,UAAM,MAAM,MAAM,KAAK,KAAK,EAAE,QAAQ,YAAY,OAAO,KAAK,CAAC;AAC/D,QAAI,IAAI,WAAW,IAAK,OAAM,IAAI,MAAM,IAAI,WAAW,gCAAgC;AAAA,EAC3F;AAAA,EAEA,MAAM,WAA0B;AAC5B,QAAI;AAAE,YAAM,KAAK,KAAK,EAAE,QAAQ,WAAW,CAAC;AAAA,IAAG,QAAQ;AAAA,IAAkC;AACzF,SAAK,OAAO;AACZ,QAAI;AAAE,gBAAAD,QAAG,WAAW,KAAK,aAAa,CAAC;AAAA,IAAG,QAAQ;AAAA,IAAqB;AAAA,EAC3E;AACJ;;;ALhRA,IAAM,SAAN,MAAa;AAAA,EACD;AAAA,EACA;AAAA,EACA;AAAA,EACA,SAA4B;AAAA,EAC5B;AAAA,EACA,eAAe;AAAA,EAEvB,YAAY,MAAc,UAAU,KAAO;AACvC,SAAK,OAAO;AACZ,SAAK,SAAS,KAAK,UAAU,IAAI;AACjC,SAAK,YAAY,KAAK,aAAa;AACnC,SAAK,UAAU;AAAA,EACnB;AAAA,EAEA,MAAM,mBAAkC;AACpC,QAAI,CAAC,KAAK,QAAQ;AACd,WAAK,SAAS,MAAM,OAAO,IAAI;AAAA,IACnC;AAAA,EACJ;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,MAAc,YAA0C;AACpD,QAAI,KAAK,gBAAgB,CAAC,aAAa,UAAU,EAAG,QAAO;AAC3D,UAAM,KAAK,iBAAiB;AAC5B,QAAI,CAAC,KAAK,OAAQ,QAAO;AAEzB,UAAM,aAAa,KAAK,OAAO,cAAkC;AACjE,QAAI,CAAC,WAAY,QAAO;AAExB,UAAM,SAAS,aAAa,IAAI,KAAK,MAAM,YAAY,KAAK,SAAS;AACrE,UAAMG,MAAK,MAAM,OAAO,OAAO;AAC/B,QAAI,CAACA,KAAI;AACL,WAAK,eAAe;AACpB,aAAO;AAAA,IACX;AACA,WAAO;AAAA,EACX;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,MAAM,WAAW,KAAa,MAAwC;AAClE,UAAM,SAAS,MAAM,KAAK,UAAU;AACpC,QAAI,QAAQ;AACR,UAAI;AACA,eAAO,MAAM,OAAO,QAAQ,KAAK,IAAI;AAAA,MACzC,SAAS,OAAY;AACjB,YAAI,KAAM,OAAM;AAAA,MAEpB;AAAA,IACJ;AACA,QAAI,MAAM;AACN,YAAM,IAAI,MAAM,wGAAwG;AAAA,IAC5H;AACA,WAAO,KAAK,IAAI,gBAAgB,CAAC,YAAY,WAAW,SAAS,KAAK,UAAU,GAAG,CAAC,CAAQ;AAAA,EAChG;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,SAAS,OAAe,SAAgB,CAAC,GAAG,MAAwC;AACtF,UAAM,SAAS,MAAM,KAAK,UAAU;AACpC,QAAI,QAAQ;AACR,UAAI;AACA,eAAO,MAAM,OAAO,IAAI,OAAO,QAAQ,IAAI;AAAA,MAC/C,SAAS,OAAY;AACjB,YAAI,KAAM,OAAM;AAAA,MACpB;AAAA,IACJ;AACA,QAAI,MAAM;AACN,YAAM,IAAI,MAAM,wGAAwG;AAAA,IAC5H;AACA,WAAO,KAAK,IAAI,gBAAgB,CAAC,YAAY,OAAO,WAAW,OAAO,YAAY,KAAK,UAAU,MAAM,CAAC,CAAQ;AAAA,EACpH;AAAA;AAAA,EAGA,MAAM,mBAAoC;AACtC,UAAM,SAAS,MAAM,KAAK,UAAU;AACpC,QAAI,CAAC,QAAQ;AACT,YAAM,IAAI,MAAM,wGAAwG;AAAA,IAC5H;AACA,WAAO,OAAO,MAAM;AAAA,EACxB;AAAA,EAEA,MAAM,kBAAkB,MAA6B;AACjD,UAAM,SAAS,MAAM,KAAK,UAAU;AACpC,QAAI,CAAC,OAAQ,OAAM,IAAI,MAAM,2CAA2C;AACxE,WAAO,OAAO,OAAO,IAAI;AAAA,EAC7B;AAAA,EAEA,MAAM,oBAAoB,MAA6B;AACnD,UAAM,SAAS,MAAM,KAAK,UAAU;AACpC,QAAI,CAAC,OAAQ,OAAM,IAAI,MAAM,2CAA2C;AACxE,WAAO,OAAO,SAAS,IAAI;AAAA,EAC/B;AAAA,EAEA,eAAe;AACX,QAAI,OAAO,CAAC;AACZ,QAAI,KAAK,OAAO,QAAQ,UAAU;AAC9B,aAAO;AAAA,QACH;AAAA,QAAQ,YAAY,KAAK;AAAA,QACzB;AAAA,QAAkB,KAAK;AAAA,QACvB;AAAA,QAAc,KAAK,OAAO,OAAO,WAAW;AAAA,QAC5C;AAAA,QAAW,KAAK,OAAO;AAAA,MAC3B;AAAA,IACJ,OAAO;AACH,aAAO;AAAA,QACH;AAAA,QAAQ,YAAY,KAAK;AAAA,QACzB;AAAA,QAAkB,KAAK;AAAA,QACvB;AAAA,QAAc,KAAK,OAAO,OAAO;AAAA,QACjC;AAAA,QAAU,KAAK,OAAO,OAAO;AAAA,QAC7B;AAAA,QAAU,OAAO,KAAK,OAAO,OAAO,IAAI;AAAA,QACxC;AAAA,QAAW,KAAK,OAAO;AAAA,MAC3B;AAEA,UAAI,KAAK,OAAO,OAAO,QAAQ,QAAQ,KAAK,OAAO,OAAO,SAAS,IAAI;AACnE,aAAK,KAAK,UAAU,KAAK,OAAO,OAAO,IAAI;AAAA,MAC/C;AACA,UAAI,KAAK,OAAO,OAAO,YAAY,QAAQ,KAAK,OAAO,OAAO,aAAa,IAAI;AAC3E,aAAK,KAAK,cAAc,KAAK,OAAO,OAAO,QAAQ;AAAA,MACvD;AAAA,IACJ;AACA,WAAO;AAAA,EACX;AAAA,EAEA,UAAU,MAAc;AACpB,UAAM,iBAAiB,IAAI,OAAY;AAEvC,QAAI;AACA,YAAM,iBAAiB,aAAAC,QAAK,QAAQ,QAAQ,IAAI,GAAG,kBAAkB;AAErE,YAAM,aAAa,OAAO,eAAe,cAAc,aAAa,QAAQ,IAAI;AAChF,YAAMC,eAAU,6BAAc,UAAU;AAExC,UAAIA,SAAQ,SAASA,SAAQ,SAAS;AAClC,YAAI;AACA,iBAAOA,SAAQ,MAAMA,SAAQ,QAAQ,cAAc,CAAC;AAAA,QACxD,SAAS,GAAG;AAAA,QAEZ;AAAA,MACJ;AACA,YAAM,eAAeA,SAAQ,cAAc;AAC3C,YAAM,WAAW,aAAa,WAAW;AAEzC,UAAI,OAAO,aAAa,YAAY;AAChC,iBAAS,cAAc;AAAA,MAC3B,OAAO;AACH,gBAAQ,MAAM,+DAAuD;AAAA,MACzE;AAAA,IACJ,SAAS,OAAY;AACjB,cAAQ,MAAM,qCAAgC,MAAM,OAAO;AAC3D,UAAI,MAAM,SAAS,oBAAoB;AACnC,gBAAQ,MAAM,qEAAgE;AAAA,MAClF;AAAA,IACJ;AAEA,WAAO,eAAe,YAAY,IAAI;AAAA,EAE1C;AAAA,EAEA,YAAY;AACR,WAAO,KAAK;AAAA,EAChB;AAAA,EAEA,MAAM,IAAI,QAAgB,MAAU;AAChC,UAAM,KAAK,iBAAiB;AAE5B,QAAI,CAAC,KAAK,QAAQ;AACd,YAAM,IAAI,MAAM,wBAAwB;AAAA,IAC5C;AAEA,WAAO,IAAI,QAAwB,CAACC,UAAS,WAAW;AACpD,YAAM,YAAQ,6BAAM,KAAK,OAAQ,MAA0B,GAAG,CAAC,GAAG,KAAK,WAAW,GAAG,IAAI,CAAC;AAE1F,UAAI,eAAe;AACnB,UAAI,eAAe;AACnB,UAAI,aAAa;AAEjB,YAAM,YAAY,WAAW,MAAM;AAC/B,YAAI,CAAC,YAAY;AACb,uBAAa;AACb,gBAAM,KAAK;AACX,iBAAO,IAAI,MAAM,iBAAiB,CAAC;AAAA,QACvC;AAAA,MACJ,GAAG,KAAK,OAAO;AAEf,YAAM,cAAc,CAAC,aAA6B;AAC9C,YAAI,CAAC,YAAY;AACb,uBAAa;AACb,uBAAa,SAAS;AACtB,UAAAA,SAAQ,QAAQ;AAAA,QACpB;AAAA,MACJ;AAIA,YAAM,gBAAgB,CAAC,WAA2B;AAC9C,YAAI;AACJ,gBAAQ,MAAM,OAAO,QAAQ,IAAI,OAAO,IAAI;AACxC,gBAAM,OAAO,OAAO,MAAM,GAAG,GAAG;AAChC,mBAAS,OAAO,MAAM,MAAM,CAAC;AAC7B,gBAAM,SAAS,KAAK,QAAQ,mBAAmB;AAC/C,cAAI,WAAW,GAAI;AACnB,cAAI;AACA,kBAAM,WAA4B,KAAK,MAAM,KAAK,MAAM,SAAS,oBAAoB,MAAM,CAAC;AAC5F,wBAAY;AAAA,cACR,QAAQ,SAAS;AAAA,cACjB,SAAS,SAAS;AAAA,cAClB,MAAM,SAAS;AAAA,YACnB,CAAC;AAAA,UACL,SAAS,OAAO;AACZ,wBAAY;AAAA,cACR,QAAQ;AAAA,cACR,SAAS;AAAA,cACT,MAAM;AAAA,YACV,CAAC;AAAA,UACL;AAAA,QACJ;AACA,eAAO;AAAA,MACX;AAEA,YAAM,OAAO,GAAG,QAAQ,CAAC,SAAS;AAC9B,cAAM,OAAO,KAAK,SAAS;AAE3B,cAAM,UAAU,KAAK,MAAM,IAAI,EAAE,OAAO,CAAC,MAAc,EAAE,KAAK,KAAK,CAAC,EAAE,SAAS,mBAAmB,CAAC,EAAE,KAAK,IAAI;AAC9G,YAAI,QAAS,SAAQ,IAAI,OAAO;AAChC,uBAAe,cAAc,eAAe,IAAI;AAAA,MACpD,CAAC;AAED,YAAM,OAAO,GAAG,QAAQ,CAAC,SAAS;AAC9B,cAAM,OAAO,KAAK,SAAS;AAE3B,cAAM,UAAU,KAAK,MAAM,IAAI,EAAE,OAAO,CAAC,MAAc,EAAE,KAAK,KAAK,CAAC,EAAE,SAAS,mBAAmB,CAAC,EAAE,KAAK,IAAI;AAC9G,YAAI,QAAS,SAAQ,IAAI,OAAO;AAChC,uBAAe,cAAc,eAAe,IAAI;AAAA,MACpD,CAAC;AAGD,YAAM,GAAG,SAAS,CAAC,SAAS;AACxB,qBAAa,SAAS;AACtB,YAAI,CAAC,YAAY;AACb,sBAAY;AAAA,YACR,QAAQ,SAAS,IAAI,MAAM;AAAA,YAC3B,SAAS,SAAS,IAAI,sBAAsB,4BAA4B,IAAI;AAAA,YAC5E,MAAM;AAAA,UACV,CAAC;AAAA,QACL;AAAA,MACJ,CAAC;AAED,YAAM,GAAG,SAAS,CAAC,UAAU;AACzB,qBAAa,SAAS;AACtB,YAAI,CAAC,YAAY;AACb,sBAAY;AAAA,YACR,QAAQ;AAAA,YACR,SAAS,kBAAkB,MAAM,OAAO;AAAA,YACxC,MAAM;AAAA,UACV,CAAC;AAAA,QACL;AAAA,MACJ,CAAC;AAED,YAAM,MAAM;AAAA,IAChB,CAAC;AAAA,EACL;AACJ;;;AMrRA,IAAAC,eAAiB;;;ACAjB,IAAAC,MAAoB;AACpB,IAAAC,QAAsB;AAuBtB,IAAI,CAAC,QAAQ,IAAI,oBAAoB;AACjC,UAAQ,IAAI,qBAAqB;AACrC;AAkBA,IAAI,UAAgC;AACpC,IAAI,aAAa;AAEjB,IAAM,UAAU,oBAAI,IAAoB;AACxC,IAAM,aAAa,oBAAI,IAA6B;AAEpD,SAAS,UAAuD;AAC5D,QAAMC,QAAO,QAAQ,SAAS,UAAU,UAAU;AAClD,MAAI,QAAQ,aAAa,QAAS,QAAO,EAAE,MAAM,WAAW,KAAK,OAAO,MAAAA,MAAK;AAC7E,MAAI,QAAQ,aAAa,SAAU,QAAO,EAAE,MAAM,SAAS,KAAK,SAAS,MAAAA,MAAK;AAC9E,SAAO,EAAE,MAAM,SAAS,KAAK,MAAM,MAAAA,MAAK;AAC5C;AAEA,SAAS,SAAS,MAA6B;AAC3C,QAAM,aAAa;AAAA,IACV,cAAQ,QAAQ,IAAI,GAAG,WAAW,OAAO,IAAI;AAAA,IAC7C,cAAQ,QAAQ,IAAI,GAAG,gBAAgB,WAAW,OAAO,IAAI;AAAA,EACtE;AACA,aAAW,KAAK,YAAY;AACxB,QAAO,eAAW,CAAC,EAAG,QAAO;AAAA,EACjC;AACA,SAAO;AACX;AAEA,SAAS,GAAG,MAA+B;AACvC,SAAO,EAAE,QAAQ,KAAK,SAAS,MAAM,KAAkB;AAC3D;AAEA,SAAS,QAAQ,GAA4B;AACzC,QAAM,MAAM,aAAa,QAAQ,EAAE,UAAU,OAAO,CAAC;AACrD,SAAO,EAAE,QAAQ,KAAK,SAAS,KAAK,MAAM,KAAK;AACnD;AAIA,SAAS,kBAAwC;AAC7C,QAAM,EAAE,MAAM,MAAAA,MAAK,IAAI,QAAQ;AAC/B,QAAM,YAAY,SAAS,qBAAqB,IAAI,IAAIA,KAAI,OAAO;AACnE,MAAI,CAAC,UAAW,QAAO;AAEvB,MAAI;AAEA,UAAM,QAAQ,QAAQ,SAAS;AAC/B,QAAI,OAAO,MAAM,YAAY,WAAY,QAAO;AAEhD,WAAO;AAAA,MACH,MAAM,QAAQ,SAAS;AACnB,eAAO,OAAO,MAAM,MAAM,QAAQ,OAAO,CAAC;AAAA,MAC9C;AAAA,MACA,MAAM,QAAQ,QAAQ,KAAK,MAAM;AAC7B,YAAI;AAEA,gBAAM,OAAO,MAAM,MAAM,QAAQ,QAAQ,KAAK,QAAQ,MAAS;AAC/D,iBAAO,GAAG,IAAI;AAAA,QAClB,SAAS,GAAG;AAAE,iBAAO,QAAQ,CAAC;AAAA,QAAG;AAAA,MACrC;AAAA,MACA,MAAM,aAAa,QAAQ,KAAK;AAC5B,YAAI;AACA,gBAAM,UAAU,MAAM,MAAM,aAAa,QAAQ,GAAG;AACpD,iBAAO,GAAG,OAAO;AAAA,QACrB,SAAS,GAAG;AAAE,iBAAO,QAAQ,CAAC;AAAA,QAAG;AAAA,MACrC;AAAA,MACA,MAAM,IAAI,QAAQ,OAAO,QAAQ,MAAM;AACnC,YAAI;AACA,gBAAM,OAAO,MAAM,MAAM,IAAI,QAAQ,OAAO,QAAQ,QAAQ,MAAS;AACrE,iBAAO,GAAG,IAAI;AAAA,QAClB,SAAS,GAAG;AAAE,iBAAO,QAAQ,CAAC;AAAA,QAAG;AAAA,MACrC;AAAA,MACA,MAAM,MAAM,QAAQ;AAChB,YAAI;AACA,gBAAM,OAAO,MAAM,MAAM,MAAM,MAAM;AACrC,iBAAO,GAAG,EAAE,OAAO,KAAK,CAAC;AAAA,QAC7B,SAAS,GAAG;AAAE,iBAAO,QAAQ,CAAC;AAAA,QAAG;AAAA,MACrC;AAAA,MACA,MAAM,OAAO,SAAS,MAAM;AACxB,YAAI;AACA,gBAAM,MAAM,OAAO,IAAI;AACvB,iBAAO,GAAG,IAAI;AAAA,QAClB,SAAS,GAAG;AAAE,iBAAO,QAAQ,CAAC;AAAA,QAAG;AAAA,MACrC;AAAA,MACA,MAAM,SAAS,SAAS,MAAM;AAC1B,YAAI;AACA,gBAAM,MAAM,SAAS,IAAI;AACzB,iBAAO,GAAG,IAAI;AAAA,QAClB,SAAS,GAAG;AAAE,iBAAO,QAAQ,CAAC;AAAA,QAAG;AAAA,MACrC;AAAA,MACA,MAAM,WAAW,QAAQ;AACrB,YAAI;AAAE,gBAAM,WAAW,MAAM;AAAA,QAAG,QAAQ;AAAA,QAA2B;AAAA,MACvE;AAAA,IACJ;AAAA,EACJ,QAAQ;AACJ,WAAO;AAAA,EACX;AACJ;AAIA,SAAS,mBAAyC;AAC9C,QAAM,EAAE,MAAM,KAAK,MAAAA,MAAK,IAAI,QAAQ;AACpC,QAAM,UAAU,SAAS,yBAAyB,IAAI,IAAIA,KAAI,IAAI,GAAG,EAAE;AACvE,MAAI,CAAC,QAAS,QAAO;AAErB,MAAI;AAEA,UAAM,QAAQ,QAAQ,OAAO;AAC7B,UAAM,MAAM,MAAM,KAAK,OAAO;AAE9B,UAAM,WAAW,IAAI,KAAK,eAAe,UAAU,CAAC,KAAK,CAAC;AAC1D,UAAM,WAAW,IAAI,KAAK,eAAe,UAAU,CAAC,UAAU,OAAO,KAAK,CAAC;AAC3E,UAAM,gBAAgB,IAAI,KAAK,qBAAqB,UAAU,CAAC,UAAU,KAAK,CAAC;AAC/E,UAAM,OAAO,IAAI,KAAK,WAAW,UAAU,CAAC,UAAU,OAAO,OAAO,KAAK,CAAC;AAC1E,UAAM,SAAS,IAAI,KAAK,aAAa,UAAU,CAAC,QAAQ,CAAC;AACzD,UAAM,UAAU,IAAI,KAAK,cAAc,UAAU,CAAC,UAAU,KAAK,CAAC;AAClE,UAAM,YAAY,IAAI,KAAK,gBAAgB,UAAU,CAAC,UAAU,KAAK,CAAC;AACtE,UAAM,cAAc,IAAI,KAAK,kBAAkB,UAAU,CAAC,QAAQ,CAAC;AACnE,UAAM,QAAQ,IAAI,KAAK,YAAY,QAAQ,CAAC,QAAQ,CAAC;AAErD,UAAM,OAAO,CAAC,QAAiC;AAC3C,UAAI,CAAC,IAAK,QAAO,EAAE,QAAQ,KAAK,SAAS,iCAAiC,MAAM,KAAK;AACrF,YAAM,IAAY,MAAM,OAAO,KAAK,QAAQ,EAAE;AAC9C,YAAM,GAAG;AACT,UAAI;AACA,cAAM,IAAI,KAAK,MAAM,CAAC;AACtB,eAAO,EAAE,QAAQ,EAAE,UAAU,KAAK,SAAS,EAAE,WAAW,IAAI,MAAM,EAAE,QAAQ,KAAK;AAAA,MACrF,SAAS,GAAQ;AACb,eAAO,EAAE,QAAQ,KAAK,SAAS,8BAA8B,EAAE,OAAO,IAAI,MAAM,KAAK;AAAA,MACzF;AAAA,IACJ;AAEA,UAAM,OAAO,CAAC,OAAY,SACtB,IAAI,QAAQ,CAACC,UAAS,WAAW;AAC7B,SAAG,MAAM,GAAG,MAAM,CAAC,KAAmB,QAAiB;AACnD,YAAI,IAAK,QAAO,OAAO,GAAG;AAC1B,QAAAA,SAAQ,KAAK,GAAG,CAAC;AAAA,MACrB,CAAC;AAAA,IACL,CAAC;AAEL,WAAO;AAAA,MACH,MAAM,QAAQ,SAAS;AACnB,cAAM,MAAM,MAAM,KAAK,UAAU,OAAO;AACxC,YAAI,IAAI,WAAW,OAAO,CAAC,IAAI,MAAM,QAAQ;AACzC,gBAAM,IAAI,MAAM,OAAO,IAAI,WAAW,yBAAyB,CAAC;AAAA,QACpE;AACA,eAAO,OAAO,IAAI,KAAK,MAAM;AAAA,MACjC;AAAA,MACA,SAAS,CAAC,QAAQ,KAAK,SAAS,KAAK,UAAU,QAAQ,KAAK,UAAU,GAAG,GAAG,IAAI;AAAA,MAChF,cAAc,CAAC,QAAQ,QAAQ,KAAK,eAAe,QAAQ,KAAK,UAAU,GAAG,CAAC;AAAA,MAC9E,KAAK,CAAC,QAAQ,OAAO,QAAQ,SAAS,KAAK,MAAM,QAAQ,OAAO,KAAK,UAAU,UAAU,CAAC,CAAC,GAAG,IAAI;AAAA,MAClG,OAAO,CAAC,WAAW,KAAK,QAAQ,MAAM;AAAA,MACtC,QAAQ,CAAC,QAAQ,SAAS,KAAK,SAAS,QAAQ,IAAI;AAAA,MACpD,UAAU,CAAC,QAAQ,SAAS,KAAK,WAAW,QAAQ,IAAI;AAAA,MACxD,MAAM,WAAW,QAAQ;AACrB,YAAI;AAAE,gBAAM,KAAK,aAAa,MAAM;AAAA,QAAG,QAAQ;AAAA,QAA2B;AAAA,MAC9E;AAAA,IACJ;AAAA,EACJ,QAAQ;AACJ,WAAO;AAAA,EACX;AACJ;AAEA,SAAS,cAAoC;AACzC,MAAI,QAAS,QAAO;AACpB,MAAI,WAAY,QAAO;AACvB,MAAI,QAAQ,IAAI,oBAAoB,OAAO,QAAQ,IAAI,oBAAoB,SAAS;AAChF,iBAAa;AACb,WAAO;AAAA,EACX;AACA,YAAU,gBAAgB,KAAK,iBAAiB;AAChD,MAAI,CAAC,QAAS,cAAa;AAC3B,SAAO;AACX;AAIO,IAAM,iBAAN,MAAqB;AAAA;AAAA,EAExB,OAAO,YAAqB;AACxB,WAAO,YAAY,MAAM;AAAA,EAC7B;AAAA,EAEA,aAAqB,UAAU,cAAsB,QAA8B;AAC/E,UAAM,WAAW,QAAQ,IAAI,YAAY;AACzC,QAAI,SAAU,QAAO;AAErB,UAAM,WAAW,WAAW,IAAI,YAAY;AAC5C,QAAI,SAAU,QAAO;AAErB,UAAM,WAAW,YAAY;AACzB,YAAM,KAAK,YAAY;AACvB,UAAI,CAAC,GAAI,OAAM,IAAI,MAAM,+BAA+B;AAExD,YAAM,QAAQ,OAAO,SAAS,aAAa,eAAe,OAAO;AACjE,YAAM,MAA+B;AAAA,QACjC,aAAa;AAAA,QACb;AAAA,QACA,UAAU,OAAO,SAAS,WAAW,GAAG,OAAO,OAAO,QAAQ,QAAQ,OAAO,OAAO;AAAA,QACpF,MAAM,OAAO,OAAO;AAAA,QACpB,MAAM,OAAO,OAAO,QAAQ,OAAO,OAAO,OAAO,OAAO,IAAI,IAAI;AAAA,QAChE,MAAM,OAAO,OAAO;AAAA,QACpB,UAAU,OAAO,OAAO;AAAA,QACxB,gBAAgB,OAAO,MAAM;AAAA,QAC7B,gBAAgB,OAAO,MAAM;AAAA,QAC7B,kBAAkB,OAAO,MAAM;AAAA,QAC/B,eAAe,OAAO,MAAM;AAAA,MAChC;AACA,YAAM,SAAS,MAAM,GAAG,QAAQ,KAAK,UAAU,GAAG,CAAC;AACnD,cAAQ,IAAI,cAAc,MAAM;AAChC,aAAO;AAAA,IACX,GAAG;AAEH,eAAW,IAAI,cAAc,OAAO;AACpC,QAAI;AACA,aAAO,MAAM;AAAA,IACjB,UAAE;AACE,iBAAW,OAAO,YAAY;AAAA,IAClC;AAAA,EACJ;AAAA,EAEA,aAAa,WAAW,cAAsB,QAAa,KAAa,MAAwC;AAC5G,UAAM,KAAK,YAAY;AACvB,UAAM,SAAS,MAAM,KAAK,UAAU,cAAc,MAAM;AACxD,WAAO,GAAG,QAAQ,QAAQ,KAAK,QAAQ,IAAI;AAAA,EAC/C;AAAA,EAEA,aAAa,aAAa,cAAsB,QAAa,KAAwC;AACjG,UAAM,KAAK,YAAY;AACvB,UAAM,SAAS,MAAM,KAAK,UAAU,cAAc,MAAM;AACxD,WAAO,GAAG,aAAa,QAAQ,GAAG;AAAA,EACtC;AAAA,EAEA,aAAa,SAAS,cAAsB,QAAa,OAAe,QAAe,MAAwC;AAC3H,UAAM,KAAK,YAAY;AACvB,UAAM,SAAS,MAAM,KAAK,UAAU,cAAc,MAAM;AACxD,WAAO,GAAG,IAAI,QAAQ,OAAO,UAAU,CAAC,GAAG,QAAQ,IAAI;AAAA,EAC3D;AAAA,EAEA,aAAa,MAAM,cAAsB,QAAsC;AAC3E,UAAM,KAAK,YAAY;AACvB,UAAM,SAAS,MAAM,KAAK,UAAU,cAAc,MAAM;AACxD,WAAO,GAAG,MAAM,MAAM;AAAA,EAC1B;AAAA,EAEA,aAAa,OAAO,cAAsB,QAAa,MAAuC;AAC1F,UAAM,KAAK,YAAY;AACvB,UAAM,SAAS,MAAM,KAAK,UAAU,cAAc,MAAM;AACxD,WAAO,GAAG,OAAO,QAAQ,IAAI;AAAA,EACjC;AAAA,EAEA,aAAa,SAAS,cAAsB,QAAa,MAAuC;AAC5F,UAAM,KAAK,YAAY;AACvB,UAAM,SAAS,MAAM,KAAK,UAAU,cAAc,MAAM;AACxD,WAAO,GAAG,SAAS,QAAQ,IAAI;AAAA,EACnC;AAAA,EAEA,aAAa,WAAW,cAAqC;AACzD,UAAM,KAAK,YAAY;AACvB,UAAM,SAAS,QAAQ,IAAI,YAAY;AACvC,QAAI,MAAM,QAAQ;AACd,cAAQ,OAAO,YAAY;AAC3B,YAAM,GAAG,WAAW,MAAM;AAAA,IAC9B;AAAA,EACJ;AACJ;;;AD5SA,IAAAC,iBAA8B;AAC9B,IAAAC,OAAqB;AACrB,IAAAC,wBAAoC;AAGpC,IAAM,mBAAmB,oBAAI,IAA4D;AAWzF,IAAM,cAAc,oBAAI,IAAwB;AAChD,IAAM,mBAAmB;AAGzB,IAAM,aAAa,oBAAI,IAAiB;AACxC,IAAM,iBAAiB;AAEvB,IAAM,cAAN,MAAkB;AAAA,EACN;AAAA,EACA;AAAA,EACA;AAAA,EACA,SAA4B;AAAA,EAC5B;AAAA,EACA;AAAA,EACA;AAAA,EAER,YAAY,MAAc,UAAU,KAAO,gBAAsB;AAC7D,SAAK,OAAO;AAIZ,SAAK,SAAS,kBAAkB,KAAK,UAAU,IAAI;AACnD,SAAK,YAAY,KAAK,aAAa;AAEnC,SAAK,UAAU,KAAK,QAAQ,QAAQ,oBAAoB;AACxD,SAAK,eAAe,GAAG,IAAI,iBAAiB,KAAK,OAAO,IAAI,IAAI,KAAK,OAAO,OAAO,QAAQ,IAAI,KAAK,OAAO,OAAO,QAAQ,WAAW;AACrI,SAAK,UAAU,KAAK,aAAa;AAAA,EACrC;AAAA,EAEQ,eAAuB;AAE3B,WAAO;AAAA,EACX;AAAA,EAEA,MAAc,kBAAkB,WAAoC;AAChE,aAAS,OAAO,WAAW,QAAQ,MAAM,QAAQ;AAC7C,UAAI,MAAM,KAAK,gBAAgB,IAAI,GAAG;AAClC,eAAO;AAAA,MACX;AAAA,IACJ;AACA,UAAM,IAAI,MAAM,6CAA6C;AAAA,EACjE;AAAA,EAEQ,gBAAgB,MAAgC;AACpD,WAAO,IAAI,QAAQ,CAACC,aAAY;AAC5B,YAAM,SAAa,kBAAa;AAEhC,aAAO,KAAK,SAAS,MAAMA,SAAQ,KAAK,CAAC;AACzC,aAAO,KAAK,aAAa,MAAM;AAC3B,eAAO,MAAM;AACb,QAAAA,SAAQ,IAAI;AAAA,MAChB,CAAC;AAED,aAAO,OAAO,MAAM,WAAW;AAAA,IACnC,CAAC;AAAA,EACL;AAAA,EAEA,MAAM,mBAAkC;AACpC,QAAI,CAAC,KAAK,QAAQ;AACd,WAAK,SAAS,MAAM,OAAO,IAAI;AAAA,IACnC;AAAA,EACJ;AAAA,EAEA,eAAe;AACX,QAAI,OAAO,CAAC;AACZ,QAAI,KAAK,OAAO,QAAQ,UAAU;AAC9B,aAAO;AAAA,QACH;AAAA,QAAQ,YAAY,KAAK;AAAA,QACzB;AAAA,QAAkB,KAAK;AAAA,QACvB;AAAA,QAAc,KAAK,OAAO,OAAO,WAAW;AAAA,QAC5C;AAAA,QAAW,KAAK,OAAO;AAAA,MAC3B;AAAA,IACJ,OAAO;AACH,aAAO;AAAA,QACH;AAAA,QAAQ,YAAY,KAAK;AAAA,QACzB;AAAA,QAAkB,KAAK;AAAA,QACvB;AAAA,QAAc,KAAK,OAAO,OAAO;AAAA,QACjC;AAAA,QAAU,KAAK,OAAO,OAAO;AAAA,QAC7B;AAAA,QAAU,OAAO,KAAK,OAAO,OAAO,IAAI;AAAA,QACxC;AAAA,QAAW,KAAK,OAAO;AAAA,MAC3B;AAEA,UAAI,KAAK,OAAO,OAAO,QAAQ,QAAQ,KAAK,OAAO,OAAO,SAAS,IAAI;AACnE,aAAK,KAAK,UAAU,KAAK,OAAO,OAAO,IAAI;AAAA,MAC/C;AACA,UAAI,KAAK,OAAO,OAAO,YAAY,QAAQ,KAAK,OAAO,OAAO,aAAa,IAAI;AAC3E,aAAK,KAAK,cAAc,KAAK,OAAO,OAAO,QAAQ;AAAA,MACvD;AAAA,IACJ;AAGA,UAAM,OAAO,KAAK,OAAO,QAAQ,CAAC;AAClC,QAAI,KAAK,kBAAkB,KAAM,MAAK,KAAK,qBAAqB,OAAO,KAAK,cAAc,CAAC;AAC3F,QAAI,KAAK,kBAAkB,KAAM,MAAK,KAAK,qBAAqB,OAAO,KAAK,cAAc,CAAC;AAC3F,QAAI,KAAK,oBAAoB,KAAM,MAAK,KAAK,wBAAwB,OAAO,KAAK,gBAAgB,CAAC;AAClG,QAAI,KAAK,iBAAiB,KAAM,MAAK,KAAK,qBAAqB,OAAO,KAAK,aAAa,CAAC;AAEzF,WAAO;AAAA,EACX;AAAA;AAAA,EAGQ,gBAAyB;AAC7B,UAAM,OAAO,QAAQ,IAAI;AACzB,QAAI,SAAS,OAAO,SAAS,QAAS,QAAO;AAC7C,WAAO,KAAK,QAAQ,QAAQ,YAAY;AAAA,EAC5C;AAAA,EAEA,UAAU,MAAc;AACpB,UAAM,iBAAiB,IAAI,OAAY;AAEvC,QAAI;AACA,YAAM,iBAAiB,aAAAC,QAAK,QAAQ,QAAQ,IAAI,GAAG,kBAAkB;AACrE,YAAM,aAAa,OAAO,eAAe,cAAc,aAAa,QAAQ,IAAI;AAChF,YAAMC,eAAU,8BAAc,UAAU;AAExC,UAAIA,SAAQ,SAASA,SAAQ,SAAS;AAClC,YAAI;AACA,iBAAOA,SAAQ,MAAMA,SAAQ,QAAQ,cAAc,CAAC;AAAA,QACxD,SAAS,GAAG;AAAA,QAEZ;AAAA,MACJ;AACA,YAAM,eAAeA,SAAQ,cAAc;AAC3C,YAAM,WAAW,aAAa,WAAW;AAEzC,UAAI,OAAO,aAAa,YAAY;AAChC,iBAAS,cAAc;AAAA,MAC3B,OAAO;AACH,gBAAQ,MAAM,+DAAuD;AAAA,MACzE;AAAA,IACJ,SAAS,OAAY;AACjB,cAAQ,MAAM,qCAAgC,MAAM,OAAO;AAC3D,UAAI,MAAM,SAAS,oBAAoB;AACnC,gBAAQ,MAAM,qEAAgE;AAAA,MAClF;AAAA,IACJ;AAEA,WAAO,eAAe,YAAY,IAAI;AAAA,EAC1C;AAAA,EAEA,YAAY;AACR,WAAO,KAAK;AAAA,EAChB;AAAA,EAEA,MAAM,IAAI,QAAgB,MAAyC;AAE/D,UAAM,cAAc,KAAK,UAAU,SAAO,QAAQ,UAAU;AAC5D,UAAM,kBAAkB,gBAAgB,MAAM,KAAK,cAAc,CAAC,MAAM;AACxE,UAAM,gBAAgB,WAAW;AAEjC,QAAI,iBAAiB,iBAAiB;AAElC,aAAO,KAAK,qBAAqB,KAAK,cAAc,IAAI,CAAC;AAAA,IAC7D,OAAO;AAEH,aAAO,KAAK,cAAc,QAAQ,IAAI;AAAA,IAC1C;AAAA,EACJ;AAAA,EAEQ,cAAc,MAAqC;AACvD,UAAM,UAA+B,CAAC;AACtC,aAAS,IAAI,GAAG,IAAI,KAAK,QAAQ,KAAK,GAAG;AACrC,UAAI,KAAK,CAAC,EAAE,WAAW,IAAI,GAAG;AAC1B,gBAAQ,KAAK,CAAC,EAAE,UAAU,CAAC,CAAC,IAAI,KAAK,IAAI,CAAC;AAAA,MAC9C;AAAA,IACJ;AACA,WAAO;AAAA,EACX;AAAA;AAAA;AAAA;AAAA,EAKQ,cAAuB;AAC3B,WAAO,eAAe,UAAU;AAAA,EACpC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,MAAM,WAAW,KAAa,MAAwC;AAClE,QAAI,KAAK,YAAY,GAAG;AACpB,aAAO,eAAe,WAAW,KAAK,cAAc,KAAK,QAAQ,KAAK,IAAI;AAAA,IAC9E;AAGA,UAAM,UAA+B,EAAE,QAAQ,WAAW,IAAI;AAC9D,QAAI,KAAM,SAAQ,QAAQ;AAC1B,WAAO,KAAK,qBAAqB,OAAO;AAAA,EAC5C;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,MAAM,aAAa,KAAwC;AACvD,QAAI,KAAK,YAAY,GAAG;AACpB,aAAO,eAAe,aAAa,KAAK,cAAc,KAAK,QAAQ,GAAG;AAAA,IAC1E;AAEA,UAAM,OAAO,MAAM,KAAK,iBAAiB;AACzC,QAAI;AACA,YAAM,UAAiB,CAAC;AACxB,iBAAW,MAAM,KAAK;AAClB,cAAM,MAAM,MAAM,KAAK,WAAW,IAAI,IAAI;AAC1C,YAAI,IAAI,WAAW,KAAK;AACpB,gBAAM,IAAI,MAAM,OAAO,IAAI,OAAO,CAAC;AAAA,QACvC;AACA,gBAAQ,KAAK,IAAI,IAAI;AAAA,MACzB;AACA,YAAM,KAAK,kBAAkB,IAAI;AACjC,aAAO,EAAE,QAAQ,KAAK,SAAS,mBAAmB,MAAM,QAAQ;AAAA,IACpE,SAAS,OAAY;AACjB,UAAI;AAAE,cAAM,KAAK,oBAAoB,IAAI;AAAA,MAAG,QAAQ;AAAA,MAAmB;AACvE,aAAO,EAAE,QAAQ,KAAK,SAAS,OAAO,WAAW,OAAO,KAAK,GAAG,MAAM,KAAK;AAAA,IAC/E;AAAA,EACJ;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,SAAS,OAAe,SAAgB,CAAC,GAAG,MAAwC;AACtF,QAAI,KAAK,YAAY,GAAG;AACpB,aAAO,eAAe,SAAS,KAAK,cAAc,KAAK,QAAQ,OAAO,QAAQ,IAAI;AAAA,IACtF;AACA,UAAM,UAA+B,EAAE,QAAQ,OAAO,OAAO,OAAO;AACpE,QAAI,KAAM,SAAQ,QAAQ;AAC1B,WAAO,KAAK,qBAAqB,OAAO;AAAA,EAC5C;AAAA;AAAA,EAGA,MAAM,mBAAoC;AACtC,UAAM,MAAM,KAAK,YAAY,IACvB,MAAM,eAAe,MAAM,KAAK,cAAc,KAAK,MAAM,IACzD,MAAM,KAAK,qBAAqB,EAAE,QAAQ,QAAQ,CAAC;AACzD,QAAI,IAAI,WAAW,OAAO,CAAC,IAAI,MAAM,OAAO;AACxC,YAAM,IAAI,MAAM,OAAO,IAAI,WAAW,iFAAiF,CAAC;AAAA,IAC5H;AACA,WAAO,IAAI,KAAK;AAAA,EACpB;AAAA,EAEA,MAAM,kBAAkB,MAA6B;AACjD,UAAM,MAAM,KAAK,YAAY,IACvB,MAAM,eAAe,OAAO,KAAK,cAAc,KAAK,QAAQ,IAAI,IAChE,MAAM,KAAK,qBAAqB,EAAE,QAAQ,UAAU,OAAO,KAAK,CAAC;AACvE,QAAI,IAAI,WAAW,IAAK,OAAM,IAAI,MAAM,OAAO,IAAI,WAAW,8BAA8B,CAAC;AAAA,EACjG;AAAA,EAEA,MAAM,oBAAoB,MAA6B;AACnD,UAAM,MAAM,KAAK,YAAY,IACvB,MAAM,eAAe,SAAS,KAAK,cAAc,KAAK,QAAQ,IAAI,IAClE,MAAM,KAAK,qBAAqB,EAAE,QAAQ,YAAY,OAAO,KAAK,CAAC;AACzE,QAAI,IAAI,WAAW,IAAK,OAAM,IAAI,MAAM,OAAO,IAAI,WAAW,gCAAgC,CAAC;AAAA,EACnG;AAAA,EAEA,MAAc,qBAAqB,SAAuD;AAGtF,QAAI,CAAC,KAAK,cAAc,GAAG;AACvB,UAAI,QAAQ,SAAS,CAAC,SAAS,UAAU,UAAU,EAAE,SAAS,QAAQ,MAAM,GAAG;AAC3E,cAAM,IAAI,MAAM,iHAAiH;AAAA,MACrI;AACA,YAAM,OAAiB,CAAC;AACxB,iBAAW,CAAC,KAAK,KAAK,KAAK,OAAO,QAAQ,OAAO,GAAG;AAChD,aAAK,KAAK,KAAK,IAAI,QAAQ,MAAM,GAAG,CAAC,IAAI,OAAO,UAAU,WAAW,QAAQ,KAAK,UAAU,KAAK,CAAC;AAAA,MACtG;AACA,aAAO,KAAK,cAAc,gBAAgB,IAAI;AAAA,IAClD;AAEA,UAAM,aAAa,iBAAiB,IAAI,KAAK,YAAY;AAGzD,QAAI,CAAC,cAAc,CAAC,WAAW,WAAW,WAAW,QAAQ,QAAQ;AACjE,YAAM,KAAK,eAAe;AAE1B,YAAM,KAAK,mBAAmB;AAAA,IAClC;AAEA,UAAM,OAAO,iBAAiB,IAAI,KAAK,YAAY,EAAG;AACtD,UAAM,SAAS,MAAM,KAAK,cAAc,IAAI;AAC5C,QAAI;AACA,YAAM,SAAS,MAAM,KAAK,oBAAoB,QAAQ,OAAO;AAC7D,WAAK,cAAc,QAAQ,KAAK;AAChC,aAAO;AAAA,IACX,SAAS,OAAO;AAGZ,WAAK,cAAc,QAAQ,IAAI;AAC/B,YAAM;AAAA,IACV;AAAA,EACJ;AAAA,EAEQ,UAAsB;AAC1B,QAAI,OAAO,YAAY,IAAI,KAAK,YAAY;AAC5C,QAAI,CAAC,MAAM;AACP,aAAO,EAAE,MAAM,CAAC,GAAG,OAAO,GAAG,SAAS,CAAC,EAAE;AACzC,kBAAY,IAAI,KAAK,cAAc,IAAI;AAAA,IAC3C;AACA,WAAO;AAAA,EACX;AAAA,EAEA,MAAc,cAAc,MAAmC;AAC3D,UAAM,OAAO,KAAK,QAAQ;AAG1B,WAAO,KAAK,KAAK,SAAS,GAAG;AACzB,YAAM,IAAI,KAAK,KAAK,IAAI;AACxB,UAAI,CAAC,EAAE,UAAW,QAAO;AACzB,WAAK;AAAA,IACT;AAEA,QAAI,KAAK,QAAQ,kBAAkB;AAC/B,WAAK;AACL,UAAI;AACA,eAAO,MAAM,KAAK,oBAAoB,IAAI;AAAA,MAC9C,SAAS,GAAG;AACR,aAAK;AACL,cAAM;AAAA,MACV;AAAA,IACJ;AAGA,WAAO,IAAI,QAAoB,CAAAF,aAAW,KAAK,QAAQ,KAAKA,QAAO,CAAC;AAAA,EACxE;AAAA,EAEQ,cAAc,QAAoB,QAAuB;AAC7D,UAAM,OAAO,YAAY,IAAI,KAAK,YAAY;AAC9C,QAAI,CAAC,MAAM;AAAE,aAAO,QAAQ;AAAG;AAAA,IAAQ;AAEvC,QAAI,UAAU,OAAO,WAAW;AAC5B,WAAK;AACL,UAAI;AAAE,eAAO,QAAQ;AAAA,MAAG,QAAQ;AAAA,MAAmB;AACnD;AAAA,IACJ;AAEA,UAAM,SAAS,KAAK,QAAQ,MAAM;AAClC,QAAI,QAAQ;AACR,aAAO,MAAM;AAAA,IACjB,OAAO;AACH,WAAK,KAAK,KAAK,MAAM;AAAA,IACzB;AAAA,EACJ;AAAA,EAEA,MAAc,qBAAoC;AAC9C,UAAM,aAAa;AACnB,UAAM,aAAa;AAEnB,UAAM,aAAa,iBAAiB,IAAI,KAAK,YAAY;AACzD,QAAI,CAAC,YAAY;AACb,YAAM,IAAI,MAAM,kBAAkB;AAAA,IACtC;AAEA,aAAS,IAAI,GAAG,IAAI,YAAY,KAAK;AACjC,UAAI,MAAM,KAAK,mBAAmB,WAAW,IAAI,GAAG;AAChD;AAAA,MACJ;AACA,YAAM,KAAK,MAAM,UAAU;AAAA,IAC/B;AACA,UAAM,IAAI,MAAM,kDAAkD;AAAA,EACtE;AAAA,EAEA,MAAc,mBAAmB,MAAgC;AAC7D,WAAO,IAAI,QAAQ,CAACA,aAAY;AAC5B,YAAM,SAAS,IAAQ,YAAO;AAC9B,YAAM,UAAU,WAAW,MAAM;AAC7B,eAAO,QAAQ;AACf,QAAAA,SAAQ,KAAK;AAAA,MACjB,GAAG,GAAI;AAEP,aAAO,QAAQ,MAAM,aAAa,MAAM;AACpC,qBAAa,OAAO;AACpB,eAAO,QAAQ;AACf,QAAAA,SAAQ,IAAI;AAAA,MAChB,CAAC;AAED,aAAO,GAAG,SAAS,MAAM;AACrB,qBAAa,OAAO;AACpB,QAAAA,SAAQ,KAAK;AAAA,MACjB,CAAC;AAAA,IACL,CAAC;AAAA,EACL;AAAA,EAEQ,MAAM,IAA2B;AACrC,WAAO,IAAI,QAAQ,CAAAA,aAAW,WAAWA,UAAS,EAAE,CAAC;AAAA,EACzD;AAAA,EAEQ,aAAa,SAAsB;AAEvC,QAAI,WAAW,IAAI,OAAO,GAAG;AACzB,aAAO,WAAW,IAAI,OAAO;AAAA,IACjC;AAIA,UAAM,SAAS,KAAK,MAAM,OAAO;AAEjC,QAAI,WAAW,QAAQ,gBAAgB;AACnC,YAAM,SAAS,WAAW,KAAK,EAAE,KAAK,EAAE;AACxC,UAAI,WAAW,OAAW,YAAW,OAAO,MAAM;AAAA,IACtD;AACA,eAAW,IAAI,SAAS,MAAM;AAE9B,WAAO;AAAA,EACX;AAAA,EAEA,MAAc,iBAAgC;AAC1C,UAAM,KAAK,iBAAiB;AAE5B,QAAI,CAAC,KAAK,QAAQ;AACd,YAAM,IAAI,MAAM,wBAAwB;AAAA,IAC5C;AAGA,SAAK,UAAU,MAAM,KAAK,kBAAkB,KAAK,OAAO;AAExD,WAAO,IAAI,QAAQ,CAACA,UAAS,WAAW;AAEpC,YAAM,aAAa,CAAC,GAAG,KAAK,WAAW,YAAY,UAAU,cAAc,KAAK,QAAQ,SAAS,CAAC;AAClG,YAAM,oBAAgB,6BAAM,KAAK,OAAQ,cAAkC,GAAG,UAAU;AAExF,UAAI,UAAU;AAEd,YAAM,UAAU,WAAW,MAAM;AAC7B,YAAI,CAAC,SAAS;AACV,wBAAc,KAAK;AACnB,iBAAO,IAAI,MAAM,4BAA4B,CAAC;AAAA,QAClD;AAAA,MACJ,GAAG,IAAK;AAER,oBAAc,OAAO,GAAG,QAAQ,CAAC,SAAS;AACtC,cAAM,SAAS,KAAK,SAAS;AAE7B,YAAI,OAAO,SAAS,yBAAyB,GAAG;AAC5C,cAAI,CAAC,SAAS;AACV,sBAAU;AACV,yBAAa,OAAO;AACpB,6BAAiB,IAAI,KAAK,cAAc;AAAA,cACpC,MAAM,KAAK;AAAA,cACX,SAAS;AAAA,YACb,CAAC;AACD,YAAAA,SAAQ;AAAA,UACZ;AAAA,QACJ;AAAA,MACJ,CAAC;AAED,oBAAc,OAAO,GAAG,QAAQ,CAAC,SAAS;AACtC,gBAAQ,MAAM,mCAAmC,KAAK,SAAS,EAAE,KAAK,CAAC,EAAE;AAAA,MAC7E,CAAC;AAED,oBAAc,GAAG,SAAS,CAAC,SAAS;AAChC,yBAAiB,OAAO,KAAK,YAAY;AAAA,MAC7C,CAAC;AAED,oBAAc,GAAG,SAAS,CAAC,UAAU;AACjC,YAAI,CAAC,SAAS;AACV,uBAAa,OAAO;AACpB,iBAAO,KAAK;AAAA,QAChB;AAAA,MACJ,CAAC;AAAA,IACL,CAAC;AAAA,EACL;AAAA,EAEA,MAAc,oBAAoB,MAAmC;AACjE,WAAO,IAAI,QAAQ,CAACA,UAAS,WAAW;AACpC,YAAM,SAAS,IAAQ,YAAO;AAC9B,aAAO,WAAW,IAAI;AACtB,aAAO,aAAa,MAAM,GAAK;AAE/B,YAAM,UAAU,WAAW,MAAM;AAC7B,eAAO,QAAQ;AACf,eAAO,IAAI,MAAM,oBAAoB,CAAC;AAAA,MAC1C,GAAG,GAAI;AAEP,aAAO,QAAQ,MAAM,aAAa,MAAM;AACpC,qBAAa,OAAO;AACpB,QAAAA,SAAQ,MAAM;AAAA,MAClB,CAAC;AAED,aAAO,GAAG,SAAS,CAAC,UAAU;AAC1B,qBAAa,OAAO;AACpB,eAAO,KAAK;AAAA,MAChB,CAAC;AAAA,IACL,CAAC;AAAA,EACL;AAAA,EAEA,MAAc,oBAAoB,YAAwB,SAAuD;AAC7G,WAAO,IAAI,QAAQ,CAACA,UAAS,WAAW;AACpC,UAAI,iBAAiB;AACrB,UAAI,aAAa;AAEjB,YAAM,UAAU,WAAW,MAAM;AAC7B,YAAI,CAAC,YAAY;AACb,uBAAa;AACb,qBAAW,eAAe,QAAQ,MAAM;AACxC,qBAAW,eAAe,SAAS,OAAO;AAC1C,iBAAO,IAAI,MAAM,iBAAiB,CAAC;AAAA,QACvC;AAAA,MACJ,GAAG,KAAK,OAAO;AAEf,YAAM,SAAS,CAAC,SAAiB;AAC7B,0BAAkB,KAAK,SAAS;AAKhC,YAAI;AACJ,gBAAQ,MAAM,eAAe,QAAQ,IAAI,OAAO,MAAM,CAAC,YAAY;AAC/D,gBAAM,OAAO,eAAe,MAAM,GAAG,GAAG;AACxC,2BAAiB,eAAe,MAAM,MAAM,CAAC;AAC7C,gBAAM,SAAS,KAAK,QAAQ,mBAAmB;AAC/C,cAAI,WAAW,GAAI;AACnB,uBAAa;AACb,uBAAa,OAAO;AACpB,qBAAW,eAAe,QAAQ,MAAM;AACxC,qBAAW,eAAe,SAAS,OAAO;AAE1C,cAAI;AACA,kBAAM,WAA4B,KAAK,MAAM,KAAK,MAAM,SAAS,oBAAoB,MAAM,CAAC;AAC5F,YAAAA,SAAQ;AAAA,cACJ,QAAQ,SAAS;AAAA,cACjB,SAAS,SAAS;AAAA,cAClB,MAAM,SAAS;AAAA,YACnB,CAAC;AAAA,UACL,SAAS,OAAO;AACZ,mBAAO,IAAI,MAAM,0BAA0B,CAAC;AAAA,UAChD;AAAA,QACJ;AAAA,MACJ;AAEA,YAAM,UAAU,CAAC,UAAiB;AAC9B,YAAI,CAAC,YAAY;AACb,uBAAa;AACb,uBAAa,OAAO;AACpB,qBAAW,eAAe,QAAQ,MAAM;AACxC,qBAAW,eAAe,SAAS,OAAO;AAC1C,iBAAO,KAAK;AAAA,QAChB;AAAA,MACJ;AAEA,iBAAW,GAAG,QAAQ,MAAM;AAC5B,iBAAW,GAAG,SAAS,OAAO;AAG9B,iBAAW,MAAM,KAAK,UAAU,OAAO,IAAI,IAAI;AAAA,IACnD,CAAC;AAAA,EACL;AAAA,EAEA,MAAc,cAAc,QAAgB,MAAyC;AACjF,UAAM,KAAK,iBAAiB;AAE5B,QAAI,CAAC,KAAK,QAAQ;AACd,YAAM,IAAI,MAAM,wBAAwB;AAAA,IAC5C;AAEA,WAAO,IAAI,QAAwB,CAACA,UAAS,WAAW;AACpD,YAAM,YAAQ,6BAAM,KAAK,OAAQ,MAA0B,GAAG,CAAC,GAAG,KAAK,WAAW,GAAG,IAAI,CAAC;AAE1F,UAAI,eAAe;AACnB,UAAI,eAAe;AACnB,UAAI,aAAa;AAEjB,YAAM,YAAY,WAAW,MAAM;AAC/B,YAAI,CAAC,YAAY;AACb,uBAAa;AACb,gBAAM,KAAK;AACX,iBAAO,IAAI,MAAM,iBAAiB,CAAC;AAAA,QACvC;AAAA,MACJ,GAAG,KAAK,OAAO;AAEf,YAAM,cAAc,CAAC,aAA6B;AAC9C,YAAI,CAAC,YAAY;AACb,uBAAa;AACb,uBAAa,SAAS;AACtB,UAAAA,SAAQ,QAAQ;AAAA,QACpB;AAAA,MACJ;AAIA,YAAM,gBAAgB,CAAC,WAA2B;AAC9C,YAAI;AACJ,gBAAQ,MAAM,OAAO,QAAQ,IAAI,OAAO,IAAI;AACxC,gBAAM,OAAO,OAAO,MAAM,GAAG,GAAG;AAChC,mBAAS,OAAO,MAAM,MAAM,CAAC;AAC7B,gBAAM,SAAS,KAAK,QAAQ,mBAAmB;AAC/C,cAAI,WAAW,GAAI;AACnB,cAAI;AACA,kBAAM,WAA4B,KAAK,MAAM,KAAK,MAAM,SAAS,oBAAoB,MAAM,CAAC;AAC5F,wBAAY;AAAA,cACR,QAAQ,SAAS;AAAA,cACjB,SAAS,SAAS;AAAA,cAClB,MAAM,SAAS;AAAA,YACnB,CAAC;AAAA,UACL,SAAS,OAAO;AACZ,wBAAY;AAAA,cACR,QAAQ;AAAA,cACR,SAAS;AAAA,cACT,MAAM;AAAA,YACV,CAAC;AAAA,UACL;AAAA,QACJ;AACA,eAAO;AAAA,MACX;AAEA,YAAM,OAAO,GAAG,QAAQ,CAAC,SAAS;AAC9B,uBAAe,cAAc,eAAe,KAAK,SAAS,CAAC;AAAA,MAC/D,CAAC;AAED,YAAM,OAAO,GAAG,QAAQ,CAAC,SAAS;AAC9B,uBAAe,cAAc,eAAe,KAAK,SAAS,CAAC;AAAA,MAC/D,CAAC;AAED,YAAM,GAAG,SAAS,CAAC,SAAS;AACxB,qBAAa,SAAS;AACtB,YAAI,CAAC,YAAY;AACb,sBAAY;AAAA,YACR,QAAQ,SAAS,IAAI,MAAM;AAAA,YAC3B,SAAS,SAAS,IAAI,sBAAsB,4BAA4B,IAAI;AAAA,YAC5E,MAAM;AAAA,UACV,CAAC;AAAA,QACL;AAAA,MACJ,CAAC;AAED,YAAM,GAAG,SAAS,CAAC,UAAU;AACzB,qBAAa,SAAS;AACtB,YAAI,CAAC,YAAY;AACb,sBAAY;AAAA,YACR,QAAQ;AAAA,YACR,SAAS,kBAAkB,MAAM,OAAO;AAAA,YACxC,MAAM;AAAA,UACV,CAAC;AAAA,QACL;AAAA,MACJ,CAAC;AAED,YAAM,MAAM;AAAA,IAChB,CAAC;AAAA,EACL;AAAA,EAEA,MAAM,aAAsC;AAExC,UAAM,eAAe,WAAW,KAAK,YAAY;AAGjD,UAAM,OAAO,YAAY,IAAI,KAAK,YAAY;AAC9C,QAAI,MAAM;AACN,iBAAW,KAAK,KAAK,MAAM;AACvB,YAAI;AAAE,YAAE,QAAQ;AAAA,QAAG,QAAQ;AAAA,QAAmB;AAAA,MAClD;AACA,kBAAY,OAAO,KAAK,YAAY;AAAA,IACxC;AAEA,UAAM,aAAa,iBAAiB,IAAI,KAAK,YAAY;AAEzD,QAAI,cAAc,WAAW,WAAW,CAAC,WAAW,QAAQ,QAAQ;AAChE,iBAAW,QAAQ,KAAK;AACxB,uBAAiB,OAAO,KAAK,YAAY;AAEzC,aAAO;AAAA,QACH,QAAQ;AAAA,QACR,SAAS;AAAA,QACT,MAAM;AAAA,MACV;AAAA,IACJ;AAEA,WAAO;AAAA,MACH,QAAQ;AAAA,MACR,SAAS;AAAA,MACT,MAAM;AAAA,IACV;AAAA,EACJ;AACJ;;;AErrBA,IAAAG,QAAsB;AACtB,IAAAC,aAAe;AAEf,IAAM,WAAgB,cAAQ,QAAQ,IAAI,GAAG,SAAS;AA2BtD,IAAM,SAAN,MAAa;AAAA,EACD;AAAA,EACA,SAA6B;AAAA,EAErC,YAAY,QAAwB;AAChC,SAAK,WAAW,OAAO,YAAY;AAAA,EACvC;AAAA;AAAA,EAGQ,aAAqB;AACzB,WAAY,WAAK,UAAU,KAAK,WAAW,KAAK;AAAA,EACpD;AAAA;AAAA;AAAA;AAAA,EAKQ,YAAyB;AAC7B,QAAI,CAAC,KAAK,QAAQ;AACd,YAAM,aAAkB,WAAK,WAAW,KAAK,QAAQ,EAAE,QAAQ,OAAO,GAAG;AACzE,WAAK,SAAS,IAAI,YAAY,mBAAmB,KAAK,QAAQ,IAAI,KAAO;AAAA,QACrE,MAAM;AAAA,QACN,QAAQ,EAAE,UAAU,WAAW;AAAA,MACnC,CAAC;AAAA,IACL;AACA,WAAO,KAAK;AAAA,EAChB;AAAA,EAEA,MAAM,UAA4B;AAE9B,QAAI,CAAC,WAAAC,QAAG,WAAW,QAAQ,GAAG;AAC1B,iBAAAA,QAAG,UAAU,UAAU,EAAE,WAAW,KAAK,CAAC;AAAA,IAC9C;AACA,WAAO,WAAAA,QAAG,WAAW,KAAK,WAAW,CAAC;AAAA,EAC1C;AAAA,EAEA,MAAM,UAAgC;AAClC,QAAI,CAAC,WAAAA,QAAG,WAAW,QAAQ,GAAG;AAC1B,iBAAAA,QAAG,UAAU,UAAU,EAAE,WAAW,KAAK,CAAC;AAAA,IAC9C;AACA,WAAO,KAAK,UAAU;AAAA,EAC1B;AAAA,EAEA,MAAM,aAA4B;AAAA,EAGlC;AAAA,EAEA,MAAM,MAAM,UAAwC;AAChD,WAAO,KAAK,oBAAoB,UAAU,CAAC,CAAC;AAAA,EAChD;AAAA,EAEA,MAAM,oBAAoB,UAAkB,SAAgB,CAAC,GAAyB;AAClF,QAAI;AACA,UAAI,OAAO,aAAa,UAAU;AAC9B,cAAM,IAAI,MAAM,iCAAiC;AAAA,MACrD;AACA,UAAI,CAAC,MAAM,QAAQ,MAAM,GAAG;AACxB,cAAM,IAAI,MAAM,8BAA8B;AAAA,MAClD;AAEA,YAAM,WAAW,MAAM,KAAK,UAAU,EAAE,SAAS,UAAU,MAAM;AAEjE,UAAI,SAAS,WAAW,KAAK;AACzB,eAAO,EAAE,QAAQ,SAAS,SAAS,SAAS,WAAW,gBAAgB,MAAM,KAAK;AAAA,MACtF;AACA,aAAO,EAAE,QAAQ,WAAW,SAAS,+BAA+B,MAAM,SAAS,KAAK;AAAA,IAC5F,SAAS,OAAO;AACZ,aAAO;AAAA,QACH,QAAQ;AAAA,QACR,SAAU,MAAgB,WAAW;AAAA,QACrC,MAAM;AAAA,MACV;AAAA,IACJ;AAAA,EACJ;AAAA,EAEA,4BAA4B,KAAsC;AAC9D,UAAM,gBAAgB,IAAI,QAAQ,QAAQ,GAAG,EAAE,KAAK;AAEpD,UAAM,iBAAiB,cAAc,MAAM,uBAAuB;AAClE,QAAI,CAAC,gBAAgB;AACjB,YAAM,IAAI,MAAM,0DAA0D;AAAA,IAC9E;AAEA,UAAM,YAAY,eAAe,CAAC;AAElC,UAAM,mBAAmB,cAAc,YAAY,EAAE,QAAQ,QAAQ;AACrE,UAAM,gBAAgB,cAAc,UAAU,gBAAgB;AAC9D,UAAM,cAAc,cAAc,MAAM,6BAA6B;AACrE,QAAI,CAAC,aAAa;AACd,YAAM,IAAI,MAAM,mDAAmD;AAAA,IACvE;AAEA,UAAM,eAAe,YAAY,CAAC;AAElC,aAAS,YAAY,KAAoB;AACrC,YAAM,SAAgB,CAAC;AACvB,UAAI,eAAe;AACnB,UAAI,WAAW;AACf,UAAI,YAAY;AAChB,UAAI,YAAY;AAChB,UAAI,eAAe;AAEnB,eAAS,IAAI,GAAG,IAAI,IAAI,QAAQ,KAAK;AACjC,cAAM,OAAO,IAAI,CAAC;AAClB,cAAM,WAAW,IAAI,IAAI,CAAC;AAE1B,YAAI,CAAC,YAAY,IAAI,UAAU,GAAG,IAAI,CAAC,MAAM,YAAY;AACrD,sBAAY;AAAA,QAChB;AAEA,YAAI,aAAa,SAAS,KAAK;AAC3B;AAAA,QACJ,WAAW,aAAa,SAAS,KAAK;AAClC;AACA,cAAI,iBAAiB,GAAG;AACpB,wBAAY;AAAA,UAChB;AAAA,QACJ;AAEA,YAAI,CAAC,cAAc,SAAS,OAAO,SAAS,QAAQ,aAAa,MAAM;AACnE,cAAI,CAAC,UAAU;AACX,uBAAW;AACX,wBAAY;AAAA,UAChB,WAAW,SAAS,WAAW;AAC3B,gBAAI,IAAI,IAAI,CAAC,MAAM,WAAW;AAC1B,8BAAgB,OAAO;AACvB;AACA;AAAA,YACJ,OAAO;AACH,yBAAW;AACX,0BAAY;AAAA,YAChB;AAAA,UACJ;AAAA,QACJ;AAEA,YAAI,CAAC,YAAY,CAAC,aAAa,SAAS,KAAK;AACzC,iBAAO,KAAK,WAAW,aAAa,KAAK,CAAC,CAAC;AAC3C,yBAAe;AACf;AAAA,QACJ;AAEA,wBAAgB;AAAA,MACpB;AAEA,UAAI,aAAa,KAAK,GAAG;AACrB,eAAO,KAAK,WAAW,aAAa,KAAK,CAAC,CAAC;AAAA,MAC/C;AAEA,aAAO;AAAA,IACX;AAEA,aAAS,WAAW,OAAoB;AACpC,cAAQ,MAAM,KAAK;AAEnB,UAAI,MAAM,WAAW,UAAU,GAAG;AAC9B,eAAO;AAAA,MACX;AAEA,UAAK,MAAM,WAAW,GAAG,KAAK,MAAM,SAAS,GAAG,KAC3C,MAAM,WAAW,GAAG,KAAK,MAAM,SAAS,GAAG,GAAI;AAChD,gBAAQ,MAAM,MAAM,GAAG,EAAE;AACzB,gBAAQ,MAAM,QAAQ,OAAO,GAAG,EAAE,QAAQ,OAAO,GAAG;AAAA,MACxD;AAEA,aAAO;AAAA,IACX;AAEA,UAAM,aAAa,YAAY,YAAY;AAC3C,UAAM,eAAe,WAAW,IAAI,MAAM,GAAG,EAAE,KAAK,IAAI;AACxD,UAAM,oBAAoB,GAAG,SAAS,YAAY,YAAY;AAE9D,WAAO;AAAA,MACH,OAAO;AAAA,MACP;AAAA,IACJ;AAAA,EACJ;AACJ;AAEO,IAAM,WAAW,IAAI,OAAO,EAAC,UAAU,SAAQ,CAAC;AACvD,IAAO,mBAAQ;;;AClNf,IAAAC,MAAoB;AACpB,IAAAC,QAAsB;AACtB,oBAA6B;AA4CtB,IAAM,aAAN,MAAM,oBAAmB,2BAAa;AAAA,EACzC,OAAe,WAAW,oBAAI,IAAsD;AAAA;AAAA,EACpF,OAAe,UAAU,oBAAI,IAAsB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASnD,aAAa,MAAM,UAAkB,SAAiB,QAAkB,QAAQ,SAAkB,MAAwB;AACtH,QAAI;AAEA,YAAM,MAAW,cAAQ,QAAQ;AACjC,UAAI,CAAI,eAAW,GAAG,GAAG;AACrB,QAAG,cAAU,KAAK,EAAE,WAAW,KAAK,CAAC;AAAA,MACzC;AAGA,YAAM,aAAY,oBAAI,KAAK,GAAE,YAAY;AACzC,YAAM,mBAAmB,IAAI,SAAS,MAAM,KAAK,KAAK,OAAO;AAAA;AAG7D,UAAI,YAAW,QAAQ,IAAI,QAAQ,GAAG;AAClC,oBAAW,QAAQ,IAAI,QAAQ,EAAG,KAAK,gBAAgB;AACvD,eAAO;AAAA,MACX;AAGA,UAAI,QAAQ;AACR,cAAS,aAAS,WAAW,UAAU,kBAAkB,MAAM;AAAA,MACnE,OAAO;AACH,cAAS,aAAS,UAAU,UAAU,kBAAkB,MAAM;AAAA,MAClE;AAEA,aAAO;AAAA,IACX,SAAS,OAAO;AACZ,cAAQ,MAAM,0BAA0B,KAAK;AAC7C,YAAM;AAAA,IACV;AAAA,EACJ;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,OAAO,YAAY,UAAwB;AACvC,QAAI,CAAC,YAAW,QAAQ,IAAI,QAAQ,GAAG;AACnC,kBAAW,QAAQ,IAAI,UAAU,CAAC,CAAC;AAAA,IACvC;AAAA,EACJ;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,aAAa,aAAa,UAAoC;AAC1D,UAAM,SAAS,YAAW,QAAQ,IAAI,QAAQ;AAC9C,QAAI,UAAU,OAAO,SAAS,GAAG;AAC7B,UAAI;AAEA,cAAM,MAAW,cAAQ,QAAQ;AACjC,YAAI,CAAI,eAAW,GAAG,GAAG;AACrB,UAAG,cAAU,KAAK,EAAE,WAAW,KAAK,CAAC;AAAA,QACzC;AAGA,cAAM,UAAU,OAAO,KAAK,EAAE;AAC9B,cAAS,aAAS,WAAW,UAAU,SAAS,MAAM;AAGtD,oBAAW,QAAQ,OAAO,QAAQ;AAClC,eAAO;AAAA,MACX,SAAS,OAAO;AACZ,gBAAQ,MAAM,6BAA6B,KAAK;AAChD,cAAM;AAAA,MACV;AAAA,IACJ;AAGA,gBAAW,QAAQ,OAAO,QAAQ;AAClC,WAAO;AAAA,EACX;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,OAAO,cAAc,UAA0B;AAC3C,QAAI,YAAW,QAAQ,IAAI,QAAQ,GAAG;AAClC,YAAM,iBAAiB,YAAW,QAAQ,IAAI,QAAQ,EAAG;AACzD,kBAAW,QAAQ,OAAO,QAAQ;AAClC,aAAO;AAAA,IACX;AACA,WAAO;AAAA,EACX;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,OAAO,UAAU,UAA2B;AACxC,WAAO,YAAW,QAAQ,IAAI,QAAQ;AAAA,EAC1C;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,OAAO,cAAc,UAA0B;AAC3C,UAAM,SAAS,YAAW,QAAQ,IAAI,QAAQ;AAC9C,WAAO,SAAS,OAAO,SAAS;AAAA,EACpC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,OAAO,iBAAiB,UAAkB,UAA4B,CAAC,GAAwB;AAC3F,UAAM;AAAA,MACF,eAAe;AAAA,MACf,iBAAiB;AAAA,MACjB,gBAAgB;AAAA,MAChB,eAAe;AAAA;AAAA,MACf,YAAY;AAAA;AAAA,IAChB,IAAI;AAGJ,QAAI,WAAW;AACX,kBAAW,YAAY,QAAQ;AAAA,IACnC;AAGA,UAAM,cAAc,QAAQ;AAC5B,UAAM,gBAAgB,QAAQ;AAC9B,UAAM,eAAe,QAAQ;AAE7B,QAAI,cAAc;AACd,cAAQ,MAAM,YAAY,MAAa;AACnC,cAAM,UAAU,KAAK;AAAA,UAAI,SACrB,OAAO,QAAQ,WAAW,KAAK,UAAU,GAAG,IAAI,OAAO,GAAG;AAAA,QAC9D,EAAE,KAAK,GAAG;AAEV,oBAAW,MAAM,UAAU,SAAS,MAAM,EAAE,MAAM,SAAO;AACrD,wBAAc,0BAA0B,GAAG;AAAA,QAC/C,CAAC;AAED,YAAI,cAAc;AACd,sBAAY,MAAM,SAAS,IAAI;AAAA,QACnC;AAAA,MACJ;AAAA,IACJ;AAEA,QAAI,gBAAgB;AAChB,cAAQ,QAAQ,YAAY,MAAa;AACrC,cAAM,UAAU,KAAK;AAAA,UAAI,SACrB,OAAO,QAAQ,WAAW,KAAK,UAAU,GAAG,IAAI,OAAO,GAAG;AAAA,QAC9D,EAAE,KAAK,GAAG;AAEV,oBAAW,MAAM,UAAU,SAAS,OAAO,EAAE,MAAM,SAAO;AACtD,wBAAc,gCAAgC,GAAG;AAAA,QACrD,CAAC;AAED,YAAI,cAAc;AACd,wBAAc,MAAM,SAAS,IAAI;AAAA,QACrC;AAAA,MACJ;AAAA,IACJ;AAEA,QAAI,eAAe;AACf,cAAQ,OAAO,YAAY,MAAa;AACpC,cAAM,UAAU,KAAK;AAAA,UAAI,SACrB,OAAO,QAAQ,WAAW,KAAK,UAAU,GAAG,IAAI,OAAO,GAAG;AAAA,QAC9D,EAAE,KAAK,GAAG;AAEV,oBAAW,MAAM,UAAU,SAAS,MAAM,EAAE,MAAM,SAAO;AACrD,wBAAc,+BAA+B,GAAG;AAAA,QACpD,CAAC;AAED,YAAI,cAAc;AACd,uBAAa,MAAM,SAAS,IAAI;AAAA,QACpC;AAAA,MACJ;AAAA,IACJ;AAGA,WAAO;AAAA,MACH,SAAS,MAAM;AACX,YAAI,aAAc,SAAQ,MAAM;AAChC,YAAI,eAAgB,SAAQ,QAAQ;AACpC,YAAI,cAAe,SAAQ,OAAO;AAAA,MACtC;AAAA,MACA,QAAQ,YAAY;AAChB,YAAI,WAAW;AACX,iBAAO,MAAM,YAAW,aAAa,QAAQ;AAAA,QACjD;AACA,eAAO;AAAA,MACX;AAAA,MACA,SAAS,MAAM;AACX,YAAI,WAAW;AACX,iBAAO,YAAW,cAAc,QAAQ;AAAA,QAC5C;AACA,eAAO;AAAA,MACX;AAAA,MACA,WAAW,MAAM,YAAW,UAAU,QAAQ;AAAA,MAC9C,eAAe,MAAM,YAAW,cAAc,QAAQ;AAAA,IAC1D;AAAA,EACJ;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,aAAa,KAAK,UAAkB,UAAuB,CAAC,GAA+B;AACvF,UAAM;AAAA,MACF,QAAQ;AAAA;AAAA,MACR,UAAU;AAAA;AAAA,MACV,UAAU;AAAA;AAAA,IACd,IAAI;AAEJ,QAAI;AACA,UAAI,CAAI,eAAW,QAAQ,GAAG;AAC1B,eAAO,UAAU,CAAC,IAAI;AAAA,MAC1B;AAEA,UAAI,UAAU,MAAS,aAAS,SAAS,UAAU,MAAM;AAEzD,UAAI,SAAS;AACT,YAAI,aAAa,QAAQ,MAAM,IAAI,EAAE,OAAO,UAAQ,KAAK,KAAK,MAAM,EAAE;AAEtE,YAAI,UAAU,MAAM;AAChB,cAAI,SAAS;AACT,yBAAa,WAAW,MAAM,CAAC,KAAK;AAAA,UACxC,OAAO;AACH,yBAAa,WAAW,MAAM,GAAG,KAAK;AAAA,UAC1C;AAAA,QACJ;AAEA,eAAO;AAAA,MACX;AAGA,UAAI,UAAU,MAAM;AAChB,YAAI,aAAa,QAAQ,MAAM,IAAI,EAAE,OAAO,UAAQ,KAAK,KAAK,MAAM,EAAE;AACtE,YAAI,SAAS;AACT,uBAAa,WAAW,MAAM,CAAC,KAAK;AAAA,QACxC,OAAO;AACH,uBAAa,WAAW,MAAM,GAAG,KAAK;AAAA,QAC1C;AACA,kBAAU,WAAW,KAAK,IAAI;AAAA,MAClC;AAEA,aAAO;AAAA,IACX,SAAS,OAAO;AACZ,cAAQ,MAAM,sBAAsB,KAAK;AACzC,YAAM;AAAA,IACV;AAAA,EACJ;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASA,OAAO,MAAM,UAAkB,UAAoD,UAAwB,CAAC,GAAoB;AAC5H,UAAM;AAAA,MACF,aAAa;AAAA,MACb,WAAW;AAAA,MACX,UAAU;AAAA;AAAA,IACd,IAAI;AAEJ,QAAI,WAAW;AACf,QAAI,eAAe;AAGnB,QAAO,eAAW,QAAQ,GAAG;AACzB,YAAM,QAAW,aAAS,QAAQ;AAClC,iBAAW,MAAM;AACjB,qBAAe,UAAU,MAAM,OAAO;AAAA,IAC1C;AAGA,UAAM,WAAW,OAAO,MAAgB,SAAmB;AACvD,UAAI;AACA,YAAI,KAAK,OAAO,UAAU;AAEtB,gBAAM,SAAY,qBAAiB,UAAU;AAAA,YACzC,OAAO;AAAA,YACP,KAAK,KAAK,OAAO;AAAA,YACjB,UAAU;AAAA,UACd,CAAC;AAED,cAAI,SAAS;AAEb,iBAAO,GAAG,QAAQ,CAAC,UAAU;AACzB,sBAAU;AACV,kBAAM,QAAQ,OAAO,MAAM,IAAI;AAG/B,qBAAS,IAAI,GAAG,IAAI,MAAM,SAAS,GAAG,KAAK;AACvC,kBAAI,MAAM,CAAC,EAAE,KAAK,GAAG;AACjB,yBAAS,MAAM,CAAC,EAAE,KAAK,GAAG,QAAQ;AAAA,cACtC;AAAA,YACJ;AAGA,qBAAS,MAAM,MAAM,SAAS,CAAC;AAAA,UACnC,CAAC;AAED,iBAAO,GAAG,OAAO,MAAM;AAEnB,gBAAI,OAAO,KAAK,GAAG;AACf,uBAAS,OAAO,KAAK,GAAG,QAAQ;AAAA,YACpC;AAAA,UACJ,CAAC;AAED,qBAAW,KAAK;AAChB,yBAAe,KAAK;AAAA,QACxB;AAAA,MACJ,SAAS,OAAO;AACZ,gBAAQ,MAAM,qBAAqB,KAAK;AAAA,MAC5C;AAAA,IACJ;AAGA,IAAG,cAAU,UAAU,EAAE,YAAY,SAAS,GAAG,QAAQ;AAGzD,UAAM,YAAY,GAAG,QAAQ,IAAI,KAAK,IAAI,CAAC;AAE3C,gBAAW,SAAS,IAAI,WAAW,QAAe;AAGlD,WAAO;AAAA,MACH,IAAI;AAAA,MACJ,MAAM,MAAM;AACR,cAAM,iBAAiB,YAAW,SAAS,IAAI,SAAS;AACxD,YAAI,gBAAgB;AAChB,UAAG,gBAAY,UAAU,cAAc;AACvC,sBAAW,SAAS,OAAO,SAAS;AAAA,QACxC;AAAA,MACJ;AAAA,MACA,YAAY,MAAM,YAAW,SAAS,IAAI,SAAS;AAAA,IACvD;AAAA,EACJ;AAAA;AAAA;AAAA;AAAA,EAKA,OAAO,kBAAwB;AAC3B,eAAW,CAAC,SAAS,KAAK,YAAW,UAAU;AAC3C,YAAM,WAAW,UAAU,MAAM,GAAG,EAAE,CAAC;AACvC,MAAG,gBAAY,QAAQ;AAAA,IAC3B;AACA,gBAAW,SAAS,MAAM;AAAA,EAC9B;AAAA;AAAA;AAAA;AAAA,EAKA,aAAa,KAAK,UAAkB,SAAmC;AACnE,WAAO,KAAK,MAAM,UAAU,SAAS,MAAM;AAAA,EAC/C;AAAA,EAEA,aAAa,MAAM,UAAkB,SAAmC;AACpE,WAAO,KAAK,MAAM,UAAU,SAAS,OAAO;AAAA,EAChD;AAAA,EAEA,aAAa,KAAK,UAAkB,SAAmC;AACnE,WAAO,KAAK,MAAM,UAAU,SAAS,MAAM;AAAA,EAC/C;AAAA,EAEA,aAAa,MAAM,UAAkB,SAAmC;AACpE,WAAO,KAAK,MAAM,UAAU,SAAS,OAAO;AAAA,EAChD;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,aAAa,QAAQ,UAAkB,WAAmB,KAAuB;AAC7E,QAAI;AACA,YAAM,QAAQ,MAAM,KAAK,KAAK,UAAU,EAAE,SAAS,KAAK,CAAC;AAEzD,UAAI,MAAM,SAAS,UAAU;AACzB,cAAM,YAAY,MAAM,MAAM,CAAC,QAAQ;AACvC,cAAM,UAAU,UAAU,KAAK,IAAI,IAAI;AACvC,cAAS,aAAS,UAAU,UAAU,SAAS,MAAM;AACrD,eAAO,MAAM,SAAS;AAAA,MAC1B;AAEA,aAAO;AAAA,IACX,SAAS,OAAO;AACZ,cAAQ,MAAM,yBAAyB,KAAK;AAC5C,YAAM;AAAA,IACV;AAAA,EACJ;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,aAAa,cAAc,UAAoC;AAC3D,QAAI;AACA,UAAO,eAAW,QAAQ,GAAG;AACzB,cAAS,aAAS,OAAO,QAAQ;AACjC,eAAO;AAAA,MACX;AACA,aAAO;AAAA,IACX,SAAS,OAAO;AACZ,cAAQ,MAAM,oCAAoC,KAAK;AACvD,YAAM;AAAA,IACV;AAAA,EACJ;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,aAAa,eAAe,WAA8C;AACtE,UAAM,UAA0B,CAAC;AAEjC,eAAW,YAAY,WAAW;AAC9B,UAAI;AACA,cAAM,UAAU,MAAM,KAAK,cAAc,QAAQ;AACjD,gBAAQ,KAAK,EAAE,UAAU,SAAS,OAAO,KAAK,CAAC;AAAA,MACnD,SAAS,OAAO;AACZ,gBAAQ,KAAK,EAAE,UAAU,SAAS,OAAO,OAAQ,MAAgB,QAAQ,CAAC;AAAA,MAC9E;AAAA,IACJ;AAEA,WAAO;AAAA,EACX;AACJ;;;ACleO,IAAM,yBAAN,MAA6B;AAAA,EAElC,aAAa,kBAAkB,MAA8B;AAC3D,QAAI,iBAAiB,CAAC;AACtB,QAAI,MAAM,iBAAS,QAAQ,GAAG;AAC5B,YAAM,iBAAS,QAAQ;AACvB,UAAI;AAEF,cAAM,mBAAmB;AACzB,cAAM,oBAAoB,MAAM,iBAAS,MAAM,gBAAgB;AAE/D,YAAI,kBAAkB,WAAW,aAAa,kBAAkB,QAAQ,kBAAkB,KAAK,SAAS,GAAG;AACzG,gBAAM,gBAAgB,MAAM,iBAAS,oBAAoB,6DAA6D,CAAC,IAAI,CAAC;AAC5H,2BAAiB,cAAc;AAAA,QACjC,OAAO;AAEL,2BAAiB,CAAC;AAAA,QACpB;AAAA,MACF,SAAS,OAAO;AACd,gBAAQ,MAAM,mCAAmC,KAAK;AACtD,yBAAiB,CAAC;AAAA,MACpB;AACA,YAAM,iBAAS,WAAW;AAAA,IAC5B;AAEA,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,OAAO,mBAAmB,aAAqB,SAAmC;AAChF,QAAI;AAEF,YAAM,gBAAgB,YAAY,MAAM,kDAAkD;AAE1F,UAAI,CAAC,eAAe;AAClB,cAAM,IAAI,MAAM,qCAAqC;AAAA,MACvD;AAEA,UAAI,eAAuB,cAAc,CAAC,EAAE,KAAK;AAGjD,UAAI,aAAa,SAAS,GAAG,GAAG;AAC9B,uBAAe,aAAa,MAAM,GAAG,EAAE,EAAE,KAAK;AAAA,MAChD;AAKA,qBAAe,aAAa,QAAQ,uBAAuB,CAAC,QAAQ,eAAuB;AACzF,cAAM,kBAAkB,WAAW,KAAK,EAAE,QAAQ,SAAS,EAAE;AAC7D,eAAO,SAAS,KAAK,UAAU,eAAe,CAAC;AAAA,MACjD,CAAC;AAGD,YAAM,kBAAkB,IAAI,SAAS,SAAS,YAAY;AAC1D,aAAO,gBAAgB,OAAO;AAAA,IAChC,SAAS,OAAO;AACd,cAAQ,MAAM,oCAAoC,KAAK;AACvD,aAAO;AAAA,IACT;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,OAAO,oBAAoB,aAA+B;AACxD,UAAM,eAAyB,CAAC;AAChC,UAAM,gBAAgB,YAAY,MAAM,qBAAqB;AAE7D,QAAI,eAAe;AACjB,iBAAW,SAAS,eAAe;AACjC,cAAM,aAAa,MAAM,MAAM,oBAAoB;AACnD,YAAI,YAAY;AACd,gBAAM,aAAa,WAAW,CAAC,EAAE,KAAK,EAAE,QAAQ,SAAS,EAAE;AAC3D,cAAI,CAAC,aAAa,SAAS,UAAU,GAAG;AACtC,yBAAa,KAAK,UAAU;AAAA,UAC9B;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAEA,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,OAAO,eACL,MACA,iBACK;AAEL,WAAO,KAAK,IAAI,CAAC,MAAM,UAAU;AAC/B,UAAI,gBAAqB,EAAE,GAAG,KAAK;AAGnC,sBAAgB,QAAQ,CAAC,WAAW;AAClC,YAAI;AACF,gBAAM,EAAE,QAAQ,WAAW,MAAAC,OAAM,YAAY,IAAI;AAKjD,cAAI,sBAAsB,YAAY;AAAA,YACpC;AAAA,YACA,CAAC,OAAO,eAAe;AACrB,oBAAM,kBAAkB,WAAW,QAAQ,SAAS,EAAE;AACtD,qBAAO,SAAS,KAAK,UAAU,eAAe,CAAC;AAAA,YACjD;AAAA,UACF;AAGA,gBAAM,eAAe,oBAAoB,MAAM,+CAA+C;AAC9F,cAAI,CAAC,cAAc;AACjB,kBAAM,IAAI,MAAM,8CAA2C,SAAS,EAAE;AAAA,UACxE;AAEA,gBAAM,eAAe,aAAa,CAAC;AAGnC,gBAAM,kBAAkB,IAAI,SAAS,SAAS,YAAY;AAC1D,cAAI,SAAS,gBAAgB,aAAa;AAG1C,mBAAS,cAAc,QAAQA,KAAgB;AAG/C,wBAAc,SAAS,IAAI;AAAA,QAE7B,SAAS,OAAO;AACd,kBAAQ,MAAM,0BAA0B,OAAO,MAAM,YAAY,KAAK,KAAK,KAAK;AAEhF,wBAAc,OAAO,MAAM,IAAI;AAAA,QACjC;AAAA,MACF,CAAC;AAED,aAAO;AAAA,IACT,CAAC;AAAA,EACH;AACF;AAEO,IAAM,iBAAN,MAAqB;AAAA,EAC1B,aAAa,qBACX,UACA,QACA,WACA,cACmB;AACnB,aAAS,sBAAsB,OAAeC,SAAmC;AAE/E,YAAM,aAAa,MAAM,KAAK,EAAE,QAAQ,QAAQ,GAAG;AAGnD,YAAM,iBAAiB,WAAW,MAAM,wCAAwC;AAChF,UAAI,CAAC,gBAAgB;AACnB,cAAM,IAAI,MAAM,0CAA0C;AAAA,MAC5D;AAEA,YAAMC,aAAY,eAAe,CAAC;AAGlC,YAAM,eAAe,WAAW,MAAM,UAAU;AAChD,UAAI,CAAC,cAAc;AACjB,cAAM,IAAI,MAAM,qDAAqD;AAAA,MACvE;AAEA,YAAM,gBAAgB,aAAa,CAAC;AACpC,YAAM,oBAAoB,cAAc,MAAM,GAAG,EAAE,IAAI,SAAO,IAAI,KAAK,CAAC;AAExE,YAAM,UAAoB,CAAC;AAE3B,iBAAW,OAAO,mBAAmB;AAEnC,YAAI,IAAI,YAAY,EAAE,WAAW,aAAa,KAC5C,IAAI,YAAY,EAAE,WAAW,aAAa,KAC1C,IAAI,YAAY,EAAE,WAAW,YAAY,GAAG;AAC5C;AAAA,QACF;AAEA,cAAM,QAAQ,IAAI,MAAM,KAAK;AAC7B,YAAI,MAAM,SAAS,EAAG;AAEtB,cAAM,aAAa,MAAM,CAAC;AAC1B,cAAM,aAAa,MAAM,CAAC;AAE1B,cAAM,SAAiB;AAAA,UACrB,MAAM;AAAA,UACN,MAAM;AAAA,UACN,UAAU,CAAC,IAAI,YAAY,EAAE,SAAS,UAAU;AAAA,UAChD,YAAY,IAAI,YAAY,EAAE,SAAS,aAAa;AAAA,UACpD,eAAe,IAAI,YAAY,EAAE,SAAS,eAAe,KAAK,IAAI,YAAY,EAAE,SAAS,gBAAgB;AAAA,QAC3G;AAEA,gBAAQ,KAAK,MAAM;AAAA,MACrB;AAEA,aAAO,EAAE,WAAAA,YAAW,QAAQ;AAAA,IAC9B;AAEA,aAAS,qBACP,YACA,YACAA,YACU;AACV,YAAM,UAAoB,CAAC;AAG3B,iBAAW,CAAC,UAAU,KAAK,YAAY;AACrC,YAAI,CAAC,WAAW,IAAI,UAAU,GAAG;AAC/B,kBAAQ,KAAK,eAAeA,UAAS,gBAAgB,UAAU,GAAG;AAAA,QACpE;AAAA,MACF;AAGA,iBAAW,CAAC,YAAY,MAAM,KAAK,YAAY;AAC7C,cAAM,YAAY,WAAW,IAAI,UAAU;AAE3C,YAAI,CAAC,WAAW;AAEd,gBAAM,YAAY,sBAAsB,QAAQ,OAAO;AACvD,kBAAQ,KAAK,eAAeA,UAAS,eAAe,SAAS,GAAG;AAAA,QAClE,WAAW,CAAC,aAAa,QAAQ,SAAS,GAAG;AAE3C,gBAAM,YAAY,sBAAsB,QAAQ,OAAO;AACvD,kBAAQ,KAAK,eAAeA,UAAS,kBAAkB,SAAS,GAAG;AAAA,QACrE;AAAA,MACF;AAEA,aAAO;AAAA,IACT;AAEA,aAAS,0BACP,YACA,YACAA,YACU;AACV,YAAM,UAAoB,CAAC;AAG3B,iBAAW,CAAC,UAAU,KAAK,YAAY;AACrC,YAAI,CAAC,WAAW,IAAI,UAAU,GAAG;AAC/B,kBAAQ,KAAK,eAAeA,UAAS,gBAAgB,UAAU,GAAG;AAAA,QACpE;AAAA,MACF;AAGA,iBAAW,CAAC,YAAY,MAAM,KAAK,YAAY;AAC7C,cAAM,YAAY,WAAW,IAAI,UAAU;AAE3C,YAAI,CAAC,WAAW;AAEd,gBAAM,YAAY,sBAAsB,QAAQ,UAAU;AAC1D,kBAAQ,KAAK,eAAeA,UAAS,eAAe,SAAS,GAAG;AAAA,QAClE,WAAW,CAAC,aAAa,QAAQ,SAAS,GAAG;AAE3C,cAAI,OAAO,SAAS,UAAU,MAAM;AAClC,kBAAM,SAAS,OAAO,KAAK,QAAQ,WAAW,KAAK,EAAE,QAAQ,QAAQ,SAAS;AAC9E,oBAAQ,KAAK,eAAeA,UAAS,iBAAiB,UAAU,SAAS,MAAM,GAAG;AAAA,UACpF;AAEA,cAAI,OAAO,aAAa,UAAU,UAAU;AAC1C,kBAAM,aAAa,OAAO,WAAW,kBAAkB;AACvD,oBAAQ,KAAK,eAAeA,UAAS,iBAAiB,UAAU,IAAI,UAAU,GAAG;AAAA,UACnF;AAAA,QACF;AAAA,MACF;AAEA,aAAO;AAAA,IACT;AAEA,aAAS,sBACP,WACA,WACAA,YACU;AAEV,YAAM,UAAoB,CAAC;AAG3B,UAAI,aAAa,WAAW,SAAS,GAAG;AACtC,eAAO;AAAA,MACT;AAEA,YAAM,gBAAgB,GAAGA,UAAS,SAAS,KAAK,IAAI,CAAC;AAGrD,YAAM,kBAAkB,sBAAsB,WAAW,UAAU,aAAa;AAChF,cAAQ,KAAK,eAAe;AAG5B,YAAM,gBAAgB,UAAU,QAC7B,OAAO,SAAO,UAAU,QAAQ,KAAK,YAAU,OAAO,KAAK,YAAY,MAAM,IAAI,KAAK,YAAY,CAAC,CAAC,EACpG,IAAI,SAAO,IAAI,IAAI;AAEtB,UAAI,cAAc,SAAS,GAAG;AAC5B,cAAM,cAAc,cAAc,KAAK,IAAI;AAC3C,gBAAQ,KAAK,eAAe,aAAa,KAAK,WAAW,YAAY,WAAW,SAASA,UAAS,GAAG;AAAA,MACvG;AAGA,cAAQ,KAAK,cAAcA,UAAS,GAAG;AAGvC,cAAQ,KAAK,eAAe,aAAa,cAAcA,UAAS,GAAG;AAEnE,aAAO;AAAA,IACT;AAEA,aAAS,uBACP,YACA,YACA,gBACU;AACV,YAAM,UAAoB,CAAC;AAG3B,YAAM,iBAA2B,CAAC;AAClC,iBAAW,CAAC,SAAS,KAAK,YAAY;AACpC,YAAI,CAAC,WAAW,IAAI,SAAS,GAAG;AAC9B,yBAAe,KAAK,SAAS;AAAA,QAC/B;AAAA,MACF;AAEA,UAAI,eAAe,SAAS,GAAG;AAC7B,cAAM,cAAc,eAAe,OAAO,CAAC,KAAK,UAAU;AACxD,cAAI,KAAK,IAAI;AACb,iBAAO;AAAA,QACT,GAAG,CAAC,CAA2B;AAE/B,gBAAQ,KAAK,MAAM,cAAc,6BAA6B,KAAK,UAAU,WAAW,CAAC,MAAM;AAAA,MACjG;AAGA,YAAM,cAAmC,CAAC;AAC1C,iBAAW,CAAC,WAAW,MAAM,KAAK,YAAY;AAC5C,YAAI,CAAC,WAAW,IAAI,SAAS,GAAG;AAE9B,cAAI,eAAoB;AACxB,cAAI,CAAC,OAAO,UAAU;AACpB,oBAAQ,OAAO,KAAK,YAAY,GAAG;AAAA,cACjC,KAAK;AACH,+BAAe;AACf;AAAA,cACF,KAAK;AAAA,cACL,KAAK;AACH,+BAAe;AACf;AAAA,cACF;AACE,+BAAe;AAAA,YACnB;AAAA,UACF;AACA,sBAAY,SAAS,IAAI;AAAA,QAC3B;AAAA,MACF;AAEA,UAAI,OAAO,KAAK,WAAW,EAAE,SAAS,GAAG;AACvC,gBAAQ,KAAK,MAAM,cAAc,2BAA2B,KAAK,UAAU,WAAW,CAAC,MAAM;AAAA,MAC/F;AAEA,aAAO;AAAA,IACT;AAEA,aAAS,sBAAsB,QAAgBD,SAA8B;AAC3E,UAAI,MAAM,GAAG,OAAO,IAAI,IAAI,OAAO,IAAI;AAEvC,UAAI,OAAO,YAAY;AACrB,eAAO;AAAA,MACT;AAEA,UAAI,OAAO,eAAe;AACxB,YAAIA,YAAW,SAAS;AACtB,iBAAO;AAAA,QACT,WAAWA,YAAW,UAAU;AAC9B,iBAAO;AAAA,QACT,WAAWA,YAAW,YAAY;AAChC,gBAAM,IAAI,QAAQ,OAAO,MAAM,QAAQ;AAAA,QACzC;AAAA,MACF;AAEA,UAAI,CAAC,OAAO,UAAU;AACpB,eAAO;AAAA,MACT;AAEA,aAAO;AAAA,IACT;AAEA,aAAS,sBAAsB,QAAqBA,SAAsBC,YAA4B;AACpG,YAAM,OAAOA,cAAa,OAAO;AACjC,YAAM,aAAa,OAAO,QAAQ,IAAI,SAAO,sBAAsB,KAAKD,OAAM,CAAC;AAC/E,aAAO,gBAAgB,IAAI,KAAK,WAAW,KAAK,IAAI,CAAC;AAAA,IACvD;AAEA,aAAS,aAAa,MAAc,MAAuB;AACzD,aAAO,KAAK,KAAK,YAAY,MAAM,KAAK,KAAK,YAAY,KACvD,KAAK,SAAS,KAAK,QACnB,KAAK,aAAa,KAAK,YACvB,KAAK,eAAe,KAAK,cACzB,KAAK,kBAAkB,KAAK;AAAA,IAChC;AAEA,aAAS,aAAa,SAAsB,SAA+B;AACzE,UAAI,QAAQ,QAAQ,WAAW,QAAQ,QAAQ,QAAQ;AACrD,eAAO;AAAA,MACT;AAEA,YAAM,QAAQ,IAAI,IAAI,QAAQ,QAAQ,IAAI,SAAO,CAAC,IAAI,KAAK,YAAY,GAAG,GAAG,CAAC,CAAC;AAC/E,YAAM,QAAQ,IAAI,IAAI,QAAQ,QAAQ,IAAI,SAAO,CAAC,IAAI,KAAK,YAAY,GAAG,GAAG,CAAC,CAAC;AAE/E,iBAAW,CAAC,MAAM,IAAI,KAAK,OAAO;AAChC,cAAM,OAAO,MAAM,IAAI,IAAI;AAC3B,YAAI,CAAC,QAAQ,CAAC,aAAa,MAAM,IAAI,GAAG;AACtC,iBAAO;AAAA,QACT;AAAA,MACF;AAEA,aAAO;AAAA,IACT;AAEA,QAAI,MAAM,iBAAS,QAAQ,GAAG;AAC5B,YAAM,iBAAS,QAAQ;AACvB,UAAI;AAEF,cAAM,mBAAmB;AACzB,cAAM,oBAAoB,MAAM,iBAAS,MAAM,gBAAgB;AAE/D,YAAI,kBAAkB,WAAW,aAAa,kBAAkB,QAAQ,kBAAkB,KAAK,SAAS,GAAG;AACzG,gBAAM,gBAAgB,MAAM,iBAAS,oBAAoB,4EAA4E,CAAC,WAAW,YAAY,CAAC;AAC9J,gBAAM,WAAW,cAAc,KAAK,CAAC;AAIrC,cAAI,CAAC,YAAY,CAAC,SAAS,QAAQ;AACjC,kBAAM,iBAAS,WAAW;AAC1B,mBAAO,CAAC,QAAQ;AAAA,UAClB;AAEA,gBAAM,YAAY,sBAAsB,UAAU,MAAM;AACxD,gBAAM,YAAY,sBAAsB,SAAS,QAAQ,MAAM;AAG/D,cAAI,UAAU,UAAU,YAAY,MAAM,UAAU,YAAY,GAAG;AACjE,kBAAM,IAAI,MAAM,mCAAmC,UAAU,SAAS,sCAAmC,SAAS,GAAG;AAAA,UACvH;AAGA,gBAAM,aAAa,IAAI,IAAI,UAAU,QAAQ,IAAI,SAAO,CAAC,IAAI,KAAK,YAAY,GAAG,GAAG,CAAC,CAAC;AACtF,gBAAM,aAAa,IAAI,IAAI,UAAU,QAAQ,IAAI,SAAO,CAAC,IAAI,KAAK,YAAY,GAAG,GAAG,CAAC,CAAC;AAEtF,kBAAQ,QAAQ;AAAA,YACd,KAAK;AACH,qBAAO,qBAAqB,YAAY,YAAY,SAAS;AAAA,YAE/D,KAAK;AACH,qBAAO,0BAA0B,YAAY,YAAY,SAAS;AAAA,YAEpE,KAAK;AACH,qBAAO,sBAAsB,WAAW,WAAW,SAAS;AAAA,YAE9D,KAAK;AACH,qBAAO,uBAAuB,YAAY,YAAY,SAAS;AAAA,YAEjE;AACE,oBAAM,IAAI,MAAM,uCAAuC,MAAM,EAAE;AAAA,UACnE;AAAA,QACF;AAAA,MACF,SAAS,OAAO;AACd,gBAAQ,MAAM,mCAAmC,KAAK;AAAA,MACxD;AACA,YAAM,iBAAS,WAAW;AAC1B,aAAO,CAAC,QAAQ;AAAA,IAClB,OAAO;AACL,aAAO,CAAC,QAAQ;AAAA,IAClB;AAAA,EACF;AAAA,EAEA,aAAa,UAAU,WAAmB,cAAsB,QAA+B;AAE7F,QAAI,MAAM,iBAAS,QAAQ,GAAG;AAC5B,YAAM,iBAAS,QAAQ;AACvB,UAAI;AACF,cAAM,iBAAS,oBAAoB,0EAA0E,CAAC,WAAW,YAAY,CAAC;AAGtI,cAAM,mBAAmB;AACzB,cAAM,iBAAS,oBAAoB,kBAAkB,CAAC,WAAW,cAAc,MAAM,CAAC;AAAA,MACxF,SAAS,OAAO;AACd,gBAAQ,MAAM,mCAAmC,KAAK;AAAA,MACxD;AACA,YAAM,iBAAS,WAAW;AAAA,IAC5B;AAAA,EACF;AACF;AAEO,IAAM,mBAAN,MAAuB;AAAA,EAE5B,aAAa,YAAY,MAA8B;AACrD,QAAI,WAAW,CAAC;AAChB,QAAI,MAAM,iBAAS,QAAQ,GAAG;AAC5B,YAAM,iBAAS,QAAQ;AACvB,UAAI;AAEF,cAAM,mBAAmB;AACzB,cAAM,oBAAoB,MAAM,iBAAS,MAAM,gBAAgB;AAE/D,YAAI,kBAAkB,WAAW,aAAa,kBAAkB,QAAQ,kBAAkB,KAAK,SAAS,GAAG;AACzG,gBAAM,gBAAgB,MAAM,iBAAS,oBAAoB,6DAA6D,CAAC,IAAI,CAAC;AAC5H,qBAAW,cAAc;AAAA,QAC3B,OAAO;AAEL,qBAAW,CAAC;AAAA,QACd;AAAA,MACF,SAAS,OAAO;AACd,gBAAQ,MAAM,mCAAmC,KAAK;AACtD,mBAAW,CAAC;AAAA,MACd;AACA,YAAM,iBAAS,WAAW;AAAA,IAC5B;AAEA,WAAO;AAAA,EACT;AACF;AAGA,SAAS,cAAc,OAAYD,OAAqB;AACtD,UAAQA,OAAM;AAAA,IACZ,KAAK;AACH,aAAO,OAAO,KAAK;AAAA,IACrB,KAAK;AACH,YAAM,MAAM,OAAO,KAAK;AACxB,aAAO,MAAM,GAAG,IAAI,IAAI;AAAA,IAC1B,KAAK;AACH,aAAO,QAAQ,KAAK;AAAA,IACtB,KAAK;AACH,aAAO,iBAAiB,OAAO,QAAQ,IAAI,KAAK,KAAK;AAAA,IACvD,KAAK;AACH,aAAO;AAAA,IACT;AACE,aAAO;AAAA,EACX;AACF;","names":["import_path","platform","arch","os","followRedirects","resolve","arch","platform","ora","chalk","__filename","fs","path","os","import_url","import_path","import_meta","__filename","platform","arch","import_child_process","import_path","path","fs","resolve","net","ok","path","require","resolve","import_path","fs","path","arch","resolve","import_module","net","import_child_process","resolve","path","require","path","import_fs","fs","fs","path","type","dbType","tableName"]}